@openai/agents-extensions 0.8.5 → 0.9.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.
- package/dist/metadata.js +2 -2
- package/dist/metadata.mjs +2 -2
- package/dist/sandbox/blaxel/index.d.ts +2 -0
- package/dist/sandbox/blaxel/index.js +19 -0
- package/dist/sandbox/blaxel/index.js.map +1 -0
- package/dist/sandbox/blaxel/index.mjs +3 -0
- package/dist/sandbox/blaxel/index.mjs.map +1 -0
- package/dist/sandbox/blaxel/mounts.d.ts +101 -0
- package/dist/sandbox/blaxel/mounts.js +542 -0
- package/dist/sandbox/blaxel/mounts.js.map +1 -0
- package/dist/sandbox/blaxel/mounts.mjs +529 -0
- package/dist/sandbox/blaxel/mounts.mjs.map +1 -0
- package/dist/sandbox/blaxel/sandbox.d.ts +155 -0
- package/dist/sandbox/blaxel/sandbox.js +1110 -0
- package/dist/sandbox/blaxel/sandbox.js.map +1 -0
- package/dist/sandbox/blaxel/sandbox.mjs +1072 -0
- package/dist/sandbox/blaxel/sandbox.mjs.map +1 -0
- package/dist/sandbox/cloudflare/index.d.ts +2 -0
- package/dist/sandbox/cloudflare/index.js +19 -0
- package/dist/sandbox/cloudflare/index.js.map +1 -0
- package/dist/sandbox/cloudflare/index.mjs +3 -0
- package/dist/sandbox/cloudflare/index.mjs.map +1 -0
- package/dist/sandbox/cloudflare/mounts.d.ts +28 -0
- package/dist/sandbox/cloudflare/mounts.js +150 -0
- package/dist/sandbox/cloudflare/mounts.js.map +1 -0
- package/dist/sandbox/cloudflare/mounts.mjs +143 -0
- package/dist/sandbox/cloudflare/mounts.mjs.map +1 -0
- package/dist/sandbox/cloudflare/sandbox.d.ts +91 -0
- package/dist/sandbox/cloudflare/sandbox.js +1163 -0
- package/dist/sandbox/cloudflare/sandbox.js.map +1 -0
- package/dist/sandbox/cloudflare/sandbox.mjs +1125 -0
- package/dist/sandbox/cloudflare/sandbox.mjs.map +1 -0
- package/dist/sandbox/daytona/index.d.ts +2 -0
- package/dist/sandbox/daytona/index.js +19 -0
- package/dist/sandbox/daytona/index.js.map +1 -0
- package/dist/sandbox/daytona/index.mjs +3 -0
- package/dist/sandbox/daytona/index.mjs.map +1 -0
- package/dist/sandbox/daytona/mounts.d.ts +11 -0
- package/dist/sandbox/daytona/mounts.js +17 -0
- package/dist/sandbox/daytona/mounts.js.map +1 -0
- package/dist/sandbox/daytona/mounts.mjs +12 -0
- package/dist/sandbox/daytona/mounts.mjs.map +1 -0
- package/dist/sandbox/daytona/sandbox.d.ts +160 -0
- package/dist/sandbox/daytona/sandbox.js +938 -0
- package/dist/sandbox/daytona/sandbox.js.map +1 -0
- package/dist/sandbox/daytona/sandbox.mjs +900 -0
- package/dist/sandbox/daytona/sandbox.mjs.map +1 -0
- package/dist/sandbox/e2b/index.d.ts +2 -0
- package/dist/sandbox/e2b/index.js +19 -0
- package/dist/sandbox/e2b/index.js.map +1 -0
- package/dist/sandbox/e2b/index.mjs +3 -0
- package/dist/sandbox/e2b/index.mjs.map +1 -0
- package/dist/sandbox/e2b/mounts.d.ts +11 -0
- package/dist/sandbox/e2b/mounts.js +17 -0
- package/dist/sandbox/e2b/mounts.js.map +1 -0
- package/dist/sandbox/e2b/mounts.mjs +12 -0
- package/dist/sandbox/e2b/mounts.mjs.map +1 -0
- package/dist/sandbox/e2b/sandbox.d.ts +169 -0
- package/dist/sandbox/e2b/sandbox.js +829 -0
- package/dist/sandbox/e2b/sandbox.js.map +1 -0
- package/dist/sandbox/e2b/sandbox.mjs +791 -0
- package/dist/sandbox/e2b/sandbox.mjs.map +1 -0
- package/dist/sandbox/modal/index.d.ts +2 -0
- package/dist/sandbox/modal/index.js +19 -0
- package/dist/sandbox/modal/index.js.map +1 -0
- package/dist/sandbox/modal/index.mjs +3 -0
- package/dist/sandbox/modal/index.mjs.map +1 -0
- package/dist/sandbox/modal/mounts.d.ts +24 -0
- package/dist/sandbox/modal/mounts.js +194 -0
- package/dist/sandbox/modal/mounts.js.map +1 -0
- package/dist/sandbox/modal/mounts.mjs +188 -0
- package/dist/sandbox/modal/mounts.mjs.map +1 -0
- package/dist/sandbox/modal/sandbox.d.ts +220 -0
- package/dist/sandbox/modal/sandbox.js +1621 -0
- package/dist/sandbox/modal/sandbox.js.map +1 -0
- package/dist/sandbox/modal/sandbox.mjs +1581 -0
- package/dist/sandbox/modal/sandbox.mjs.map +1 -0
- package/dist/sandbox/runloop/index.d.ts +2 -0
- package/dist/sandbox/runloop/index.js +19 -0
- package/dist/sandbox/runloop/index.js.map +1 -0
- package/dist/sandbox/runloop/index.mjs +3 -0
- package/dist/sandbox/runloop/index.mjs.map +1 -0
- package/dist/sandbox/runloop/mounts.d.ts +11 -0
- package/dist/sandbox/runloop/mounts.js +17 -0
- package/dist/sandbox/runloop/mounts.js.map +1 -0
- package/dist/sandbox/runloop/mounts.mjs +12 -0
- package/dist/sandbox/runloop/mounts.mjs.map +1 -0
- package/dist/sandbox/runloop/sandbox.d.ts +266 -0
- package/dist/sandbox/runloop/sandbox.js +1390 -0
- package/dist/sandbox/runloop/sandbox.js.map +1 -0
- package/dist/sandbox/runloop/sandbox.mjs +1346 -0
- package/dist/sandbox/runloop/sandbox.mjs.map +1 -0
- package/dist/sandbox/shared/archive.d.ts +34 -0
- package/dist/sandbox/shared/archive.js +397 -0
- package/dist/sandbox/shared/archive.js.map +1 -0
- package/dist/sandbox/shared/archive.mjs +389 -0
- package/dist/sandbox/shared/archive.mjs.map +1 -0
- package/dist/sandbox/shared/editor.d.ts +17 -0
- package/dist/sandbox/shared/editor.js +65 -0
- package/dist/sandbox/shared/editor.js.map +1 -0
- package/dist/sandbox/shared/editor.mjs +61 -0
- package/dist/sandbox/shared/editor.mjs.map +1 -0
- package/dist/sandbox/shared/environment.d.ts +1 -0
- package/dist/sandbox/shared/environment.js +13 -0
- package/dist/sandbox/shared/environment.js.map +1 -0
- package/dist/sandbox/shared/environment.mjs +2 -0
- package/dist/sandbox/shared/environment.mjs.map +1 -0
- package/dist/sandbox/shared/git.d.ts +4 -0
- package/dist/sandbox/shared/git.js +20 -0
- package/dist/sandbox/shared/git.js.map +1 -0
- package/dist/sandbox/shared/git.mjs +17 -0
- package/dist/sandbox/shared/git.mjs.map +1 -0
- package/dist/sandbox/shared/inContainerMounts.d.ts +40 -0
- package/dist/sandbox/shared/inContainerMounts.js +670 -0
- package/dist/sandbox/shared/inContainerMounts.js.map +1 -0
- package/dist/sandbox/shared/inContainerMounts.mjs +662 -0
- package/dist/sandbox/shared/inContainerMounts.mjs.map +1 -0
- package/dist/sandbox/shared/index.d.ts +23 -0
- package/dist/sandbox/shared/index.js +112 -0
- package/dist/sandbox/shared/index.js.map +1 -0
- package/dist/sandbox/shared/index.mjs +18 -0
- package/dist/sandbox/shared/index.mjs.map +1 -0
- package/dist/sandbox/shared/localSources.d.ts +8 -0
- package/dist/sandbox/shared/localSources.js +378 -0
- package/dist/sandbox/shared/localSources.js.map +1 -0
- package/dist/sandbox/shared/localSources.mjs +372 -0
- package/dist/sandbox/shared/localSources.mjs.map +1 -0
- package/dist/sandbox/shared/manifest.d.ts +38 -0
- package/dist/sandbox/shared/manifest.js +254 -0
- package/dist/sandbox/shared/manifest.js.map +1 -0
- package/dist/sandbox/shared/manifest.mjs +233 -0
- package/dist/sandbox/shared/manifest.mjs.map +1 -0
- package/dist/sandbox/shared/media.d.ts +1 -0
- package/dist/sandbox/shared/media.js +10 -0
- package/dist/sandbox/shared/media.js.map +1 -0
- package/dist/sandbox/shared/media.mjs +2 -0
- package/dist/sandbox/shared/media.mjs.map +1 -0
- package/dist/sandbox/shared/metadata.d.ts +7 -0
- package/dist/sandbox/shared/metadata.js +87 -0
- package/dist/sandbox/shared/metadata.js.map +1 -0
- package/dist/sandbox/shared/metadata.mjs +81 -0
- package/dist/sandbox/shared/metadata.mjs.map +1 -0
- package/dist/sandbox/shared/output.d.ts +1 -0
- package/dist/sandbox/shared/output.js +8 -0
- package/dist/sandbox/shared/output.js.map +1 -0
- package/dist/sandbox/shared/output.mjs +2 -0
- package/dist/sandbox/shared/output.mjs.map +1 -0
- package/dist/sandbox/shared/paths.d.ts +27 -0
- package/dist/sandbox/shared/paths.js +245 -0
- package/dist/sandbox/shared/paths.js.map +1 -0
- package/dist/sandbox/shared/paths.mjs +236 -0
- package/dist/sandbox/shared/paths.mjs.map +1 -0
- package/dist/sandbox/shared/ports.d.ts +14 -0
- package/dist/sandbox/shared/ports.js +75 -0
- package/dist/sandbox/shared/ports.js.map +1 -0
- package/dist/sandbox/shared/ports.mjs +69 -0
- package/dist/sandbox/shared/ports.mjs.map +1 -0
- package/dist/sandbox/shared/process.d.ts +16 -0
- package/dist/sandbox/shared/process.js +90 -0
- package/dist/sandbox/shared/process.js.map +1 -0
- package/dist/sandbox/shared/process.mjs +86 -0
- package/dist/sandbox/shared/process.mjs.map +1 -0
- package/dist/sandbox/shared/pty.d.ts +81 -0
- package/dist/sandbox/shared/pty.js +382 -0
- package/dist/sandbox/shared/pty.js.map +1 -0
- package/dist/sandbox/shared/pty.mjs +335 -0
- package/dist/sandbox/shared/pty.mjs.map +1 -0
- package/dist/sandbox/shared/runAs.d.ts +46 -0
- package/dist/sandbox/shared/runAs.js +149 -0
- package/dist/sandbox/shared/runAs.js.map +1 -0
- package/dist/sandbox/shared/runAs.mjs +141 -0
- package/dist/sandbox/shared/runAs.mjs.map +1 -0
- package/dist/sandbox/shared/session.d.ts +16 -0
- package/dist/sandbox/shared/session.js +138 -0
- package/dist/sandbox/shared/session.js.map +1 -0
- package/dist/sandbox/shared/session.mjs +128 -0
- package/dist/sandbox/shared/session.mjs.map +1 -0
- package/dist/sandbox/shared/sessionBase.d.ts +90 -0
- package/dist/sandbox/shared/sessionBase.js +446 -0
- package/dist/sandbox/shared/sessionBase.js.map +1 -0
- package/dist/sandbox/shared/sessionBase.mjs +442 -0
- package/dist/sandbox/shared/sessionBase.mjs.map +1 -0
- package/dist/sandbox/shared/sessionState.d.ts +7 -0
- package/dist/sandbox/shared/sessionState.js +35 -0
- package/dist/sandbox/shared/sessionState.js.map +1 -0
- package/dist/sandbox/shared/sessionState.mjs +31 -0
- package/dist/sandbox/shared/sessionState.mjs.map +1 -0
- package/dist/sandbox/shared/snapshots.d.ts +9 -0
- package/dist/sandbox/shared/snapshots.js +62 -0
- package/dist/sandbox/shared/snapshots.js.map +1 -0
- package/dist/sandbox/shared/snapshots.mjs +57 -0
- package/dist/sandbox/shared/snapshots.mjs.map +1 -0
- package/dist/sandbox/shared/typeGuards.d.ts +10 -0
- package/dist/sandbox/shared/typeGuards.js +50 -0
- package/dist/sandbox/shared/typeGuards.js.map +1 -0
- package/dist/sandbox/shared/typeGuards.mjs +38 -0
- package/dist/sandbox/shared/typeGuards.mjs.map +1 -0
- package/dist/sandbox/shared/types.d.ts +24 -0
- package/dist/sandbox/shared/types.js +3 -0
- package/dist/sandbox/shared/types.js.map +1 -0
- package/dist/sandbox/shared/types.mjs +2 -0
- package/dist/sandbox/shared/types.mjs.map +1 -0
- package/dist/sandbox/vercel/index.d.ts +1 -0
- package/dist/sandbox/vercel/index.js +18 -0
- package/dist/sandbox/vercel/index.js.map +1 -0
- package/dist/sandbox/vercel/index.mjs +2 -0
- package/dist/sandbox/vercel/index.mjs.map +1 -0
- package/dist/sandbox/vercel/sandbox.d.ts +135 -0
- package/dist/sandbox/vercel/sandbox.js +1001 -0
- package/dist/sandbox/vercel/sandbox.js.map +1 -0
- package/dist/sandbox/vercel/sandbox.mjs +963 -0
- package/dist/sandbox/vercel/sandbox.mjs.map +1 -0
- package/package.json +108 -4
|
@@ -0,0 +1,1390 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.RunloopSandboxClient = exports.RunloopSandboxSession = exports.RunloopPlatformClient = exports.RunloopPlatformAxonsClient = exports.RunloopPlatformNetworkPoliciesClient = exports.RunloopPlatformSecretsClient = exports.RunloopPlatformBenchmarksClient = exports.RunloopPlatformBlueprintsClient = exports.DEFAULT_RUNLOOP_ROOT_WORKSPACE_ROOT = exports.DEFAULT_RUNLOOP_WORKSPACE_ROOT = void 0;
|
|
37
|
+
const agents_core_1 = require("@openai/agents-core");
|
|
38
|
+
const sandbox_1 = require("@openai/agents-core/sandbox");
|
|
39
|
+
const node_path_1 = require("node:path");
|
|
40
|
+
const shared_1 = require("../shared/index.js");
|
|
41
|
+
const inContainerMounts_1 = require("../shared/inContainerMounts.js");
|
|
42
|
+
const mounts_1 = require("./mounts.js");
|
|
43
|
+
exports.DEFAULT_RUNLOOP_WORKSPACE_ROOT = '/home/user';
|
|
44
|
+
exports.DEFAULT_RUNLOOP_ROOT_WORKSPACE_ROOT = '/root';
|
|
45
|
+
const UNKNOWN_RUNLOOP_EXIT_CODE = 1;
|
|
46
|
+
const DEFAULT_RUNLOOP_TUNNEL_PARAMS = {
|
|
47
|
+
auth_mode: 'open',
|
|
48
|
+
http_keep_alive: true,
|
|
49
|
+
wake_on_http: false,
|
|
50
|
+
};
|
|
51
|
+
class RunloopPlatformBlueprintsClient {
|
|
52
|
+
sdk;
|
|
53
|
+
constructor(sdk) {
|
|
54
|
+
this.sdk = sdk;
|
|
55
|
+
}
|
|
56
|
+
async list(params = {}) {
|
|
57
|
+
return await callRunloopPlatformMethod('blueprint.list', this.sdk.blueprint?.list, params);
|
|
58
|
+
}
|
|
59
|
+
async listPublic(params = {}) {
|
|
60
|
+
return await callRunloopPlatformMethod('api.blueprints.listPublic', this.sdk.api?.blueprints?.listPublic, params);
|
|
61
|
+
}
|
|
62
|
+
get(blueprintId) {
|
|
63
|
+
return callRunloopPlatformGetter('blueprint.fromId', this.sdk.blueprint?.fromId, blueprintId);
|
|
64
|
+
}
|
|
65
|
+
async logs(blueprintId, params = {}) {
|
|
66
|
+
return await callRunloopPlatformMethod('api.blueprints.logs', this.sdk.api?.blueprints?.logs, blueprintId, params);
|
|
67
|
+
}
|
|
68
|
+
async create(params = {}) {
|
|
69
|
+
return await callRunloopPlatformMethod('blueprint.create', this.sdk.blueprint?.create, params);
|
|
70
|
+
}
|
|
71
|
+
async awaitBuildComplete(blueprintId, params = {}) {
|
|
72
|
+
return await callRunloopPlatformMethod('api.blueprints.awaitBuildComplete', this.sdk.api?.blueprints?.awaitBuildComplete, blueprintId, params);
|
|
73
|
+
}
|
|
74
|
+
async delete(blueprintId, params = {}) {
|
|
75
|
+
return await callRunloopPlatformMethod('blueprint.delete', bindRunloopMethod(this.get(blueprintId), 'delete'), params);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
exports.RunloopPlatformBlueprintsClient = RunloopPlatformBlueprintsClient;
|
|
79
|
+
class RunloopPlatformBenchmarksClient {
|
|
80
|
+
sdk;
|
|
81
|
+
constructor(sdk) {
|
|
82
|
+
this.sdk = sdk;
|
|
83
|
+
}
|
|
84
|
+
async list(params = {}) {
|
|
85
|
+
return await callRunloopPlatformMethod('benchmark.list', this.sdk.benchmark?.list, params);
|
|
86
|
+
}
|
|
87
|
+
async listPublic(params = {}) {
|
|
88
|
+
return await callRunloopPlatformMethod('api.benchmarks.listPublic', this.sdk.api?.benchmarks?.listPublic, params);
|
|
89
|
+
}
|
|
90
|
+
get(benchmarkId) {
|
|
91
|
+
if (this.sdk.benchmark?.retrieve) {
|
|
92
|
+
return callRunloopPlatformMethod('benchmark.retrieve', this.sdk.benchmark.retrieve, benchmarkId);
|
|
93
|
+
}
|
|
94
|
+
return this.getBenchmarkFacade(benchmarkId);
|
|
95
|
+
}
|
|
96
|
+
async create(params = {}) {
|
|
97
|
+
return await callRunloopPlatformMethod('benchmark.create', this.sdk.benchmark?.create, params);
|
|
98
|
+
}
|
|
99
|
+
async update(benchmarkId, params = {}) {
|
|
100
|
+
if (this.sdk.benchmark?.update) {
|
|
101
|
+
return await callRunloopPlatformMethod('benchmark.update', this.sdk.benchmark.update, benchmarkId, params);
|
|
102
|
+
}
|
|
103
|
+
return await callRunloopPlatformMethod('benchmark.update', bindRunloopMethod(this.getBenchmarkFacade(benchmarkId), 'update'), params);
|
|
104
|
+
}
|
|
105
|
+
async definitions(benchmarkId, params = {}) {
|
|
106
|
+
return await callRunloopPlatformMethod('api.benchmarks.definitions', this.sdk.api?.benchmarks?.definitions, benchmarkId, params);
|
|
107
|
+
}
|
|
108
|
+
async startRun(benchmarkId, params = {}) {
|
|
109
|
+
if (this.sdk.benchmark?.startRun) {
|
|
110
|
+
return await callRunloopPlatformMethod('benchmark.startRun', this.sdk.benchmark.startRun, {
|
|
111
|
+
...params,
|
|
112
|
+
benchmark_id: benchmarkId,
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
return await callRunloopPlatformMethod('benchmark.startRun', bindRunloopMethod(this.getBenchmarkFacade(benchmarkId), 'startRun'), params);
|
|
116
|
+
}
|
|
117
|
+
async updateScenarios(benchmarkId, params = {}) {
|
|
118
|
+
return await callRunloopPlatformMethod('api.benchmarks.updateScenarios', this.sdk.api?.benchmarks?.updateScenarios, benchmarkId, params);
|
|
119
|
+
}
|
|
120
|
+
getBenchmarkFacade(benchmarkId) {
|
|
121
|
+
return callRunloopPlatformGetter('benchmark.fromId', this.sdk.benchmark?.fromId, benchmarkId);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
exports.RunloopPlatformBenchmarksClient = RunloopPlatformBenchmarksClient;
|
|
125
|
+
class RunloopPlatformSecretsClient {
|
|
126
|
+
sdk;
|
|
127
|
+
constructor(sdk) {
|
|
128
|
+
this.sdk = sdk;
|
|
129
|
+
}
|
|
130
|
+
async create(params) {
|
|
131
|
+
return await callRunloopPlatformMethod('secret.create', this.sdk.secret?.create, params);
|
|
132
|
+
}
|
|
133
|
+
async list(params = {}) {
|
|
134
|
+
return await callRunloopPlatformMethod('secret.list', this.sdk.secret
|
|
135
|
+
?.list, params);
|
|
136
|
+
}
|
|
137
|
+
async get(name, params = {}) {
|
|
138
|
+
return await callRunloopPlatformMethod('api.secrets.retrieve', this.sdk.api?.secrets?.retrieve, name, params);
|
|
139
|
+
}
|
|
140
|
+
async update(params) {
|
|
141
|
+
return await callRunloopPlatformMethod('secret.update', this.sdk.secret?.update, params.name, { value: params.value });
|
|
142
|
+
}
|
|
143
|
+
async delete(name, params = {}) {
|
|
144
|
+
return await callRunloopPlatformMethod('secret.delete', this.sdk.secret
|
|
145
|
+
?.delete, name, params);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
exports.RunloopPlatformSecretsClient = RunloopPlatformSecretsClient;
|
|
149
|
+
class RunloopPlatformNetworkPoliciesClient {
|
|
150
|
+
sdk;
|
|
151
|
+
constructor(sdk) {
|
|
152
|
+
this.sdk = sdk;
|
|
153
|
+
}
|
|
154
|
+
async create(params = {}) {
|
|
155
|
+
return await callRunloopPlatformMethod('networkPolicy.create', this.sdk.networkPolicy?.create, params);
|
|
156
|
+
}
|
|
157
|
+
async list(params = {}) {
|
|
158
|
+
return await callRunloopPlatformMethod('networkPolicy.list', this.sdk.networkPolicy?.list, params);
|
|
159
|
+
}
|
|
160
|
+
get(networkPolicyId) {
|
|
161
|
+
return callRunloopPlatformGetter('networkPolicy.fromId', this.sdk.networkPolicy?.fromId, networkPolicyId);
|
|
162
|
+
}
|
|
163
|
+
async update(networkPolicyId, params = {}) {
|
|
164
|
+
return await callRunloopPlatformMethod('networkPolicy.update', bindRunloopMethod(this.get(networkPolicyId), 'update'), params);
|
|
165
|
+
}
|
|
166
|
+
async delete(networkPolicyId, params = {}) {
|
|
167
|
+
return await callRunloopPlatformMethod('networkPolicy.delete', bindRunloopMethod(this.get(networkPolicyId), 'delete'), params);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
exports.RunloopPlatformNetworkPoliciesClient = RunloopPlatformNetworkPoliciesClient;
|
|
171
|
+
class RunloopPlatformAxonsClient {
|
|
172
|
+
sdk;
|
|
173
|
+
constructor(sdk) {
|
|
174
|
+
this.sdk = sdk;
|
|
175
|
+
}
|
|
176
|
+
async create(params = {}) {
|
|
177
|
+
return await callRunloopPlatformMethod('axon.create', this.sdk.axon?.create, params);
|
|
178
|
+
}
|
|
179
|
+
async list(params = {}) {
|
|
180
|
+
return await callRunloopPlatformMethod('axon.list', this.sdk.axon?.list, params);
|
|
181
|
+
}
|
|
182
|
+
get(axonId) {
|
|
183
|
+
return callRunloopPlatformGetter('axon.fromId', this.sdk.axon?.fromId, axonId);
|
|
184
|
+
}
|
|
185
|
+
async publish(axonId, params = {}) {
|
|
186
|
+
return await callRunloopPlatformMethod('axon.publish', bindRunloopMethod(this.get(axonId), 'publish'), params);
|
|
187
|
+
}
|
|
188
|
+
async querySql(axonId, params = {}) {
|
|
189
|
+
const axon = this.get(axonId);
|
|
190
|
+
return await callRunloopPlatformMethod('axon.sql.query', bindRunloopMethod(axon.sql, 'query'), params);
|
|
191
|
+
}
|
|
192
|
+
async batchSql(axonId, params = {}) {
|
|
193
|
+
const axon = this.get(axonId);
|
|
194
|
+
return await callRunloopPlatformMethod('axon.sql.batch', bindRunloopMethod(axon.sql, 'batch'), params);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
exports.RunloopPlatformAxonsClient = RunloopPlatformAxonsClient;
|
|
198
|
+
class RunloopPlatformClient {
|
|
199
|
+
sdk;
|
|
200
|
+
constructor(sdk) {
|
|
201
|
+
this.sdk = sdk;
|
|
202
|
+
}
|
|
203
|
+
get blueprints() {
|
|
204
|
+
return new RunloopPlatformBlueprintsClient(this.sdk);
|
|
205
|
+
}
|
|
206
|
+
get benchmarks() {
|
|
207
|
+
return new RunloopPlatformBenchmarksClient(this.sdk);
|
|
208
|
+
}
|
|
209
|
+
get secrets() {
|
|
210
|
+
return new RunloopPlatformSecretsClient(this.sdk);
|
|
211
|
+
}
|
|
212
|
+
get networkPolicies() {
|
|
213
|
+
return new RunloopPlatformNetworkPoliciesClient(this.sdk);
|
|
214
|
+
}
|
|
215
|
+
get axons() {
|
|
216
|
+
return new RunloopPlatformAxonsClient(this.sdk);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
exports.RunloopPlatformClient = RunloopPlatformClient;
|
|
220
|
+
class RunloopSandboxSession extends shared_1.RemoteSandboxSessionBase {
|
|
221
|
+
sdk;
|
|
222
|
+
devbox;
|
|
223
|
+
activeMountPaths = new Set();
|
|
224
|
+
constructor(args) {
|
|
225
|
+
super({
|
|
226
|
+
state: args.state,
|
|
227
|
+
options: {
|
|
228
|
+
providerName: 'RunloopSandboxClient',
|
|
229
|
+
providerId: 'runloop',
|
|
230
|
+
concurrencyLimits: args.concurrencyLimits,
|
|
231
|
+
},
|
|
232
|
+
});
|
|
233
|
+
this.sdk = args.sdk;
|
|
234
|
+
this.devbox = args.devbox;
|
|
235
|
+
}
|
|
236
|
+
supportsPty() {
|
|
237
|
+
return false;
|
|
238
|
+
}
|
|
239
|
+
exposedPortSource() {
|
|
240
|
+
return 'tunnel URL';
|
|
241
|
+
}
|
|
242
|
+
async resolveRemoteExposedPort(port) {
|
|
243
|
+
return await this.ensureTunnelUrl(port);
|
|
244
|
+
}
|
|
245
|
+
resolveManifestForApply(manifest) {
|
|
246
|
+
return resolveRunloopManifestRoot(manifest, this.state.userParameters, true);
|
|
247
|
+
}
|
|
248
|
+
async beforeApplyManifest(manifest) {
|
|
249
|
+
await this.ensureManifestRoot(manifest.root);
|
|
250
|
+
}
|
|
251
|
+
async persistWorkspace() {
|
|
252
|
+
const snapshot = await this.persistWorkspaceViaNativeSnapshot();
|
|
253
|
+
if (snapshot) {
|
|
254
|
+
return snapshot;
|
|
255
|
+
}
|
|
256
|
+
(0, shared_1.assertTarWorkspacePersistence)('RunloopSandboxClient', 'tar');
|
|
257
|
+
return await this.persistWorkspaceTar();
|
|
258
|
+
}
|
|
259
|
+
async hydrateWorkspace(data) {
|
|
260
|
+
const snapshotRef = (0, shared_1.decodeNativeSnapshotRef)(data);
|
|
261
|
+
if (snapshotRef?.provider === 'runloop') {
|
|
262
|
+
await this.replaceDevboxFromSnapshot(snapshotRef.snapshotId);
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
(0, shared_1.assertTarWorkspacePersistence)('RunloopSandboxClient', 'tar');
|
|
266
|
+
await this.hydrateWorkspaceTar(data);
|
|
267
|
+
}
|
|
268
|
+
async close() {
|
|
269
|
+
if (this.state.pauseOnExit) {
|
|
270
|
+
await (0, shared_1.withSandboxSpan)('sandbox.stop', {
|
|
271
|
+
backend_id: 'runloop',
|
|
272
|
+
devbox_id: this.state.devboxId,
|
|
273
|
+
}, async () => {
|
|
274
|
+
await this.devbox.suspend(runloopRequestOptions(this.state.timeouts?.suspendTimeoutMs));
|
|
275
|
+
});
|
|
276
|
+
return;
|
|
277
|
+
}
|
|
278
|
+
await (0, shared_1.withSandboxSpan)('sandbox.shutdown', {
|
|
279
|
+
backend_id: 'runloop',
|
|
280
|
+
devbox_id: this.state.devboxId,
|
|
281
|
+
}, async () => {
|
|
282
|
+
await this.unmountActiveMounts();
|
|
283
|
+
await this.devbox.shutdown(runloopRequestOptions(this.state.timeouts?.cleanupTimeoutMs));
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
async shutdown() {
|
|
287
|
+
await this.close();
|
|
288
|
+
}
|
|
289
|
+
async delete() {
|
|
290
|
+
await (0, shared_1.withSandboxSpan)('sandbox.shutdown', {
|
|
291
|
+
backend_id: 'runloop',
|
|
292
|
+
devbox_id: this.state.devboxId,
|
|
293
|
+
}, async () => {
|
|
294
|
+
await this.unmountActiveMounts();
|
|
295
|
+
await this.devbox.shutdown(runloopRequestOptions(this.state.timeouts?.cleanupTimeoutMs));
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
async persistWorkspaceViaNativeSnapshot() {
|
|
299
|
+
if (this.nativeSnapshotRequiresTarFallback()) {
|
|
300
|
+
return undefined;
|
|
301
|
+
}
|
|
302
|
+
if (!this.devbox.snapshotDisk) {
|
|
303
|
+
return undefined;
|
|
304
|
+
}
|
|
305
|
+
let snapshot;
|
|
306
|
+
try {
|
|
307
|
+
const snapshotOptions = runloopLongPollOptions(this.state.timeouts?.snapshotTimeoutMs);
|
|
308
|
+
const snapshotParams = {
|
|
309
|
+
name: `sandbox-${this.state.devboxId}`,
|
|
310
|
+
metadata: {
|
|
311
|
+
openai_agents_devbox_id: this.state.devboxId,
|
|
312
|
+
},
|
|
313
|
+
};
|
|
314
|
+
snapshot = snapshotOptions
|
|
315
|
+
? await this.devbox.snapshotDisk(snapshotParams, snapshotOptions)
|
|
316
|
+
: await this.devbox.snapshotDisk(snapshotParams);
|
|
317
|
+
}
|
|
318
|
+
catch (error) {
|
|
319
|
+
throw new sandbox_1.SandboxProviderError('RunloopSandboxClient failed to create a native disk snapshot.', {
|
|
320
|
+
provider: 'runloop',
|
|
321
|
+
devboxId: this.state.devboxId,
|
|
322
|
+
cause: error instanceof Error ? error.message : String(error),
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
if (!snapshot.id) {
|
|
326
|
+
throw new sandbox_1.SandboxProviderError('RunloopSandboxClient native disk snapshot did not return a snapshot id.', {
|
|
327
|
+
provider: 'runloop',
|
|
328
|
+
devboxId: this.state.devboxId,
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
return (0, shared_1.encodeNativeSnapshotRef)({
|
|
332
|
+
provider: 'runloop',
|
|
333
|
+
snapshotId: snapshot.id,
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
nativeSnapshotRequiresTarFallback() {
|
|
337
|
+
return this.state.manifest.ephemeralPersistencePaths().size > 0;
|
|
338
|
+
}
|
|
339
|
+
async replaceDevboxFromSnapshot(snapshotId) {
|
|
340
|
+
if (!this.sdk.devbox.createFromSnapshot) {
|
|
341
|
+
throw new sandbox_1.SandboxProviderError('RunloopSandboxClient native snapshot restore requires createFromSnapshot(snapshotId).', {
|
|
342
|
+
provider: 'runloop',
|
|
343
|
+
snapshotId,
|
|
344
|
+
});
|
|
345
|
+
}
|
|
346
|
+
const previousDevbox = this.devbox;
|
|
347
|
+
const previousActiveMountPaths = new Set(this.activeMountPaths);
|
|
348
|
+
let devbox;
|
|
349
|
+
try {
|
|
350
|
+
devbox = await this.sdk.devbox.createFromSnapshot(snapshotId, createRunloopParams(this.state, this.state.environment, {
|
|
351
|
+
includeBlueprint: false,
|
|
352
|
+
includeSecrets: false,
|
|
353
|
+
}), createRunloopOptions(this.state));
|
|
354
|
+
}
|
|
355
|
+
catch (error) {
|
|
356
|
+
throw new sandbox_1.SandboxProviderError('RunloopSandboxClient failed to restore a native disk snapshot.', {
|
|
357
|
+
provider: 'runloop',
|
|
358
|
+
snapshotId,
|
|
359
|
+
cause: error instanceof Error ? error.message : String(error),
|
|
360
|
+
});
|
|
361
|
+
}
|
|
362
|
+
const previousDevboxId = this.state.devboxId;
|
|
363
|
+
this.devbox = devbox;
|
|
364
|
+
this.state.devboxId = devbox.id;
|
|
365
|
+
this.activeMountPaths.clear();
|
|
366
|
+
invalidateRunloopRuntimeCaches(this.state);
|
|
367
|
+
try {
|
|
368
|
+
await rematerializeRunloopManifestMounts(this, this.state.manifest);
|
|
369
|
+
}
|
|
370
|
+
catch (error) {
|
|
371
|
+
let replacementCleanupCause;
|
|
372
|
+
try {
|
|
373
|
+
await this.unmountActiveMounts();
|
|
374
|
+
}
|
|
375
|
+
catch (unmountError) {
|
|
376
|
+
replacementCleanupCause = errorMessage(unmountError);
|
|
377
|
+
}
|
|
378
|
+
try {
|
|
379
|
+
await devbox.shutdown();
|
|
380
|
+
}
|
|
381
|
+
catch (shutdownError) {
|
|
382
|
+
replacementCleanupCause = replacementCleanupCause
|
|
383
|
+
? `${replacementCleanupCause}; ${errorMessage(shutdownError)}`
|
|
384
|
+
: errorMessage(shutdownError);
|
|
385
|
+
}
|
|
386
|
+
this.devbox = previousDevbox;
|
|
387
|
+
this.state.devboxId = previousDevboxId;
|
|
388
|
+
this.activeMountPaths.clear();
|
|
389
|
+
for (const mountPath of previousActiveMountPaths) {
|
|
390
|
+
this.activeMountPaths.add(mountPath);
|
|
391
|
+
}
|
|
392
|
+
invalidateRunloopRuntimeCaches(this.state);
|
|
393
|
+
throw new sandbox_1.SandboxProviderError('RunloopSandboxClient native snapshot restore failed while rematerializing mounts.', {
|
|
394
|
+
provider: 'runloop',
|
|
395
|
+
devboxId: previousDevboxId,
|
|
396
|
+
replacementDevboxId: devbox.id,
|
|
397
|
+
snapshotId,
|
|
398
|
+
cause: errorMessage(error),
|
|
399
|
+
...(replacementCleanupCause ? { replacementCleanupCause } : {}),
|
|
400
|
+
});
|
|
401
|
+
}
|
|
402
|
+
try {
|
|
403
|
+
await previousDevbox.shutdown();
|
|
404
|
+
}
|
|
405
|
+
catch (error) {
|
|
406
|
+
let replacementShutdownCause;
|
|
407
|
+
try {
|
|
408
|
+
await this.unmountActiveMounts();
|
|
409
|
+
}
|
|
410
|
+
catch (unmountError) {
|
|
411
|
+
replacementShutdownCause = errorMessage(unmountError);
|
|
412
|
+
}
|
|
413
|
+
try {
|
|
414
|
+
await devbox.shutdown();
|
|
415
|
+
}
|
|
416
|
+
catch (replacementShutdownError) {
|
|
417
|
+
replacementShutdownCause = replacementShutdownCause
|
|
418
|
+
? `${replacementShutdownCause}; ${errorMessage(replacementShutdownError)}`
|
|
419
|
+
: errorMessage(replacementShutdownError);
|
|
420
|
+
}
|
|
421
|
+
this.devbox = previousDevbox;
|
|
422
|
+
this.state.devboxId = previousDevboxId;
|
|
423
|
+
this.activeMountPaths.clear();
|
|
424
|
+
for (const mountPath of previousActiveMountPaths) {
|
|
425
|
+
this.activeMountPaths.add(mountPath);
|
|
426
|
+
}
|
|
427
|
+
invalidateRunloopRuntimeCaches(this.state);
|
|
428
|
+
throw new sandbox_1.SandboxProviderError('RunloopSandboxClient native snapshot restore created a replacement devbox, but shutting down the previous devbox failed.', {
|
|
429
|
+
provider: 'runloop',
|
|
430
|
+
devboxId: previousDevbox.id,
|
|
431
|
+
replacementDevboxId: devbox.id,
|
|
432
|
+
snapshotId,
|
|
433
|
+
cause: errorMessage(error),
|
|
434
|
+
...(replacementShutdownCause ? { replacementShutdownCause } : {}),
|
|
435
|
+
});
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
manifestMetadataSupport() {
|
|
439
|
+
return shared_1.SANDBOX_MANIFEST_METADATA_SUPPORT;
|
|
440
|
+
}
|
|
441
|
+
manifestMaterializationOptions() {
|
|
442
|
+
return {
|
|
443
|
+
materializeMount: this.materializeMountEntry.bind(this),
|
|
444
|
+
};
|
|
445
|
+
}
|
|
446
|
+
assertExecRunAs(_runAs) {
|
|
447
|
+
void _runAs;
|
|
448
|
+
}
|
|
449
|
+
assertFilesystemRunAs(_runAs) {
|
|
450
|
+
(0, shared_1.assertRunAsUnsupported)('RunloopSandboxClient', _runAs);
|
|
451
|
+
}
|
|
452
|
+
async materializeMountEntry(absolutePath, entry) {
|
|
453
|
+
if (!(0, mounts_1.isRunloopCloudBucketMountEntry)(entry)) {
|
|
454
|
+
throw new sandbox_1.SandboxUnsupportedFeatureError('RunloopSandboxClient only supports RunloopCloudBucketMountStrategy mount entries.', {
|
|
455
|
+
provider: 'runloop',
|
|
456
|
+
feature: 'entry.mountStrategy',
|
|
457
|
+
path: absolutePath,
|
|
458
|
+
mountType: entry.type,
|
|
459
|
+
strategyType: entry.mountStrategy?.type,
|
|
460
|
+
});
|
|
461
|
+
}
|
|
462
|
+
const mountPath = await this.resolveRemotePath(entry.mountPath ?? absolutePath, { forWrite: true });
|
|
463
|
+
await (0, inContainerMounts_1.mountRcloneCloudBucket)({
|
|
464
|
+
providerName: 'RunloopSandboxClient',
|
|
465
|
+
providerId: 'runloop',
|
|
466
|
+
strategyType: 'runloop_cloud_bucket',
|
|
467
|
+
entry,
|
|
468
|
+
mountPath,
|
|
469
|
+
pattern: (0, inContainerMounts_1.rclonePatternFromMountStrategy)(entry.mountStrategy),
|
|
470
|
+
runCommand: this.mountCommandRunner(),
|
|
471
|
+
writeFile: this.writeRemoteFile.bind(this),
|
|
472
|
+
packageManagers: ['apt'],
|
|
473
|
+
installRcloneViaScript: true,
|
|
474
|
+
});
|
|
475
|
+
this.activeMountPaths.add(mountPath);
|
|
476
|
+
}
|
|
477
|
+
async rematerializeManifestMounts(manifest) {
|
|
478
|
+
for (const { absolutePath, entry, } of manifest.mountTargetsForMaterialization()) {
|
|
479
|
+
await this.materializeMountEntry(absolutePath, structuredClone(entry));
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
async cleanupAfterFailedResume() {
|
|
483
|
+
await this.unmountActiveMounts().catch(() => { });
|
|
484
|
+
if (this.state.pauseOnExit) {
|
|
485
|
+
await this.devbox
|
|
486
|
+
.suspend(runloopRequestOptions(this.state.timeouts?.suspendTimeoutMs))
|
|
487
|
+
.catch(() => { });
|
|
488
|
+
return;
|
|
489
|
+
}
|
|
490
|
+
await this.devbox
|
|
491
|
+
.shutdown(runloopRequestOptions(this.state.timeouts?.cleanupTimeoutMs))
|
|
492
|
+
.catch(() => { });
|
|
493
|
+
}
|
|
494
|
+
async ensureCurrentManifestRoot() {
|
|
495
|
+
await this.ensureManifestRoot(this.state.manifest.root);
|
|
496
|
+
}
|
|
497
|
+
async unmountActiveMounts() {
|
|
498
|
+
for (const mountPath of [...this.activeMountPaths].reverse()) {
|
|
499
|
+
await (0, inContainerMounts_1.unmountRcloneMount)({
|
|
500
|
+
providerName: 'RunloopSandboxClient',
|
|
501
|
+
providerId: 'runloop',
|
|
502
|
+
mountPath,
|
|
503
|
+
runCommand: this.mountCommandRunner(),
|
|
504
|
+
}).catch(() => { });
|
|
505
|
+
this.activeMountPaths.delete(mountPath);
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
mountCommandRunner() {
|
|
509
|
+
return async (command, options = {}) => {
|
|
510
|
+
const result = await this.execShellWithEnvironment(command, undefined, options.timeoutMs ?? this.state.timeouts?.fastOperationTimeoutMs, mountCommandEnvironment(this.state.environment, options.user, this.state.userParameters), options.user);
|
|
511
|
+
return {
|
|
512
|
+
status: runloopExitStatus(result),
|
|
513
|
+
stdout: await result.stdout(),
|
|
514
|
+
stderr: await result.stderr(),
|
|
515
|
+
};
|
|
516
|
+
};
|
|
517
|
+
}
|
|
518
|
+
async ensureManifestRoot(root) {
|
|
519
|
+
const home = effectiveRunloopHome(this.state.userParameters);
|
|
520
|
+
const rootParent = root === home ? root : node_path_1.posix.dirname(root);
|
|
521
|
+
const result = await this.execShellInWorkdir([
|
|
522
|
+
`home_real=$(cd -- ${(0, shared_1.shellQuote)(home)} && pwd -P)`,
|
|
523
|
+
`root_ancestor=${(0, shared_1.shellQuote)(rootParent)}`,
|
|
524
|
+
'while [ ! -e "$root_ancestor" ]; do parent=$(dirname -- "$root_ancestor"); [ "$parent" = "$root_ancestor" ] && break; root_ancestor="$parent"; done',
|
|
525
|
+
'ancestor_real=$(cd -- "$root_ancestor" && pwd -P)',
|
|
526
|
+
`printf 'OPENAI_AGENTS_REALPATH_HOME=%s\\nOPENAI_AGENTS_REALPATH_ANCESTOR=%s\\n' "$home_real" "$ancestor_real"`,
|
|
527
|
+
'case "$ancestor_real" in "$home_real"|"$home_real"/*) ancestor_confined=1 ;; *) ancestor_confined=0 ;; esac',
|
|
528
|
+
`if [ "$home_real" = / ] || [ "$ancestor_confined" != 1 ]; then printf 'OPENAI_AGENTS_REALPATH_ROOT=%s\\n' ''; exit 0; fi`,
|
|
529
|
+
`mkdir -p -- ${(0, shared_1.shellQuote)(root)}`,
|
|
530
|
+
`root_real=$(cd -- ${(0, shared_1.shellQuote)(root)} && pwd -P)`,
|
|
531
|
+
`printf 'OPENAI_AGENTS_REALPATH_ROOT=%s\\n' "$root_real"`,
|
|
532
|
+
].join(' && '), home, this.state.timeouts?.fastOperationTimeoutMs, {});
|
|
533
|
+
if (!runloopSucceeded(result)) {
|
|
534
|
+
throw new sandbox_1.SandboxProviderError('RunloopSandboxClient failed to prepare the workspace root.', {
|
|
535
|
+
provider: 'runloop',
|
|
536
|
+
root,
|
|
537
|
+
exitCode: runloopExitStatus(result),
|
|
538
|
+
stderr: await result.stderr(),
|
|
539
|
+
});
|
|
540
|
+
}
|
|
541
|
+
assertRunloopManifestRootRealPath(root, home, await result.stdout());
|
|
542
|
+
}
|
|
543
|
+
async execShellWithEnvironment(command, workdir, timeoutMs, environment, user) {
|
|
544
|
+
return await this.execShellInWorkdir(command, this.resolveWorkdir(workdir), timeoutMs, environment, user);
|
|
545
|
+
}
|
|
546
|
+
async execShellInWorkdir(command, workdir, timeoutMs, environment, user) {
|
|
547
|
+
const shellCommand = buildShellCommand(command, environment, workdir, user, this.state.userParameters);
|
|
548
|
+
const params = {
|
|
549
|
+
last_n: '2000',
|
|
550
|
+
};
|
|
551
|
+
const options = runloopLongPollOptions(timeoutMs);
|
|
552
|
+
return options
|
|
553
|
+
? await this.devbox.cmd.exec(shellCommand, params, options)
|
|
554
|
+
: await this.devbox.cmd.exec(shellCommand, params);
|
|
555
|
+
}
|
|
556
|
+
async runRemoteCommand(command, options) {
|
|
557
|
+
const result = await this.execShellInWorkdir(command, options.workdir, options.timeoutMs ?? this.timeoutForCommand(options), remoteCommandEnvironment(this.state.environment, options), options.runAs);
|
|
558
|
+
return {
|
|
559
|
+
status: runloopExitStatus(result),
|
|
560
|
+
stdout: await result.stdout(),
|
|
561
|
+
stderr: await result.stderr(),
|
|
562
|
+
};
|
|
563
|
+
}
|
|
564
|
+
async mkdirRemote(path) {
|
|
565
|
+
const result = await this.runRemoteCommand(`mkdir -p -- ${(0, shared_1.shellQuote)(path)}`, {
|
|
566
|
+
kind: 'manifest',
|
|
567
|
+
workdir: this.state.manifest.root,
|
|
568
|
+
timeoutMs: this.state.timeouts?.fastOperationTimeoutMs,
|
|
569
|
+
});
|
|
570
|
+
this.assertRemoteCommandSucceeded(result, 'create directory', path);
|
|
571
|
+
}
|
|
572
|
+
async readRemoteText(path) {
|
|
573
|
+
return await this.devbox.file.read({
|
|
574
|
+
file_path: path,
|
|
575
|
+
});
|
|
576
|
+
}
|
|
577
|
+
async readRemoteFile(path) {
|
|
578
|
+
const downloadOptions = runloopRequestOptions(this.state.timeouts?.fileDownloadTimeoutMs);
|
|
579
|
+
const response = downloadOptions
|
|
580
|
+
? await this.devbox.file.download({ path }, downloadOptions)
|
|
581
|
+
: await this.devbox.file.download({ path });
|
|
582
|
+
if (response.buffer) {
|
|
583
|
+
return Uint8Array.from(await response.buffer());
|
|
584
|
+
}
|
|
585
|
+
return new Uint8Array(await response.arrayBuffer());
|
|
586
|
+
}
|
|
587
|
+
async writeRemoteFile(path, content) {
|
|
588
|
+
const uploadOptions = runloopRequestOptions(this.state.timeouts?.fileUploadTimeoutMs);
|
|
589
|
+
const uploadParams = {
|
|
590
|
+
path,
|
|
591
|
+
file: new File([typeof content === 'string' ? content : Uint8Array.from(content)], basename(path)),
|
|
592
|
+
};
|
|
593
|
+
if (uploadOptions) {
|
|
594
|
+
await this.devbox.file.upload(uploadParams, uploadOptions);
|
|
595
|
+
}
|
|
596
|
+
else {
|
|
597
|
+
await this.devbox.file.upload(uploadParams);
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
async deleteRemotePath(path) {
|
|
601
|
+
const result = await this.runRemoteCommand(`rm -f -- ${(0, shared_1.shellQuote)(path)}`, {
|
|
602
|
+
kind: 'manifest',
|
|
603
|
+
workdir: this.state.manifest.root,
|
|
604
|
+
timeoutMs: this.state.timeouts?.fastOperationTimeoutMs,
|
|
605
|
+
});
|
|
606
|
+
this.assertRemoteCommandSucceeded(result, 'delete path', path);
|
|
607
|
+
}
|
|
608
|
+
assertRemoteCommandSucceeded(result, operation, path) {
|
|
609
|
+
if (result.status === 0) {
|
|
610
|
+
return;
|
|
611
|
+
}
|
|
612
|
+
throw new sandbox_1.SandboxProviderError(`RunloopSandboxClient failed to ${operation}.`, {
|
|
613
|
+
provider: 'runloop',
|
|
614
|
+
operation,
|
|
615
|
+
devboxId: this.state.devboxId,
|
|
616
|
+
path,
|
|
617
|
+
exitCode: result.status,
|
|
618
|
+
stdout: result.stdout ?? '',
|
|
619
|
+
stderr: result.stderr ?? '',
|
|
620
|
+
});
|
|
621
|
+
}
|
|
622
|
+
timeoutForCommand(options) {
|
|
623
|
+
if (options.kind === 'exec') {
|
|
624
|
+
return this.state.timeouts?.execTimeoutMs;
|
|
625
|
+
}
|
|
626
|
+
if (options.kind === 'running') {
|
|
627
|
+
return this.state.timeouts?.keepAliveTimeoutMs;
|
|
628
|
+
}
|
|
629
|
+
if (options.kind === 'archive') {
|
|
630
|
+
return this.state.timeouts?.snapshotTimeoutMs;
|
|
631
|
+
}
|
|
632
|
+
if (options.kind === 'path' || options.kind === 'manifest') {
|
|
633
|
+
return this.state.timeouts?.fastOperationTimeoutMs;
|
|
634
|
+
}
|
|
635
|
+
return undefined;
|
|
636
|
+
}
|
|
637
|
+
async ensureTunnelUrl(port) {
|
|
638
|
+
const existingUrl = await this.getTunnelUrl(port);
|
|
639
|
+
if (existingUrl) {
|
|
640
|
+
return existingUrl;
|
|
641
|
+
}
|
|
642
|
+
if (!this.devbox.net?.enableTunnel) {
|
|
643
|
+
throw new sandbox_1.SandboxProviderError('RunloopSandboxClient exposed port resolution requires a Runloop tunnel API.', {
|
|
644
|
+
provider: 'runloop',
|
|
645
|
+
port,
|
|
646
|
+
});
|
|
647
|
+
}
|
|
648
|
+
try {
|
|
649
|
+
const tunnelOptions = runloopRequestOptions(this.state.timeouts?.fastOperationTimeoutMs);
|
|
650
|
+
const tunnelParams = runloopTunnelEnableParams(this.state.tunnel);
|
|
651
|
+
if (!tunnelParams) {
|
|
652
|
+
throw new sandbox_1.SandboxProviderError(`RunloopSandboxClient cannot enable a tunnel for exposed port ${port} because tunnel is disabled.`, {
|
|
653
|
+
provider: 'runloop',
|
|
654
|
+
port,
|
|
655
|
+
});
|
|
656
|
+
}
|
|
657
|
+
if (tunnelOptions) {
|
|
658
|
+
await this.devbox.net.enableTunnel(tunnelParams, tunnelOptions);
|
|
659
|
+
}
|
|
660
|
+
else {
|
|
661
|
+
await this.devbox.net.enableTunnel(tunnelParams);
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
catch (error) {
|
|
665
|
+
throw new sandbox_1.SandboxProviderError(`RunloopSandboxClient failed to enable a tunnel for exposed port ${port}.`, {
|
|
666
|
+
provider: 'runloop',
|
|
667
|
+
port,
|
|
668
|
+
cause: error instanceof Error ? error.message : String(error),
|
|
669
|
+
});
|
|
670
|
+
}
|
|
671
|
+
const enabledUrl = await this.getTunnelUrl(port);
|
|
672
|
+
if (!enabledUrl) {
|
|
673
|
+
throw new sandbox_1.SandboxProviderError(`RunloopSandboxClient did not return a tunnel URL for exposed port ${port}.`, {
|
|
674
|
+
provider: 'runloop',
|
|
675
|
+
port,
|
|
676
|
+
});
|
|
677
|
+
}
|
|
678
|
+
return enabledUrl;
|
|
679
|
+
}
|
|
680
|
+
async getTunnelUrl(port) {
|
|
681
|
+
if (!this.devbox.getTunnelUrl) {
|
|
682
|
+
throw new sandbox_1.SandboxProviderError('RunloopSandboxClient exposed port resolution requires getTunnelUrl(port).', {
|
|
683
|
+
provider: 'runloop',
|
|
684
|
+
port,
|
|
685
|
+
});
|
|
686
|
+
}
|
|
687
|
+
try {
|
|
688
|
+
const tunnelOptions = runloopRequestOptions(this.state.timeouts?.fastOperationTimeoutMs);
|
|
689
|
+
const url = tunnelOptions
|
|
690
|
+
? await this.devbox.getTunnelUrl(port, tunnelOptions)
|
|
691
|
+
: await this.devbox.getTunnelUrl(port);
|
|
692
|
+
return typeof url === 'string' && url ? url : undefined;
|
|
693
|
+
}
|
|
694
|
+
catch {
|
|
695
|
+
return undefined;
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
exports.RunloopSandboxSession = RunloopSandboxSession;
|
|
700
|
+
/**
|
|
701
|
+
* @see {@link https://docs.runloop.ai/docs/devboxes/overview | Devbox overview}.
|
|
702
|
+
* @see {@link https://docs.runloop.ai/docs/devboxes/start-stop | Devbox lifecycle}.
|
|
703
|
+
* @see {@link https://runloopai.github.io/api-client-ts/stable/classes/sdk.DevboxOps.html | TypeScript SDK Devbox reference}.
|
|
704
|
+
*/
|
|
705
|
+
class RunloopSandboxClient {
|
|
706
|
+
backendId = 'runloop';
|
|
707
|
+
options;
|
|
708
|
+
constructor(options = {}) {
|
|
709
|
+
this.options = options;
|
|
710
|
+
}
|
|
711
|
+
async platform() {
|
|
712
|
+
return new RunloopPlatformClient(await createRunloopClient(this.options));
|
|
713
|
+
}
|
|
714
|
+
async create(args, manifestOptions) {
|
|
715
|
+
const createArgs = (0, sandbox_1.normalizeSandboxClientCreateArgs)(args, manifestOptions);
|
|
716
|
+
(0, shared_1.assertCoreSnapshotUnsupported)('RunloopSandboxClient', createArgs.snapshot);
|
|
717
|
+
const resolvedOptions = {
|
|
718
|
+
...this.options,
|
|
719
|
+
...createArgs.options,
|
|
720
|
+
};
|
|
721
|
+
const timeouts = resolveRunloopTimeouts(resolvedOptions);
|
|
722
|
+
const manifest = resolveRunloopManifestRoot(createArgs.manifest, resolvedOptions.userParameters, false);
|
|
723
|
+
(0, shared_1.assertSandboxManifestMetadataSupported)('RunloopSandboxClient', manifest, shared_1.SANDBOX_MANIFEST_METADATA_SUPPORT);
|
|
724
|
+
const sdk = await createRunloopClient(resolvedOptions);
|
|
725
|
+
return await (0, shared_1.withSandboxSpan)('sandbox.start', {
|
|
726
|
+
backend_id: this.backendId,
|
|
727
|
+
}, async () => {
|
|
728
|
+
const environment = await (0, shared_1.materializeEnvironment)(manifest, resolvedOptions.env);
|
|
729
|
+
const createParams = {
|
|
730
|
+
environment_variables: environment,
|
|
731
|
+
};
|
|
732
|
+
const createBlueprintId = resolvedOptions.blueprintName
|
|
733
|
+
? undefined
|
|
734
|
+
: resolvedOptions.blueprintId;
|
|
735
|
+
for (const key of [
|
|
736
|
+
'blueprintId',
|
|
737
|
+
'name',
|
|
738
|
+
'exposedPorts',
|
|
739
|
+
'tunnel',
|
|
740
|
+
'gateways',
|
|
741
|
+
'mcp',
|
|
742
|
+
'metadata',
|
|
743
|
+
]) {
|
|
744
|
+
const value = key === 'blueprintId' ? createBlueprintId : resolvedOptions[key];
|
|
745
|
+
if (value !== undefined) {
|
|
746
|
+
createParams[toSnakeCase(key)] = value;
|
|
747
|
+
}
|
|
748
|
+
}
|
|
749
|
+
if (resolvedOptions.userParameters ||
|
|
750
|
+
resolvedOptions.launchParameters) {
|
|
751
|
+
createParams.launch_parameters = {
|
|
752
|
+
...(resolvedOptions.launchParameters ?? {}),
|
|
753
|
+
user_parameters: resolvedOptions.userParameters,
|
|
754
|
+
};
|
|
755
|
+
}
|
|
756
|
+
const createOptions = runloopLongPollOptions(timeouts.createTimeoutMs);
|
|
757
|
+
const secretRefs = resolvedOptions.secretRefs ??
|
|
758
|
+
(await upsertRunloopManagedSecrets(sdk, resolvedOptions.managedSecrets, runloopRequestOptions(timeouts.fastOperationTimeoutMs) ??
|
|
759
|
+
createOptions));
|
|
760
|
+
const persistedSecretRefs = Object.keys(secretRefs).length > 0 ? secretRefs : undefined;
|
|
761
|
+
if (persistedSecretRefs) {
|
|
762
|
+
createParams.secrets = persistedSecretRefs;
|
|
763
|
+
}
|
|
764
|
+
const devbox = await (0, shared_1.withProviderError)('RunloopSandboxClient', 'runloop', 'create devbox', async () => resolvedOptions.blueprintName
|
|
765
|
+
? await sdk.devbox.createFromBlueprintName(resolvedOptions.blueprintName, createParams, createOptions)
|
|
766
|
+
: await sdk.devbox.create(createParams, createOptions), {
|
|
767
|
+
blueprintName: resolvedOptions.blueprintName,
|
|
768
|
+
blueprintId: createBlueprintId,
|
|
769
|
+
});
|
|
770
|
+
const session = new RunloopSandboxSession({
|
|
771
|
+
sdk,
|
|
772
|
+
devbox,
|
|
773
|
+
concurrencyLimits: createArgs.concurrencyLimits,
|
|
774
|
+
state: {
|
|
775
|
+
manifest,
|
|
776
|
+
devboxId: devbox.id,
|
|
777
|
+
blueprintName: resolvedOptions.blueprintName,
|
|
778
|
+
blueprintId: createBlueprintId,
|
|
779
|
+
name: resolvedOptions.name,
|
|
780
|
+
launchParameters: resolvedOptions.launchParameters,
|
|
781
|
+
configuredExposedPorts: resolvedOptions.exposedPorts,
|
|
782
|
+
tunnel: resolvedOptions.tunnel,
|
|
783
|
+
gateways: resolvedOptions.gateways,
|
|
784
|
+
mcp: resolvedOptions.mcp,
|
|
785
|
+
metadata: resolvedOptions.metadata,
|
|
786
|
+
secretRefs: persistedSecretRefs,
|
|
787
|
+
pauseOnExit: resolvedOptions.pauseOnExit ?? false,
|
|
788
|
+
userParameters: resolvedOptions.userParameters,
|
|
789
|
+
environment,
|
|
790
|
+
baseUrl: resolvedOptions.baseUrl,
|
|
791
|
+
createTimeoutMs: timeouts.createTimeoutMs,
|
|
792
|
+
timeouts,
|
|
793
|
+
},
|
|
794
|
+
});
|
|
795
|
+
try {
|
|
796
|
+
await session.applyManifest(manifest);
|
|
797
|
+
}
|
|
798
|
+
catch (error) {
|
|
799
|
+
session.state.pauseOnExit = false;
|
|
800
|
+
await (0, shared_1.closeRemoteSessionOnManifestError)('Runloop', session, error);
|
|
801
|
+
}
|
|
802
|
+
return session;
|
|
803
|
+
});
|
|
804
|
+
}
|
|
805
|
+
async serializeSessionState(state) {
|
|
806
|
+
const { managedSecrets: _managedSecrets, ...serializableState } = state;
|
|
807
|
+
return (0, shared_1.serializeRemoteSandboxSessionState)(serializableState);
|
|
808
|
+
}
|
|
809
|
+
canPersistOwnedSessionState(state) {
|
|
810
|
+
return state.pauseOnExit;
|
|
811
|
+
}
|
|
812
|
+
async deserializeSessionState(state) {
|
|
813
|
+
const baseState = (0, shared_1.deserializeRemoteSandboxSessionStateValues)(state, this.options.env);
|
|
814
|
+
const { managedSecrets: _managedSecrets, ...rest } = state;
|
|
815
|
+
return {
|
|
816
|
+
...rest,
|
|
817
|
+
...baseState,
|
|
818
|
+
devboxId: (0, shared_1.readString)(state, 'devboxId'),
|
|
819
|
+
blueprintName: (0, shared_1.readOptionalString)(state, 'blueprintName'),
|
|
820
|
+
blueprintId: (0, shared_1.readOptionalString)(state, 'blueprintId'),
|
|
821
|
+
name: (0, shared_1.readOptionalString)(state, 'name'),
|
|
822
|
+
launchParameters: (0, shared_1.readOptionalRecord)(state.launchParameters),
|
|
823
|
+
configuredExposedPorts: (0, shared_1.readOptionalNumberArray)(state.configuredExposedPorts),
|
|
824
|
+
tunnel: typeof state.tunnel === 'boolean' || (0, shared_1.isRecord)(state.tunnel)
|
|
825
|
+
? state.tunnel
|
|
826
|
+
: undefined,
|
|
827
|
+
gateways: (0, shared_1.readOptionalRecord)(state.gateways),
|
|
828
|
+
mcp: (0, shared_1.readOptionalRecord)(state.mcp),
|
|
829
|
+
metadata: (0, shared_1.readOptionalStringRecord)(state.metadata),
|
|
830
|
+
secretRefs: (0, shared_1.readOptionalStringRecord)(state.secretRefs),
|
|
831
|
+
pauseOnExit: Boolean(state.pauseOnExit),
|
|
832
|
+
userParameters: typeof state.userParameters === 'object' && state.userParameters
|
|
833
|
+
? state.userParameters
|
|
834
|
+
: undefined,
|
|
835
|
+
baseUrl: (0, shared_1.readOptionalString)(state, 'baseUrl'),
|
|
836
|
+
createTimeoutMs: (0, shared_1.readOptionalNumber)(state, 'createTimeoutMs'),
|
|
837
|
+
timeouts: resolveRunloopTimeouts({
|
|
838
|
+
createTimeoutMs: (0, shared_1.readOptionalNumber)(state, 'createTimeoutMs'),
|
|
839
|
+
timeouts: (0, shared_1.isRecord)(state.timeouts)
|
|
840
|
+
? state.timeouts
|
|
841
|
+
: undefined,
|
|
842
|
+
}),
|
|
843
|
+
};
|
|
844
|
+
}
|
|
845
|
+
async resume(state) {
|
|
846
|
+
const resumeState = {
|
|
847
|
+
...state,
|
|
848
|
+
baseUrl: this.options.baseUrl,
|
|
849
|
+
launchParameters: this.options.launchParameters,
|
|
850
|
+
userParameters: this.options.userParameters,
|
|
851
|
+
manifest: resolveRunloopManifestRoot(state.manifest, this.options.userParameters, true),
|
|
852
|
+
};
|
|
853
|
+
const sdk = await createRunloopClient(this.options);
|
|
854
|
+
try {
|
|
855
|
+
const devbox = sdk.devbox.fromId(resumeState.devboxId);
|
|
856
|
+
if (resumeState.pauseOnExit) {
|
|
857
|
+
await devbox.resume(runloopLongPollOptions(resumeState.timeouts?.resumeTimeoutMs));
|
|
858
|
+
}
|
|
859
|
+
invalidateRunloopRuntimeCaches(resumeState);
|
|
860
|
+
const session = new RunloopSandboxSession({
|
|
861
|
+
state: resumeState,
|
|
862
|
+
sdk,
|
|
863
|
+
devbox,
|
|
864
|
+
});
|
|
865
|
+
try {
|
|
866
|
+
await session.ensureCurrentManifestRoot();
|
|
867
|
+
await rematerializeRunloopManifestMounts(session, resumeState.manifest);
|
|
868
|
+
}
|
|
869
|
+
catch (error) {
|
|
870
|
+
await session.cleanupAfterFailedResume();
|
|
871
|
+
throw error;
|
|
872
|
+
}
|
|
873
|
+
return session;
|
|
874
|
+
}
|
|
875
|
+
catch (error) {
|
|
876
|
+
(0, shared_1.assertResumeRecreateAllowed)(error, {
|
|
877
|
+
providerName: 'RunloopSandboxClient',
|
|
878
|
+
provider: 'runloop',
|
|
879
|
+
details: { devboxId: resumeState.devboxId },
|
|
880
|
+
});
|
|
881
|
+
assertRunloopResumeRecreateSecretRefsTrusted(resumeState, this.options);
|
|
882
|
+
const recreateOptions = {
|
|
883
|
+
blueprintName: this.options.blueprintName,
|
|
884
|
+
blueprintId: this.options.blueprintId,
|
|
885
|
+
name: resumeState.name,
|
|
886
|
+
launchParameters: this.options.launchParameters,
|
|
887
|
+
exposedPorts: resumeState.configuredExposedPorts,
|
|
888
|
+
tunnel: resumeState.tunnel,
|
|
889
|
+
gateways: resumeState.gateways,
|
|
890
|
+
mcp: resumeState.mcp,
|
|
891
|
+
metadata: resumeState.metadata,
|
|
892
|
+
managedSecrets: this.options.managedSecrets,
|
|
893
|
+
pauseOnExit: resumeState.pauseOnExit,
|
|
894
|
+
userParameters: this.options.userParameters,
|
|
895
|
+
env: this.options.env,
|
|
896
|
+
baseUrl: this.options.baseUrl,
|
|
897
|
+
createTimeoutMs: resumeState.createTimeoutMs,
|
|
898
|
+
timeouts: resumeState.timeouts,
|
|
899
|
+
};
|
|
900
|
+
return await this.create(resumeState.manifest, recreateOptions);
|
|
901
|
+
}
|
|
902
|
+
}
|
|
903
|
+
}
|
|
904
|
+
exports.RunloopSandboxClient = RunloopSandboxClient;
|
|
905
|
+
async function createRunloopClient(options) {
|
|
906
|
+
try {
|
|
907
|
+
const { RunloopSDK } = await Promise.resolve().then(() => __importStar(require('@runloop/api-client')));
|
|
908
|
+
return adaptRunloopClient(new RunloopSDK({
|
|
909
|
+
...(options.apiKey ? { bearerToken: options.apiKey } : {}),
|
|
910
|
+
...(options.baseUrl ? { baseURL: options.baseUrl } : {}),
|
|
911
|
+
}));
|
|
912
|
+
}
|
|
913
|
+
catch (error) {
|
|
914
|
+
throw new agents_core_1.UserError(`Runloop sandbox support requires the optional \`@runloop/api-client\` package. Install it before using Runloop-backed sandbox examples. ${error.message}`);
|
|
915
|
+
}
|
|
916
|
+
}
|
|
917
|
+
function adaptRunloopClient(sdk) {
|
|
918
|
+
const createFromSnapshot = bindRunloopMethod(sdk.devbox, 'createFromSnapshot');
|
|
919
|
+
const secretList = bindRunloopMethod(sdk.secret, 'list');
|
|
920
|
+
const secretDelete = bindRunloopMethod(sdk.secret, 'delete');
|
|
921
|
+
return {
|
|
922
|
+
devbox: {
|
|
923
|
+
create: async (params, options) => adaptRunloopDevbox(await sdk.devbox.create(params, options)),
|
|
924
|
+
createFromBlueprintName: async (blueprintName, params, options) => adaptRunloopDevbox(await sdk.devbox.createFromBlueprintName(blueprintName, params, options)),
|
|
925
|
+
...(createFromSnapshot
|
|
926
|
+
? {
|
|
927
|
+
createFromSnapshot: async (snapshotId, params, options) => adaptRunloopDevbox((await createFromSnapshot(snapshotId, params, options))),
|
|
928
|
+
}
|
|
929
|
+
: {}),
|
|
930
|
+
fromId: (id) => adaptRunloopDevbox(sdk.devbox.fromId(id)),
|
|
931
|
+
},
|
|
932
|
+
secret: {
|
|
933
|
+
create: async (...args) => {
|
|
934
|
+
const [params, options] = args;
|
|
935
|
+
const createParams = params;
|
|
936
|
+
return args.length > 1
|
|
937
|
+
? await sdk.secret.create(createParams, options)
|
|
938
|
+
: await sdk.secret.create(createParams);
|
|
939
|
+
},
|
|
940
|
+
update: async (...args) => {
|
|
941
|
+
const [secret, params, options] = args;
|
|
942
|
+
const updateParams = params;
|
|
943
|
+
return args.length > 2
|
|
944
|
+
? await sdk.secret.update(secret, updateParams, options)
|
|
945
|
+
: await sdk.secret.update(secret, updateParams);
|
|
946
|
+
},
|
|
947
|
+
...(secretList
|
|
948
|
+
? {
|
|
949
|
+
list: async (...args) => {
|
|
950
|
+
const [params, options] = args;
|
|
951
|
+
return args.length > 1
|
|
952
|
+
? await secretList(params, options)
|
|
953
|
+
: await secretList(params);
|
|
954
|
+
},
|
|
955
|
+
}
|
|
956
|
+
: {}),
|
|
957
|
+
...(secretDelete
|
|
958
|
+
? {
|
|
959
|
+
delete: async (...args) => {
|
|
960
|
+
const [secret, params, options] = args;
|
|
961
|
+
return args.length > 2
|
|
962
|
+
? await secretDelete(secret, params, options)
|
|
963
|
+
: await secretDelete(secret, params);
|
|
964
|
+
},
|
|
965
|
+
}
|
|
966
|
+
: {}),
|
|
967
|
+
},
|
|
968
|
+
blueprint: adaptRunloopPlatformResource(sdk.blueprint),
|
|
969
|
+
benchmark: adaptRunloopBenchmarkResource(sdk),
|
|
970
|
+
networkPolicy: adaptRunloopPlatformResource(sdk.networkPolicy),
|
|
971
|
+
axon: adaptRunloopPlatformResource(sdk.axon),
|
|
972
|
+
api: adaptRunloopApi(sdk),
|
|
973
|
+
};
|
|
974
|
+
}
|
|
975
|
+
function adaptRunloopDevbox(devbox) {
|
|
976
|
+
const enableTunnel = bindRunloopMethod(devbox.net, 'enableTunnel');
|
|
977
|
+
const getTunnelUrl = bindRunloopMethod(devbox, 'getTunnelUrl');
|
|
978
|
+
const snapshotDisk = bindRunloopMethod(devbox, 'snapshotDisk');
|
|
979
|
+
return {
|
|
980
|
+
id: devbox.id,
|
|
981
|
+
cmd: {
|
|
982
|
+
exec: async (...args) => {
|
|
983
|
+
const [command, params, options] = args;
|
|
984
|
+
if (args.length > 2) {
|
|
985
|
+
return await devbox.cmd.exec(command, params, options);
|
|
986
|
+
}
|
|
987
|
+
return args.length > 1
|
|
988
|
+
? await devbox.cmd.exec(command, params)
|
|
989
|
+
: await devbox.cmd.exec(command);
|
|
990
|
+
},
|
|
991
|
+
},
|
|
992
|
+
file: {
|
|
993
|
+
read: async (params, options) => await devbox.file.read(params, options),
|
|
994
|
+
write: async (params, options) => await devbox.file.write({
|
|
995
|
+
file_path: params.path,
|
|
996
|
+
contents: params.contents,
|
|
997
|
+
}, options),
|
|
998
|
+
download: async (params, options) => await devbox.file.download(params, options),
|
|
999
|
+
upload: async (params, options) => {
|
|
1000
|
+
const uploadParams = params;
|
|
1001
|
+
return options
|
|
1002
|
+
? await devbox.file.upload(uploadParams, options)
|
|
1003
|
+
: await devbox.file.upload(uploadParams);
|
|
1004
|
+
},
|
|
1005
|
+
},
|
|
1006
|
+
...(enableTunnel
|
|
1007
|
+
? {
|
|
1008
|
+
net: {
|
|
1009
|
+
enableTunnel: async (params, options) => options
|
|
1010
|
+
? await enableTunnel(params, options)
|
|
1011
|
+
: await enableTunnel(params),
|
|
1012
|
+
},
|
|
1013
|
+
}
|
|
1014
|
+
: {}),
|
|
1015
|
+
...(getTunnelUrl
|
|
1016
|
+
? {
|
|
1017
|
+
getTunnelUrl: async (port, options) => (options
|
|
1018
|
+
? await getTunnelUrl(port, options)
|
|
1019
|
+
: await getTunnelUrl(port)),
|
|
1020
|
+
}
|
|
1021
|
+
: {}),
|
|
1022
|
+
...(snapshotDisk
|
|
1023
|
+
? {
|
|
1024
|
+
snapshotDisk: async (params, options) => (options
|
|
1025
|
+
? await snapshotDisk(params, options)
|
|
1026
|
+
: await snapshotDisk(params)),
|
|
1027
|
+
}
|
|
1028
|
+
: {}),
|
|
1029
|
+
resume: async (options) => await devbox.resume(options),
|
|
1030
|
+
suspend: async (options) => await devbox.suspend(options),
|
|
1031
|
+
shutdown: async (options) => await devbox.shutdown(options),
|
|
1032
|
+
};
|
|
1033
|
+
}
|
|
1034
|
+
function adaptRunloopPlatformResource(resource) {
|
|
1035
|
+
if (!(0, shared_1.isRecord)(resource)) {
|
|
1036
|
+
return undefined;
|
|
1037
|
+
}
|
|
1038
|
+
const fromId = resource.fromId;
|
|
1039
|
+
return {
|
|
1040
|
+
create: bindRunloopMethod(resource, 'create'),
|
|
1041
|
+
list: bindRunloopMethod(resource, 'list'),
|
|
1042
|
+
fromId: typeof fromId === 'function'
|
|
1043
|
+
? (id) => fromId.call(resource, id)
|
|
1044
|
+
: undefined,
|
|
1045
|
+
};
|
|
1046
|
+
}
|
|
1047
|
+
function adaptRunloopBenchmarkResource(sdk) {
|
|
1048
|
+
const apiBenchmarks = sdk.api
|
|
1049
|
+
?.benchmarks;
|
|
1050
|
+
const apiResource = adaptRunloopApiBenchmarkResource(apiBenchmarks);
|
|
1051
|
+
if (apiResource) {
|
|
1052
|
+
return apiResource;
|
|
1053
|
+
}
|
|
1054
|
+
return adaptRunloopPlatformResource(sdk.benchmark);
|
|
1055
|
+
}
|
|
1056
|
+
function adaptRunloopApiBenchmarkResource(resource) {
|
|
1057
|
+
if (!(0, shared_1.isRecord)(resource)) {
|
|
1058
|
+
return undefined;
|
|
1059
|
+
}
|
|
1060
|
+
const adapted = {
|
|
1061
|
+
create: bindRunloopMethod(resource, 'create'),
|
|
1062
|
+
list: bindRunloopMethod(resource, 'list'),
|
|
1063
|
+
retrieve: bindRunloopMethod(resource, 'retrieve'),
|
|
1064
|
+
update: bindRunloopMethod(resource, 'update'),
|
|
1065
|
+
startRun: bindRunloopMethod(resource, 'startRun'),
|
|
1066
|
+
};
|
|
1067
|
+
return Object.values(adapted).some((value) => typeof value === 'function')
|
|
1068
|
+
? adapted
|
|
1069
|
+
: undefined;
|
|
1070
|
+
}
|
|
1071
|
+
function adaptRunloopApi(sdk) {
|
|
1072
|
+
const apiClient = sdk.api;
|
|
1073
|
+
if (!(0, shared_1.isRecord)(apiClient)) {
|
|
1074
|
+
return {};
|
|
1075
|
+
}
|
|
1076
|
+
const api = {};
|
|
1077
|
+
const blueprintsResource = apiClient.blueprints;
|
|
1078
|
+
const benchmarksResource = apiClient.benchmarks;
|
|
1079
|
+
const secretsResource = apiClient.secrets;
|
|
1080
|
+
const blueprints = runloopApiResource({
|
|
1081
|
+
listPublic: bindRunloopMethod(blueprintsResource, 'listPublic'),
|
|
1082
|
+
logs: bindRunloopMethod(blueprintsResource, 'logs'),
|
|
1083
|
+
awaitBuildComplete: bindRunloopMethod(blueprintsResource, 'awaitBuildComplete'),
|
|
1084
|
+
});
|
|
1085
|
+
if (Object.keys(blueprints).length > 0) {
|
|
1086
|
+
api.blueprints = blueprints;
|
|
1087
|
+
}
|
|
1088
|
+
const benchmarks = runloopApiResource({
|
|
1089
|
+
listPublic: bindRunloopMethod(benchmarksResource, 'listPublic'),
|
|
1090
|
+
definitions: bindRunloopMethod(benchmarksResource, 'definitions'),
|
|
1091
|
+
updateScenarios: bindRunloopMethod(benchmarksResource, 'updateScenarios'),
|
|
1092
|
+
});
|
|
1093
|
+
if (Object.keys(benchmarks).length > 0) {
|
|
1094
|
+
api.benchmarks = benchmarks;
|
|
1095
|
+
}
|
|
1096
|
+
const secrets = runloopApiResource({
|
|
1097
|
+
retrieve: bindRunloopMethod(secretsResource, 'retrieve'),
|
|
1098
|
+
});
|
|
1099
|
+
if (Object.keys(secrets).length > 0) {
|
|
1100
|
+
api.secrets = secrets;
|
|
1101
|
+
}
|
|
1102
|
+
return api;
|
|
1103
|
+
}
|
|
1104
|
+
function runloopApiResource(methods) {
|
|
1105
|
+
return Object.fromEntries(Object.entries(methods).filter((entry) => typeof entry[1] === 'function'));
|
|
1106
|
+
}
|
|
1107
|
+
function bindRunloopMethod(target, methodName) {
|
|
1108
|
+
if (!(0, shared_1.isRecord)(target)) {
|
|
1109
|
+
return undefined;
|
|
1110
|
+
}
|
|
1111
|
+
const method = target[methodName];
|
|
1112
|
+
return typeof method === 'function'
|
|
1113
|
+
? method.bind(target)
|
|
1114
|
+
: undefined;
|
|
1115
|
+
}
|
|
1116
|
+
async function upsertRunloopManagedSecrets(sdk, managedSecrets, options) {
|
|
1117
|
+
if (!managedSecrets || Object.keys(managedSecrets).length === 0) {
|
|
1118
|
+
return {};
|
|
1119
|
+
}
|
|
1120
|
+
if (!sdk.secret?.create || !sdk.secret.update) {
|
|
1121
|
+
throw new sandbox_1.SandboxProviderError('RunloopSandboxClient managedSecrets require the Runloop SDK secret API.', {
|
|
1122
|
+
provider: 'runloop',
|
|
1123
|
+
});
|
|
1124
|
+
}
|
|
1125
|
+
const refs = {};
|
|
1126
|
+
for (const [name, value] of Object.entries(managedSecrets).sort(([left], [right]) => left.localeCompare(right))) {
|
|
1127
|
+
try {
|
|
1128
|
+
await sdk.secret.create({ name, value }, options);
|
|
1129
|
+
}
|
|
1130
|
+
catch (error) {
|
|
1131
|
+
if (!isRunloopConflictError(error)) {
|
|
1132
|
+
throw new sandbox_1.SandboxProviderError(`RunloopSandboxClient failed to create managed secret ${name}.`, {
|
|
1133
|
+
provider: 'runloop',
|
|
1134
|
+
secretName: name,
|
|
1135
|
+
cause: formatRunloopSecretErrorCause(error, value),
|
|
1136
|
+
});
|
|
1137
|
+
}
|
|
1138
|
+
try {
|
|
1139
|
+
await sdk.secret.update(name, { value }, options);
|
|
1140
|
+
}
|
|
1141
|
+
catch (updateError) {
|
|
1142
|
+
throw new sandbox_1.SandboxProviderError(`RunloopSandboxClient failed to update managed secret ${name}.`, {
|
|
1143
|
+
provider: 'runloop',
|
|
1144
|
+
secretName: name,
|
|
1145
|
+
cause: formatRunloopSecretErrorCause(updateError, value),
|
|
1146
|
+
});
|
|
1147
|
+
}
|
|
1148
|
+
}
|
|
1149
|
+
refs[name] = name;
|
|
1150
|
+
}
|
|
1151
|
+
return refs;
|
|
1152
|
+
}
|
|
1153
|
+
function isRunloopConflictError(error) {
|
|
1154
|
+
if (!(0, shared_1.isRecord)(error)) {
|
|
1155
|
+
return false;
|
|
1156
|
+
}
|
|
1157
|
+
const status = error.status ?? error.statusCode;
|
|
1158
|
+
if (status === 409 || status === '409') {
|
|
1159
|
+
return true;
|
|
1160
|
+
}
|
|
1161
|
+
const code = error.code;
|
|
1162
|
+
if (code === 409 || code === '409') {
|
|
1163
|
+
return true;
|
|
1164
|
+
}
|
|
1165
|
+
const text = `${String(error.name ?? '')} ${String(error.message ?? '')}`;
|
|
1166
|
+
return /\b(conflict|already exists)\b/iu.test(text);
|
|
1167
|
+
}
|
|
1168
|
+
function formatRunloopSecretErrorCause(error, secretValue) {
|
|
1169
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1170
|
+
return secretValue ? message.split(secretValue).join('[redacted]') : message;
|
|
1171
|
+
}
|
|
1172
|
+
function errorMessage(error) {
|
|
1173
|
+
return error instanceof Error ? error.message : String(error);
|
|
1174
|
+
}
|
|
1175
|
+
async function callRunloopPlatformMethod(methodName, method, ...args) {
|
|
1176
|
+
if (!method) {
|
|
1177
|
+
throw new sandbox_1.SandboxUnsupportedFeatureError(`Runloop platform method ${methodName} is not available in the installed Runloop SDK.`, {
|
|
1178
|
+
provider: 'runloop',
|
|
1179
|
+
feature: `platform.${methodName}`,
|
|
1180
|
+
});
|
|
1181
|
+
}
|
|
1182
|
+
return await (0, shared_1.withProviderError)('RunloopSandboxClient', 'runloop', `call platform method ${methodName}`, async () => await method(...args));
|
|
1183
|
+
}
|
|
1184
|
+
function callRunloopPlatformGetter(methodName, method, id) {
|
|
1185
|
+
if (!method) {
|
|
1186
|
+
throw new sandbox_1.SandboxUnsupportedFeatureError(`Runloop platform method ${methodName} is not available in the installed Runloop SDK.`, {
|
|
1187
|
+
provider: 'runloop',
|
|
1188
|
+
feature: `platform.${methodName}`,
|
|
1189
|
+
});
|
|
1190
|
+
}
|
|
1191
|
+
try {
|
|
1192
|
+
return method(id);
|
|
1193
|
+
}
|
|
1194
|
+
catch (error) {
|
|
1195
|
+
if (error instanceof agents_core_1.UserError) {
|
|
1196
|
+
throw error;
|
|
1197
|
+
}
|
|
1198
|
+
throw new sandbox_1.SandboxProviderError(`RunloopSandboxClient failed to call platform method ${methodName}.`, {
|
|
1199
|
+
provider: 'runloop',
|
|
1200
|
+
operation: `call platform method ${methodName}`,
|
|
1201
|
+
cause: error instanceof Error ? error.message : String(error),
|
|
1202
|
+
});
|
|
1203
|
+
}
|
|
1204
|
+
}
|
|
1205
|
+
function createRunloopParams(state, environment, options = {}) {
|
|
1206
|
+
const createParams = {
|
|
1207
|
+
environment_variables: environment,
|
|
1208
|
+
};
|
|
1209
|
+
const includeBlueprint = options.includeBlueprint ?? true;
|
|
1210
|
+
const includeSecrets = options.includeSecrets ?? true;
|
|
1211
|
+
const values = {
|
|
1212
|
+
blueprintId: includeBlueprint ? state.blueprintId : undefined,
|
|
1213
|
+
name: state.name,
|
|
1214
|
+
exposedPorts: state.configuredExposedPorts,
|
|
1215
|
+
tunnel: state.tunnel,
|
|
1216
|
+
gateways: state.gateways,
|
|
1217
|
+
mcp: state.mcp,
|
|
1218
|
+
metadata: state.metadata,
|
|
1219
|
+
secrets: includeSecrets ? state.secretRefs : undefined,
|
|
1220
|
+
};
|
|
1221
|
+
for (const [key, value] of Object.entries(values)) {
|
|
1222
|
+
if (value !== undefined) {
|
|
1223
|
+
createParams[toSnakeCase(key)] = value;
|
|
1224
|
+
}
|
|
1225
|
+
}
|
|
1226
|
+
if (state.userParameters || state.launchParameters) {
|
|
1227
|
+
createParams.launch_parameters = {
|
|
1228
|
+
...(state.launchParameters ?? {}),
|
|
1229
|
+
user_parameters: state.userParameters,
|
|
1230
|
+
};
|
|
1231
|
+
}
|
|
1232
|
+
return createParams;
|
|
1233
|
+
}
|
|
1234
|
+
function resolveRunloopManifestRoot(manifest, userParameters, preserveDefaultRoot) {
|
|
1235
|
+
const effectiveHome = effectiveRunloopHome(userParameters);
|
|
1236
|
+
const resolvedManifest = !preserveDefaultRoot && manifest.root === '/workspace'
|
|
1237
|
+
? (0, shared_1.cloneManifestWithRoot)(manifest, effectiveHome)
|
|
1238
|
+
: manifest;
|
|
1239
|
+
validateRunloopManifestRoot(resolvedManifest, effectiveHome);
|
|
1240
|
+
return resolvedManifest;
|
|
1241
|
+
}
|
|
1242
|
+
function effectiveRunloopHome(userParameters) {
|
|
1243
|
+
if (!userParameters) {
|
|
1244
|
+
return exports.DEFAULT_RUNLOOP_WORKSPACE_ROOT;
|
|
1245
|
+
}
|
|
1246
|
+
validateRunloopUsername(userParameters.username);
|
|
1247
|
+
if (userParameters.username === 'root' && userParameters.uid === 0) {
|
|
1248
|
+
return exports.DEFAULT_RUNLOOP_ROOT_WORKSPACE_ROOT;
|
|
1249
|
+
}
|
|
1250
|
+
return `/home/${userParameters.username}`;
|
|
1251
|
+
}
|
|
1252
|
+
function validateRunloopUsername(username) {
|
|
1253
|
+
if (username.length > 0 &&
|
|
1254
|
+
username !== '.' &&
|
|
1255
|
+
!username.includes('/') &&
|
|
1256
|
+
!username.includes('..') &&
|
|
1257
|
+
!username.includes('\0')) {
|
|
1258
|
+
return;
|
|
1259
|
+
}
|
|
1260
|
+
throw new sandbox_1.SandboxConfigurationError('RunloopSandboxClient userParameters.username must be non-empty and must not contain "/", "..", or NUL bytes.', {
|
|
1261
|
+
provider: 'runloop',
|
|
1262
|
+
username,
|
|
1263
|
+
});
|
|
1264
|
+
}
|
|
1265
|
+
function validateRunloopManifestRoot(manifest, home) {
|
|
1266
|
+
const root = node_path_1.posix.normalize(manifest.root);
|
|
1267
|
+
if (root === home || root.startsWith(`${home}/`)) {
|
|
1268
|
+
return;
|
|
1269
|
+
}
|
|
1270
|
+
throw new sandbox_1.SandboxConfigurationError(`RunloopSandboxClient requires manifest.root to be the effective Runloop home (${home}) or a subdirectory of it.`, {
|
|
1271
|
+
provider: 'runloop',
|
|
1272
|
+
root: manifest.root,
|
|
1273
|
+
effectiveHome: home,
|
|
1274
|
+
});
|
|
1275
|
+
}
|
|
1276
|
+
function assertRunloopManifestRootRealPath(root, home, stdout) {
|
|
1277
|
+
const values = new Map(stdout
|
|
1278
|
+
.trim()
|
|
1279
|
+
.split(/\r?\n/u)
|
|
1280
|
+
.map((line) => line.match(/^(OPENAI_AGENTS_REALPATH_(?:ANCESTOR|HOME|ROOT))=(.*)$/u))
|
|
1281
|
+
.filter((match) => match !== null)
|
|
1282
|
+
.map((match) => [match[1], node_path_1.posix.normalize(match[2] ?? '')]));
|
|
1283
|
+
const realHome = values.get('OPENAI_AGENTS_REALPATH_HOME');
|
|
1284
|
+
const realAncestor = values.get('OPENAI_AGENTS_REALPATH_ANCESTOR');
|
|
1285
|
+
const realRoot = values.get('OPENAI_AGENTS_REALPATH_ROOT');
|
|
1286
|
+
const normalizedHome = node_path_1.posix.normalize(home);
|
|
1287
|
+
const realHomeIsConfined = realHome &&
|
|
1288
|
+
realHome !== '/' &&
|
|
1289
|
+
(realHome === normalizedHome || realHome.startsWith(`${normalizedHome}/`));
|
|
1290
|
+
const realAncestorIsConfined = realHome &&
|
|
1291
|
+
realAncestor &&
|
|
1292
|
+
(realAncestor === realHome || realAncestor.startsWith(`${realHome}/`));
|
|
1293
|
+
const realRootIsConfined = realHome &&
|
|
1294
|
+
realRoot &&
|
|
1295
|
+
(realRoot === realHome || realRoot.startsWith(`${realHome}/`));
|
|
1296
|
+
if (realHomeIsConfined && realAncestorIsConfined && realRootIsConfined) {
|
|
1297
|
+
return;
|
|
1298
|
+
}
|
|
1299
|
+
throw new sandbox_1.SandboxConfigurationError(`RunloopSandboxClient requires manifest.root to resolve to the effective Runloop home (${home}) or a subdirectory of it.`, {
|
|
1300
|
+
provider: 'runloop',
|
|
1301
|
+
root,
|
|
1302
|
+
effectiveHome: home,
|
|
1303
|
+
resolvedRoot: realRoot,
|
|
1304
|
+
resolvedHome: realHome,
|
|
1305
|
+
resolvedAncestor: realAncestor,
|
|
1306
|
+
});
|
|
1307
|
+
}
|
|
1308
|
+
function createRunloopOptions(state) {
|
|
1309
|
+
return runloopLongPollOptions(state.timeouts?.createTimeoutMs ?? state.createTimeoutMs);
|
|
1310
|
+
}
|
|
1311
|
+
function resolveRunloopTimeouts(options) {
|
|
1312
|
+
return {
|
|
1313
|
+
...options.timeouts,
|
|
1314
|
+
createTimeoutMs: options.timeouts?.createTimeoutMs ?? options.createTimeoutMs,
|
|
1315
|
+
fastOperationTimeoutMs: options.timeouts?.fastOperationTimeoutMs ?? options.createTimeoutMs,
|
|
1316
|
+
};
|
|
1317
|
+
}
|
|
1318
|
+
function runloopRequestOptions(timeoutMs) {
|
|
1319
|
+
return typeof timeoutMs === 'number' ? { timeout: timeoutMs } : undefined;
|
|
1320
|
+
}
|
|
1321
|
+
function runloopLongPollOptions(timeoutMs) {
|
|
1322
|
+
return typeof timeoutMs === 'number'
|
|
1323
|
+
? { timeout: timeoutMs, longPoll: { timeoutMs } }
|
|
1324
|
+
: undefined;
|
|
1325
|
+
}
|
|
1326
|
+
function runloopTunnelEnableParams(tunnel) {
|
|
1327
|
+
if (tunnel === false) {
|
|
1328
|
+
return undefined;
|
|
1329
|
+
}
|
|
1330
|
+
if ((0, shared_1.isRecord)(tunnel)) {
|
|
1331
|
+
return {
|
|
1332
|
+
...DEFAULT_RUNLOOP_TUNNEL_PARAMS,
|
|
1333
|
+
...tunnel,
|
|
1334
|
+
};
|
|
1335
|
+
}
|
|
1336
|
+
return { ...DEFAULT_RUNLOOP_TUNNEL_PARAMS };
|
|
1337
|
+
}
|
|
1338
|
+
function runloopExitStatus(result) {
|
|
1339
|
+
return result.exitCode ?? UNKNOWN_RUNLOOP_EXIT_CODE;
|
|
1340
|
+
}
|
|
1341
|
+
function runloopSucceeded(result) {
|
|
1342
|
+
return result.exitCode === 0;
|
|
1343
|
+
}
|
|
1344
|
+
function invalidateRunloopRuntimeCaches(state) {
|
|
1345
|
+
delete state.exposedPorts;
|
|
1346
|
+
}
|
|
1347
|
+
function remoteCommandEnvironment(environment, options) {
|
|
1348
|
+
return options.kind === 'exec' ? environment : {};
|
|
1349
|
+
}
|
|
1350
|
+
function assertRunloopResumeRecreateSecretRefsTrusted(state, options) {
|
|
1351
|
+
if (!state.secretRefs || Object.keys(state.secretRefs).length === 0) {
|
|
1352
|
+
return;
|
|
1353
|
+
}
|
|
1354
|
+
if (options.managedSecrets &&
|
|
1355
|
+
Object.keys(options.managedSecrets).length > 0) {
|
|
1356
|
+
return;
|
|
1357
|
+
}
|
|
1358
|
+
throw new agents_core_1.UserError('RunloopSandboxClient cannot recreate a missing devbox with persisted secretRefs. Configure managedSecrets on the client to recreate secrets from trusted input.');
|
|
1359
|
+
}
|
|
1360
|
+
async function rematerializeRunloopManifestMounts(session, manifest) {
|
|
1361
|
+
await session.rematerializeManifestMounts(manifest);
|
|
1362
|
+
}
|
|
1363
|
+
function mountCommandEnvironment(environment, user, userParameters) {
|
|
1364
|
+
const effectiveUser = user ?? effectiveRunloopUsername(userParameters);
|
|
1365
|
+
return effectiveUser === 'root' ? {} : environment;
|
|
1366
|
+
}
|
|
1367
|
+
function buildShellCommand(command, environment, cwd, user, userParameters) {
|
|
1368
|
+
const exports = Object.entries(environment).map(([key, value]) => {
|
|
1369
|
+
(0, shared_1.assertShellEnvironmentName)(key);
|
|
1370
|
+
return `export ${key}=${(0, shared_1.shellQuote)(value)}`;
|
|
1371
|
+
});
|
|
1372
|
+
const shellCommand = [`cd ${(0, shared_1.shellQuote)(cwd)}`, ...exports, command].join(' && ');
|
|
1373
|
+
return runloopShellCommandForUser(shellCommand, user, userParameters);
|
|
1374
|
+
}
|
|
1375
|
+
function runloopShellCommandForUser(command, user, userParameters) {
|
|
1376
|
+
if (!user || user === effectiveRunloopUsername(userParameters)) {
|
|
1377
|
+
return command;
|
|
1378
|
+
}
|
|
1379
|
+
return `sudo -n -u ${(0, shared_1.shellQuote)(user)} -- sh -lc ${(0, shared_1.shellQuote)(command)}`;
|
|
1380
|
+
}
|
|
1381
|
+
function effectiveRunloopUsername(userParameters) {
|
|
1382
|
+
return userParameters?.username ?? 'user';
|
|
1383
|
+
}
|
|
1384
|
+
function toSnakeCase(value) {
|
|
1385
|
+
return value.replace(/[A-Z]/gu, (match) => `_${match.toLowerCase()}`);
|
|
1386
|
+
}
|
|
1387
|
+
function basename(path) {
|
|
1388
|
+
return path.split('/').pop() || 'file';
|
|
1389
|
+
}
|
|
1390
|
+
//# sourceMappingURL=sandbox.js.map
|