@truefoundry/trueforge-core 0.1.2 → 0.1.4-rc.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/agent-session/TurnResourceResolver.d.ts.map +1 -1
- package/dist/agent-session/TurnResourceResolver.js +1 -4
- package/dist/agent-session/TurnResourceResolver.js.map +1 -1
- package/dist/agent-session/TurnResourceResolver.mjs +1 -4
- package/dist/agent-session/TurnResourceResolver.mjs.map +1 -1
- package/dist/agent-session/index.d.ts +1 -1
- package/dist/agent-session/index.d.ts.map +1 -1
- package/dist/agent-session/index.js.map +1 -1
- package/dist/agent-session/index.mjs.map +1 -1
- package/dist/agent-session/schemas/agentSpec.d.ts +7 -28
- package/dist/agent-session/schemas/agentSpec.d.ts.map +1 -1
- package/dist/agent-session/schemas/agentSpec.js +15 -43
- package/dist/agent-session/schemas/agentSpec.js.map +1 -1
- package/dist/agent-session/schemas/agentSpec.mjs +15 -43
- package/dist/agent-session/schemas/agentSpec.mjs.map +1 -1
- package/dist/agent-session/schemas/session.d.ts +0 -39
- package/dist/agent-session/schemas/session.d.ts.map +1 -1
- package/dist/core/index.d.ts +4 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +12 -0
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.mjs +7 -0
- package/dist/core/index.mjs.map +1 -1
- package/dist/core/runtime/AgentThread.d.ts.map +1 -1
- package/dist/core/runtime/AgentThread.js +25 -11
- package/dist/core/runtime/AgentThread.js.map +1 -1
- package/dist/core/runtime/AgentThread.mjs +25 -11
- package/dist/core/runtime/AgentThread.mjs.map +1 -1
- package/dist/core/sandbox/Sandbox.d.ts +15 -5
- package/dist/core/sandbox/Sandbox.d.ts.map +1 -1
- package/dist/core/sandbox/Sandbox.js +200 -84
- package/dist/core/sandbox/Sandbox.js.map +1 -1
- package/dist/core/sandbox/Sandbox.mjs +201 -85
- package/dist/core/sandbox/Sandbox.mjs.map +1 -1
- package/dist/core/sandbox/SandboxErrors.d.ts +7 -3
- package/dist/core/sandbox/SandboxErrors.d.ts.map +1 -1
- package/dist/core/sandbox/SandboxErrors.js +6 -6
- package/dist/core/sandbox/SandboxErrors.js.map +1 -1
- package/dist/core/sandbox/SandboxErrors.mjs +6 -6
- package/dist/core/sandbox/SandboxErrors.mjs.map +1 -1
- package/dist/core/sandbox/codeMode/CodeModeTransport.d.ts +22 -0
- package/dist/core/sandbox/codeMode/CodeModeTransport.d.ts.map +1 -1
- package/dist/core/sandbox/codeMode/CodeModeTransport.js.map +1 -1
- package/dist/core/sandbox/codeMode/nats/CodeModeNatsTransport.d.ts +9 -1
- package/dist/core/sandbox/codeMode/nats/CodeModeNatsTransport.d.ts.map +1 -1
- package/dist/core/sandbox/codeMode/nats/CodeModeNatsTransport.js +12 -0
- package/dist/core/sandbox/codeMode/nats/CodeModeNatsTransport.js.map +1 -1
- package/dist/core/sandbox/codeMode/nats/CodeModeNatsTransport.mjs +12 -0
- package/dist/core/sandbox/codeMode/nats/CodeModeNatsTransport.mjs.map +1 -1
- package/dist/core/sandbox/constants.d.ts +0 -2
- package/dist/core/sandbox/constants.d.ts.map +1 -1
- package/dist/core/sandbox/constants.js +2 -5
- package/dist/core/sandbox/constants.js.map +1 -1
- package/dist/core/sandbox/constants.mjs +1 -3
- package/dist/core/sandbox/constants.mjs.map +1 -1
- package/dist/core/sandbox/provider/DaytonaProvider.d.ts +4 -0
- package/dist/core/sandbox/provider/DaytonaProvider.d.ts.map +1 -1
- package/dist/core/sandbox/provider/DaytonaProvider.js +27 -5
- package/dist/core/sandbox/provider/DaytonaProvider.js.map +1 -1
- package/dist/core/sandbox/provider/DaytonaProvider.mjs +27 -4
- package/dist/core/sandbox/provider/DaytonaProvider.mjs.map +1 -1
- package/dist/core/sandbox/provider/Provider.d.ts +13 -1
- package/dist/core/sandbox/provider/Provider.d.ts.map +1 -1
- package/dist/core/sandbox/provider/Provider.js.map +1 -1
- package/dist/core/sandbox/provider/Provider.mjs.map +1 -1
- package/dist/core/sandbox/provider/TFYSandboxProvider.d.ts +17 -2
- package/dist/core/sandbox/provider/TFYSandboxProvider.d.ts.map +1 -1
- package/dist/core/sandbox/provider/TFYSandboxProvider.js +81 -17
- package/dist/core/sandbox/provider/TFYSandboxProvider.js.map +1 -1
- package/dist/core/sandbox/provider/TFYSandboxProvider.mjs +82 -13
- package/dist/core/sandbox/provider/TFYSandboxProvider.mjs.map +1 -1
- package/dist/core/sandbox/provider/execEnv.d.ts +6 -0
- package/dist/core/sandbox/provider/execEnv.d.ts.map +1 -0
- package/dist/core/sandbox/provider/execEnv.js +55 -0
- package/dist/core/sandbox/provider/execEnv.js.map +1 -0
- package/dist/core/sandbox/provider/execEnv.mjs +30 -0
- package/dist/core/sandbox/provider/execEnv.mjs.map +1 -0
- package/dist/core/sandbox/sandboxImage.d.ts +2 -5
- package/dist/core/sandbox/sandboxImage.d.ts.map +1 -1
- package/dist/core/sandbox/sandboxImage.js +8 -1
- package/dist/core/sandbox/sandboxImage.js.map +1 -1
- package/dist/core/sandbox/sandboxImage.mjs +6 -1
- package/dist/core/sandbox/sandboxImage.mjs.map +1 -1
- package/dist/core/sandbox/sandboxRef.d.ts +26 -0
- package/dist/core/sandbox/sandboxRef.d.ts.map +1 -0
- package/dist/core/sandbox/sandboxRef.js +69 -0
- package/dist/core/sandbox/sandboxRef.js.map +1 -0
- package/dist/core/sandbox/sandboxRef.mjs +41 -0
- package/dist/core/sandbox/sandboxRef.mjs.map +1 -0
- package/dist/core/sandbox/sandboxScripts.gen.d.ts +1 -1
- package/dist/core/sandbox/sandboxScripts.gen.d.ts.map +1 -1
- package/dist/core/sandbox/sandboxScripts.gen.js +1 -1
- package/dist/core/sandbox/sandboxScripts.gen.js.map +1 -1
- package/dist/core/sandbox/sandboxScripts.gen.mjs +1 -1
- package/dist/core/sandbox/sandboxScripts.gen.mjs.map +1 -1
- package/dist/core/sandbox/skills/ISkillMounter.d.ts +7 -2
- package/dist/core/sandbox/skills/ISkillMounter.d.ts.map +1 -1
- package/dist/core/sandbox/skills/ISkillMounter.js.map +1 -1
- package/dist/core/sandbox/skills/SkillMounter.d.ts +7 -2
- package/dist/core/sandbox/skills/SkillMounter.d.ts.map +1 -1
- package/dist/core/sandbox/skills/SkillMounter.js +5 -6
- package/dist/core/sandbox/skills/SkillMounter.js.map +1 -1
- package/dist/core/sandbox/skills/SkillMounter.mjs +5 -6
- package/dist/core/sandbox/skills/SkillMounter.mjs.map +1 -1
- package/dist/core/sandbox/skills/constants.d.ts +4 -2
- package/dist/core/sandbox/skills/constants.d.ts.map +1 -1
- package/dist/core/sandbox/skills/constants.js +2 -5
- package/dist/core/sandbox/skills/constants.js.map +1 -1
- package/dist/core/sandbox/skills/constants.mjs +2 -4
- package/dist/core/sandbox/skills/constants.mjs.map +1 -1
- package/dist/core/sandbox/skills/index.d.ts +1 -1
- package/dist/core/sandbox/skills/index.d.ts.map +1 -1
- package/dist/core/sandbox/skills/index.js +0 -2
- package/dist/core/sandbox/skills/index.js.map +1 -1
- package/dist/core/sandbox/skills/index.mjs +1 -2
- package/dist/core/sandbox/skills/index.mjs.map +1 -1
- package/package.json +1 -1
|
@@ -49,29 +49,36 @@ var import_LocalToolMCP = require("../mcp/LocalToolMCP.js");
|
|
|
49
49
|
var import_DeferredTool = require("../runtime/DeferredTool.js");
|
|
50
50
|
var import_errorLogFields = require("../util/errorLogFields.js");
|
|
51
51
|
var import_CodeModeDispatcher = require("./codeMode/CodeModeDispatcher.js");
|
|
52
|
-
var
|
|
52
|
+
var import_CodeModeTransport = require("./codeMode/CodeModeTransport.js");
|
|
53
53
|
var import_Provider = require("./provider/Provider.js");
|
|
54
54
|
var import_SandboxErrors = require("./SandboxErrors.js");
|
|
55
|
-
var
|
|
56
|
-
var
|
|
55
|
+
var import_sandboxRef = require("./sandboxRef.js");
|
|
56
|
+
var import_node_path = require("path");
|
|
57
|
+
function mcpClientLayout(remotePath) {
|
|
58
|
+
const pythonPath = (0, import_node_path.dirname)(remotePath);
|
|
59
|
+
const binDir = (0, import_node_path.join)(pythonPath, "bin");
|
|
60
|
+
return { pythonPath, binDir, binLink: (0, import_node_path.join)(binDir, "mcp-client") };
|
|
61
|
+
}
|
|
57
62
|
var SKILL_DOWNLOAD_TIMEOUT_SECONDS = 180;
|
|
58
63
|
var NATS_REQUEST_TIMEOUT_BUFFER_SECONDS = 30;
|
|
59
64
|
function buildWriteAndRunScriptCommand(params) {
|
|
60
65
|
const b64 = Buffer.from(params.scriptContent, "utf-8").toString("base64");
|
|
66
|
+
const scriptPath = (0, import_Provider.shellEscape)(params.scriptPath);
|
|
61
67
|
return [
|
|
62
|
-
`mkdir -p "$(dirname ${
|
|
63
|
-
`rm -f ${
|
|
64
|
-
`echo ${(0, import_Provider.shellEscape)(b64)} | base64 -d > ${
|
|
65
|
-
`chmod a-w ${
|
|
66
|
-
`python3 ${
|
|
68
|
+
`mkdir -p "$(dirname ${scriptPath})"`,
|
|
69
|
+
`rm -f ${scriptPath}`,
|
|
70
|
+
`echo ${(0, import_Provider.shellEscape)(b64)} | base64 -d > ${scriptPath}`,
|
|
71
|
+
`chmod a-w ${scriptPath}`,
|
|
72
|
+
`python3 ${scriptPath}`
|
|
67
73
|
].join(" && ");
|
|
68
74
|
}
|
|
69
75
|
function buildSyncGitCredentialsCommand(credentialsContent, credentialsPath) {
|
|
76
|
+
const path = (0, import_Provider.shellEscape)(credentialsPath);
|
|
70
77
|
if (credentialsContent === null) {
|
|
71
|
-
return `rm -f ${
|
|
78
|
+
return `rm -f ${path}`;
|
|
72
79
|
}
|
|
73
80
|
const b64 = Buffer.from(credentialsContent, "utf-8").toString("base64");
|
|
74
|
-
return `mkdir -p "$(dirname ${
|
|
81
|
+
return `mkdir -p "$(dirname ${path})" && echo '${b64}' | base64 -d > ${path} && chmod 600 ${path}`;
|
|
75
82
|
}
|
|
76
83
|
function buildGitCredentialHelperEnv(credentialsPath) {
|
|
77
84
|
return {
|
|
@@ -85,9 +92,6 @@ var SANDBOX_MCP_REMINDER_TAG = "sandbox-mcp-code-mode";
|
|
|
85
92
|
var SANDBOX_FILE_OUTPUT_TAG = "sandbox-file-output";
|
|
86
93
|
var SANDBOX_SCHEMA_INFER_TAG = "sandbox-schema-infer";
|
|
87
94
|
var SANDBOX_FILE_UPLOADS_TAG = "sandbox-file-uploads";
|
|
88
|
-
var MCP_CLIENT_DIR = "/opt/tfy/mcp-client";
|
|
89
|
-
var MCP_CLIENT_PATH = `${MCP_CLIENT_DIR}/mcp_client.py`;
|
|
90
|
-
var MCP_CLIENT_BIN_SYMLINK = "/usr/local/bin/mcp-client";
|
|
91
95
|
function injectTraceContextEnv() {
|
|
92
96
|
const carrier = {};
|
|
93
97
|
import_api.propagation.inject(import_api.context.active(), carrier);
|
|
@@ -103,10 +107,13 @@ function injectTraceContextEnv() {
|
|
|
103
107
|
function injectMCPClientEnv(params) {
|
|
104
108
|
const codeModeEnv = params.codeModeEnv ?? {};
|
|
105
109
|
const hasCodeModeTransport = Object.keys(codeModeEnv).length > 0;
|
|
110
|
+
const install = params.mcpClientInstall;
|
|
111
|
+
const layout = install === void 0 ? void 0 : mcpClientLayout(install.remotePath);
|
|
106
112
|
return {
|
|
107
|
-
...params.execExtraEnv ?? {},
|
|
108
113
|
...params.env ?? {},
|
|
109
|
-
|
|
114
|
+
...layout !== void 0 && {
|
|
115
|
+
PYTHONPATH: layout.pythonPath
|
|
116
|
+
},
|
|
110
117
|
...Object.keys(params.mcpServers).length > 0 && {
|
|
111
118
|
TFY_MCP_SERVERS: Buffer.from(JSON.stringify(params.mcpServers)).toString("base64")
|
|
112
119
|
},
|
|
@@ -138,14 +145,12 @@ function createSandboxLargeToolResponseGuidance() {
|
|
|
138
145
|
return `For use cases where the Agent needs a subset of fields from the MCP response or needs deterministic processing, write code with the provided MCP client and use <${SANDBOX_MCP_REMINDER_TAG}>.`;
|
|
139
146
|
}
|
|
140
147
|
var SANDBOX_MCP_SERVER_ID = "sandbox";
|
|
141
|
-
var Sandbox = class
|
|
148
|
+
var Sandbox = class extends import_LocalToolMCP.LocalToolMCP {
|
|
142
149
|
name = SANDBOX_MCP_SERVER_ID;
|
|
143
150
|
displayName = "Sandbox";
|
|
144
151
|
description = "Persistent sandbox environment for code execution";
|
|
145
|
-
static FILE_UPLOADS_DIR = import_constants.SANDBOX_FILE_UPLOADS_DIR;
|
|
146
152
|
provider;
|
|
147
153
|
existingSandboxId;
|
|
148
|
-
tenantName;
|
|
149
154
|
existingSandboxInfo;
|
|
150
155
|
// Cached promise to prevent concurrent sub-agents from creating duplicate sandboxes.
|
|
151
156
|
sandboxCreationPromise;
|
|
@@ -153,15 +158,15 @@ var Sandbox = class _Sandbox extends import_LocalToolMCP.LocalToolMCP {
|
|
|
153
158
|
codeExecToolSets = [];
|
|
154
159
|
fileDownloadEnabled;
|
|
155
160
|
requestTimeoutSeconds;
|
|
156
|
-
execExtraEnv;
|
|
157
161
|
skillMounter;
|
|
158
162
|
cachedSkillsSection;
|
|
159
|
-
mcpClientScriptBase64;
|
|
160
163
|
logger;
|
|
161
164
|
// Pre-resolved credential-store file content (null = clear / no git auth).
|
|
162
165
|
resolvedGitCredentialsContent;
|
|
163
166
|
codeModeDispatcher;
|
|
164
167
|
codeModeTransport;
|
|
168
|
+
/** Cached from transport.getClientInstall after sandbox init (when Code Mode is configured). */
|
|
169
|
+
mcpClientInstall;
|
|
165
170
|
tools = [
|
|
166
171
|
(0, import_LocalToolMCP.defineTool)({
|
|
167
172
|
name: SANDBOX_EXEC_TOOL_NAME,
|
|
@@ -174,20 +179,24 @@ var Sandbox = class _Sandbox extends import_LocalToolMCP.LocalToolMCP {
|
|
|
174
179
|
super({ tracing: options.tracing });
|
|
175
180
|
this.provider = options.provider;
|
|
176
181
|
this.existingSandboxId = options.existingSandboxId;
|
|
177
|
-
this.tenantName = options.execExtraEnv?.["TFY_TENANT_NAME"] ?? "";
|
|
178
182
|
this.skillMounter = options.skillMounter;
|
|
179
183
|
this.fileDownloadEnabled = options.fileDownloadEnabled ?? false;
|
|
180
184
|
const mcpBoundTimeoutMs = options.mcpRequestTimeoutMs + options.mcpConnectTimeoutMs;
|
|
181
185
|
this.requestTimeoutSeconds = Math.ceil(mcpBoundTimeoutMs / 1e3) + NATS_REQUEST_TIMEOUT_BUFFER_SECONDS;
|
|
182
|
-
this.execExtraEnv = options.execExtraEnv;
|
|
183
|
-
this.mcpClientScriptBase64 = Buffer.from(import_sandboxScripts.sandboxScripts.mcpClient, "utf-8").toString("base64");
|
|
184
186
|
this.logger = options.logger.child({ module: "Sandbox" });
|
|
185
187
|
this.resolvedGitCredentialsContent = options.resolvedGitCredentialsContent ?? null;
|
|
186
188
|
if (this.existingSandboxId) {
|
|
187
|
-
(0, import_SandboxErrors.validateSandboxOwnedByTenant)(this.existingSandboxId, this.tenantName);
|
|
188
189
|
this.existingSandboxInfo = { sandbox_id: this.existingSandboxId };
|
|
189
190
|
}
|
|
190
191
|
}
|
|
192
|
+
/** Provider-facing id (unwraps `v1:type:raw`; legacy ids pass through). */
|
|
193
|
+
providerSandboxId(sessionId) {
|
|
194
|
+
return (0, import_sandboxRef.rawSandboxId)(sessionId);
|
|
195
|
+
}
|
|
196
|
+
/** Raw id for prompt layout paths before create (empty when this turn has no existing sandbox). */
|
|
197
|
+
promptSandboxId() {
|
|
198
|
+
return this.existingSandboxId === void 0 ? "" : (0, import_sandboxRef.rawSandboxId)(this.existingSandboxId);
|
|
199
|
+
}
|
|
191
200
|
buildMcpServersEnvelope() {
|
|
192
201
|
const out = {};
|
|
193
202
|
for (const server of this.codeExecToolSets) {
|
|
@@ -217,7 +226,7 @@ var Sandbox = class _Sandbox extends import_LocalToolMCP.LocalToolMCP {
|
|
|
217
226
|
renderSkillsSection() {
|
|
218
227
|
if (this.cachedSkillsSection === void 0) {
|
|
219
228
|
const skills = new import_InstructionBuilder.InstructionBuilder("skills");
|
|
220
|
-
this.skillMounter?.instruction(skills);
|
|
229
|
+
this.skillMounter?.instruction(skills, { skillsDir: this.provider.getSkillsDir(this.promptSandboxId()) });
|
|
221
230
|
this.cachedSkillsSection = skills.build();
|
|
222
231
|
}
|
|
223
232
|
return this.cachedSkillsSection;
|
|
@@ -241,7 +250,7 @@ var Sandbox = class _Sandbox extends import_LocalToolMCP.LocalToolMCP {
|
|
|
241
250
|
buildFileUploadsSection(builder) {
|
|
242
251
|
builder.addSection(
|
|
243
252
|
SANDBOX_FILE_UPLOADS_TAG,
|
|
244
|
-
`User-uploaded files are placed in ${
|
|
253
|
+
`User-uploaded files are placed in ${this.provider.getFileUploadsDir(this.promptSandboxId())}/. The Agent must not modify files in this directory. Always create a copy at a different location and work on the copy.`
|
|
245
254
|
);
|
|
246
255
|
}
|
|
247
256
|
buildSchemaSection(builder) {
|
|
@@ -363,87 +372,168 @@ var Sandbox = class _Sandbox extends import_LocalToolMCP.LocalToolMCP {
|
|
|
363
372
|
}
|
|
364
373
|
return this.existingSandboxInfo;
|
|
365
374
|
}
|
|
375
|
+
clearExistingSandbox() {
|
|
376
|
+
this.existingSandboxInfo = void 0;
|
|
377
|
+
this.sandboxCreationPromise = void 0;
|
|
378
|
+
this.sandboxInitPromise = void 0;
|
|
379
|
+
this.mcpClientInstall = void 0;
|
|
380
|
+
}
|
|
366
381
|
async ensureSandboxCreated() {
|
|
367
382
|
if (this.existingSandboxInfo) {
|
|
368
383
|
return { sandboxInfo: this.existingSandboxInfo, sandboxCreated: void 0 };
|
|
369
384
|
}
|
|
370
|
-
this.sandboxCreationPromise ??= this.provider.createSandbox().then(({ sandboxId }) => {
|
|
371
|
-
(0,
|
|
372
|
-
|
|
373
|
-
}).catch((e) => {
|
|
385
|
+
this.sandboxCreationPromise ??= this.provider.createSandbox().then(({ sandboxId }) => ({
|
|
386
|
+
sandbox_id: (0, import_sandboxRef.formatSandboxId)({ providerType: this.provider.type, rawId: sandboxId })
|
|
387
|
+
})).catch((e) => {
|
|
374
388
|
this.sandboxCreationPromise = void 0;
|
|
375
389
|
throw e;
|
|
376
390
|
});
|
|
377
391
|
const sandboxInfo = await this.sandboxCreationPromise;
|
|
378
|
-
const
|
|
379
|
-
|
|
392
|
+
const raced = this.peekExistingSandboxInfo();
|
|
393
|
+
if (raced !== void 0) {
|
|
394
|
+
return { sandboxInfo: raced, sandboxCreated: void 0 };
|
|
395
|
+
}
|
|
380
396
|
this.existingSandboxInfo = sandboxInfo;
|
|
381
|
-
return { sandboxInfo, sandboxCreated:
|
|
397
|
+
return { sandboxInfo, sandboxCreated: sandboxInfo };
|
|
382
398
|
}
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
399
|
+
peekExistingSandboxInfo() {
|
|
400
|
+
return this.existingSandboxInfo;
|
|
401
|
+
}
|
|
402
|
+
/** Same-type missing remote/local root: drop the stale id and create a new fancy id. */
|
|
403
|
+
async recreateAfterUnavailable() {
|
|
404
|
+
this.clearExistingSandbox();
|
|
405
|
+
const created = await this.ensureSandboxCreated();
|
|
406
|
+
if (created.sandboxCreated === void 0) {
|
|
407
|
+
throw new Error("Sandbox recreate did not create a new sandbox");
|
|
408
|
+
}
|
|
409
|
+
return { sandboxInfo: created.sandboxInfo, sandboxCreated: created.sandboxCreated };
|
|
410
|
+
}
|
|
411
|
+
/**
|
|
412
|
+
* Create or reattach, then init. A missing same-type sandbox throws
|
|
413
|
+
* `SandboxNotAvailableError` from the provider; reattach then recreates.
|
|
414
|
+
*/
|
|
415
|
+
async ensureReadySandbox() {
|
|
416
|
+
const first = await this.ensureSandboxCreated();
|
|
386
417
|
try {
|
|
387
418
|
await this.ensureSandboxInitialized();
|
|
419
|
+
return first;
|
|
420
|
+
} catch (error) {
|
|
421
|
+
if (!(error instanceof import_SandboxErrors.SandboxNotAvailableError) || first.sandboxCreated !== void 0) {
|
|
422
|
+
throw error;
|
|
423
|
+
}
|
|
424
|
+
const recreated = await this.recreateAfterUnavailable();
|
|
425
|
+
await this.ensureSandboxInitialized();
|
|
426
|
+
return recreated;
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
async handleExec(input) {
|
|
430
|
+
let sandboxInfo;
|
|
431
|
+
let sandboxCreated;
|
|
432
|
+
try {
|
|
433
|
+
({ sandboxInfo, sandboxCreated } = await this.ensureReadySandbox());
|
|
388
434
|
} catch (e) {
|
|
389
435
|
this.logger.error("Sandbox initialization failed", (0, import_errorLogFields.extractErrorLogFields)(e));
|
|
390
436
|
const message = e instanceof Error ? e.message : "Sandbox initialization failed";
|
|
437
|
+
const fallback = this.existingSandboxInfo;
|
|
391
438
|
return (0, import_IMCPServer.toolResultResponse)({
|
|
392
439
|
text: `Sandbox initialization failed: ${message}`,
|
|
393
440
|
isError: true,
|
|
394
|
-
overrides: {
|
|
441
|
+
overrides: {
|
|
442
|
+
sandboxCreated: Boolean(fallback),
|
|
443
|
+
...fallback !== void 0 ? { sandboxInfo: fallback } : {}
|
|
444
|
+
}
|
|
395
445
|
});
|
|
396
446
|
}
|
|
397
|
-
const
|
|
447
|
+
const sandboxCreatedFlag = Boolean(sandboxCreated);
|
|
448
|
+
const rawId = this.providerSandboxId(sandboxInfo.sandbox_id);
|
|
449
|
+
const codeModeEnv = await this.ensureCodeModeStarted(rawId);
|
|
398
450
|
const mcpClientEnv = injectMCPClientEnv({
|
|
399
451
|
env: input.env,
|
|
400
452
|
mcpServers: this.buildMcpServersEnvelope(),
|
|
401
|
-
|
|
402
|
-
|
|
453
|
+
codeModeEnv,
|
|
454
|
+
mcpClientInstall: this.mcpClientInstall
|
|
403
455
|
});
|
|
404
|
-
const gitAuthEnv = this.resolvedGitCredentialsContent !== null ? buildGitCredentialHelperEnv(this.provider.getGitCredentialsPath(
|
|
456
|
+
const gitAuthEnv = this.resolvedGitCredentialsContent !== null ? buildGitCredentialHelperEnv(this.provider.getGitCredentialsPath(rawId)) : {};
|
|
405
457
|
const env = { ...mcpClientEnv, ...gitAuthEnv };
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
458
|
+
try {
|
|
459
|
+
const result = await this.provider.exec({
|
|
460
|
+
sandboxId: rawId,
|
|
461
|
+
command: input.command,
|
|
462
|
+
cwd: input.cwd,
|
|
463
|
+
env
|
|
464
|
+
});
|
|
465
|
+
return {
|
|
466
|
+
result: {
|
|
467
|
+
content: [{ type: "text", text: JSON.stringify(result) }],
|
|
468
|
+
isError: !result.success
|
|
469
|
+
},
|
|
470
|
+
wasInitialized: void 0,
|
|
471
|
+
sandboxCreated: sandboxCreatedFlag,
|
|
472
|
+
sandboxInfo
|
|
473
|
+
};
|
|
474
|
+
} catch (error) {
|
|
475
|
+
if (!(error instanceof import_SandboxErrors.SandboxNotAvailableError) || sandboxCreated !== void 0) {
|
|
476
|
+
throw error;
|
|
477
|
+
}
|
|
478
|
+
const recreated = await this.recreateAfterUnavailable();
|
|
479
|
+
await this.ensureSandboxInitialized();
|
|
480
|
+
const recreatedRawId = this.providerSandboxId(recreated.sandboxInfo.sandbox_id);
|
|
481
|
+
const retryCodeModeEnv = await this.ensureCodeModeStarted(recreatedRawId);
|
|
482
|
+
const retryEnv = {
|
|
483
|
+
...injectMCPClientEnv({
|
|
484
|
+
env: input.env,
|
|
485
|
+
mcpServers: this.buildMcpServersEnvelope(),
|
|
486
|
+
codeModeEnv: retryCodeModeEnv,
|
|
487
|
+
mcpClientInstall: this.mcpClientInstall
|
|
488
|
+
}),
|
|
489
|
+
...this.resolvedGitCredentialsContent !== null ? buildGitCredentialHelperEnv(this.provider.getGitCredentialsPath(recreatedRawId)) : {}
|
|
490
|
+
};
|
|
491
|
+
const retryResult = await this.provider.exec({
|
|
492
|
+
sandboxId: recreatedRawId,
|
|
493
|
+
command: input.command,
|
|
494
|
+
cwd: input.cwd,
|
|
495
|
+
env: retryEnv
|
|
496
|
+
});
|
|
497
|
+
return {
|
|
498
|
+
result: {
|
|
499
|
+
content: [{ type: "text", text: JSON.stringify(retryResult) }],
|
|
500
|
+
isError: !retryResult.success
|
|
501
|
+
},
|
|
502
|
+
wasInitialized: void 0,
|
|
503
|
+
sandboxCreated: true,
|
|
504
|
+
sandboxInfo: recreated.sandboxInfo
|
|
505
|
+
};
|
|
506
|
+
}
|
|
421
507
|
}
|
|
422
508
|
async getToolResultDumpDir() {
|
|
423
|
-
const { sandboxCreated } = await this.ensureSandboxCreated();
|
|
424
|
-
const dir = this.provider.getToolResultDumpDir(this.
|
|
509
|
+
const { sandboxCreated, sandboxInfo } = await this.ensureSandboxCreated();
|
|
510
|
+
const dir = this.provider.getToolResultDumpDir(this.providerSandboxId(sandboxInfo.sandbox_id)).replace(/\/+$/, "");
|
|
425
511
|
return { dir, sandboxCreated };
|
|
426
512
|
}
|
|
427
513
|
async uploadFile(params) {
|
|
428
|
-
const { sandboxCreated } = await this.
|
|
429
|
-
await this.ensureSandboxInitialized();
|
|
430
|
-
const { sandbox_id: sandboxId } = this.requiredSandboxInfo;
|
|
514
|
+
const { sandboxCreated, sandboxInfo } = await this.ensureReadySandbox();
|
|
431
515
|
const fileName = params.fileName.replace(/^\/+/, "");
|
|
432
516
|
const targetDir = params.targetDir.replace(/\/+$/, "");
|
|
433
517
|
const filePath = `${targetDir}/${fileName}`;
|
|
434
|
-
await this.provider.uploadFile({
|
|
518
|
+
await this.provider.uploadFile({
|
|
519
|
+
sandboxId: this.providerSandboxId(sandboxInfo.sandbox_id),
|
|
520
|
+
remotePath: filePath,
|
|
521
|
+
content: params.content
|
|
522
|
+
});
|
|
435
523
|
return { filePath, sandboxCreated };
|
|
436
524
|
}
|
|
437
525
|
async uploadUserFile(input) {
|
|
438
526
|
(0, import_SandboxErrors.validateNoPathTraversal)(input.fileName);
|
|
527
|
+
const { sandboxCreated, sandboxInfo } = await this.ensureReadySandbox();
|
|
439
528
|
const result = await this.uploadFile({
|
|
440
|
-
targetDir:
|
|
529
|
+
targetDir: this.provider.getFileUploadsDir(this.providerSandboxId(sandboxInfo.sandbox_id)),
|
|
441
530
|
fileName: input.fileName,
|
|
442
531
|
content: input.content
|
|
443
532
|
});
|
|
533
|
+
const created = sandboxCreated ?? result.sandboxCreated;
|
|
444
534
|
return {
|
|
445
535
|
filePath: result.filePath,
|
|
446
|
-
...
|
|
536
|
+
...created && { sandboxCreated: created }
|
|
447
537
|
};
|
|
448
538
|
}
|
|
449
539
|
async writeArtifact(input) {
|
|
@@ -472,7 +562,7 @@ var Sandbox = class _Sandbox extends import_LocalToolMCP.LocalToolMCP {
|
|
|
472
562
|
await this.sandboxInitPromise;
|
|
473
563
|
}
|
|
474
564
|
async writeGitCredentials() {
|
|
475
|
-
const sandboxId = this.requiredSandboxInfo.sandbox_id;
|
|
565
|
+
const sandboxId = this.providerSandboxId(this.requiredSandboxInfo.sandbox_id);
|
|
476
566
|
const credentialsPath = this.provider.getGitCredentialsPath(sandboxId);
|
|
477
567
|
const result = await this.provider.exec({
|
|
478
568
|
sandboxId,
|
|
@@ -481,30 +571,56 @@ var Sandbox = class _Sandbox extends import_LocalToolMCP.LocalToolMCP {
|
|
|
481
571
|
(0, import_Provider.ensureExecSuccess)(result);
|
|
482
572
|
}
|
|
483
573
|
async initSandboxEnvironment() {
|
|
484
|
-
const
|
|
574
|
+
const sandboxId = this.providerSandboxId(this.requiredSandboxInfo.sandbox_id);
|
|
575
|
+
const fileUploadsDir = this.provider.getFileUploadsDir(sandboxId);
|
|
576
|
+
const skillsDir = this.provider.getSkillsDir(sandboxId);
|
|
577
|
+
const toolResultDumpDir = this.provider.getToolResultDumpDir(sandboxId);
|
|
485
578
|
this.logger.info("Uploading MCP client script and preparing skills directory in sandbox");
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
579
|
+
this.mcpClientInstall = this.codeModeTransport?.getClientInstall({ sandboxId });
|
|
580
|
+
const install = this.mcpClientInstall;
|
|
581
|
+
const dirs = [(0, import_Provider.shellEscape)(fileUploadsDir), (0, import_Provider.shellEscape)(toolResultDumpDir), (0, import_Provider.shellEscape)(skillsDir)];
|
|
582
|
+
if (install !== void 0) {
|
|
583
|
+
const { pythonPath, binDir } = mcpClientLayout(install.remotePath);
|
|
584
|
+
dirs.push((0, import_Provider.shellEscape)(pythonPath));
|
|
585
|
+
if (install.pathBinSymlink === void 0) {
|
|
586
|
+
dirs.push((0, import_Provider.shellEscape)(binDir));
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
(0, import_Provider.ensureExecSuccess)(await this.provider.exec({ sandboxId, command: `mkdir -p ${dirs.join(" ")}` }));
|
|
590
|
+
const initSteps = [];
|
|
591
|
+
if (install !== void 0) {
|
|
592
|
+
await this.provider.uploadFile({
|
|
593
|
+
sandboxId,
|
|
594
|
+
remotePath: install.remotePath,
|
|
595
|
+
content: Buffer.from(install.content, "utf-8")
|
|
596
|
+
});
|
|
597
|
+
initSteps.push(`chmod 0555 ${(0, import_Provider.shellEscape)(install.remotePath)}`);
|
|
598
|
+
if (install.pathBinSymlink !== void 0) {
|
|
599
|
+
initSteps.push(`ln -sf ${(0, import_Provider.shellEscape)(install.remotePath)} ${(0, import_Provider.shellEscape)(install.pathBinSymlink)}`);
|
|
600
|
+
} else {
|
|
601
|
+
const { binDir, binLink } = mcpClientLayout(install.remotePath);
|
|
602
|
+
initSteps.push(`ln -sf ${(0, import_Provider.shellEscape)((0, import_node_path.relative)(binDir, install.remotePath))} ${(0, import_Provider.shellEscape)(binLink)}`);
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
const skillInit = this.skillMounter?.getSandboxInit({
|
|
606
|
+
skillsDir,
|
|
607
|
+
gitDownloaderPath: this.provider.getGitDownloaderPath(sandboxId)
|
|
608
|
+
});
|
|
495
609
|
if (skillInit) {
|
|
496
610
|
initSteps.push(skillInit.command);
|
|
497
611
|
}
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
612
|
+
if (initSteps.length > 0) {
|
|
613
|
+
(0, import_Provider.ensureExecSuccess)(
|
|
614
|
+
await this.provider.exec({
|
|
615
|
+
sandboxId,
|
|
616
|
+
command: initSteps.join(" && "),
|
|
617
|
+
env: skillInit?.env,
|
|
618
|
+
timeoutSeconds: skillInit?.timeoutSeconds
|
|
619
|
+
})
|
|
620
|
+
);
|
|
621
|
+
}
|
|
506
622
|
this.logger.info(
|
|
507
|
-
`Sandbox initialized:
|
|
623
|
+
install === void 0 ? `Sandbox initialized: skills dir ${skillsDir}` : `Sandbox initialized: MCP client at ${install.remotePath}; skills dir ${skillsDir}`
|
|
508
624
|
);
|
|
509
625
|
await this.writeGitCredentials();
|
|
510
626
|
}
|