@truefoundry/trueforge-core 0.1.3 → 0.1.4
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 -4
- package/dist/core/sandbox/Sandbox.d.ts.map +1 -1
- package/dist/core/sandbox/Sandbox.js +200 -80
- package/dist/core/sandbox/Sandbox.js.map +1 -1
- package/dist/core/sandbox/Sandbox.mjs +201 -81
- 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/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,9 +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
113
|
...params.env ?? {},
|
|
108
|
-
|
|
114
|
+
...layout !== void 0 && {
|
|
115
|
+
PYTHONPATH: layout.pythonPath
|
|
116
|
+
},
|
|
109
117
|
...Object.keys(params.mcpServers).length > 0 && {
|
|
110
118
|
TFY_MCP_SERVERS: Buffer.from(JSON.stringify(params.mcpServers)).toString("base64")
|
|
111
119
|
},
|
|
@@ -137,14 +145,12 @@ function createSandboxLargeToolResponseGuidance() {
|
|
|
137
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}>.`;
|
|
138
146
|
}
|
|
139
147
|
var SANDBOX_MCP_SERVER_ID = "sandbox";
|
|
140
|
-
var Sandbox = class
|
|
148
|
+
var Sandbox = class extends import_LocalToolMCP.LocalToolMCP {
|
|
141
149
|
name = SANDBOX_MCP_SERVER_ID;
|
|
142
150
|
displayName = "Sandbox";
|
|
143
151
|
description = "Persistent sandbox environment for code execution";
|
|
144
|
-
static FILE_UPLOADS_DIR = import_constants.SANDBOX_FILE_UPLOADS_DIR;
|
|
145
152
|
provider;
|
|
146
153
|
existingSandboxId;
|
|
147
|
-
tenantName;
|
|
148
154
|
existingSandboxInfo;
|
|
149
155
|
// Cached promise to prevent concurrent sub-agents from creating duplicate sandboxes.
|
|
150
156
|
sandboxCreationPromise;
|
|
@@ -154,12 +160,13 @@ var Sandbox = class _Sandbox extends import_LocalToolMCP.LocalToolMCP {
|
|
|
154
160
|
requestTimeoutSeconds;
|
|
155
161
|
skillMounter;
|
|
156
162
|
cachedSkillsSection;
|
|
157
|
-
mcpClientScriptBase64;
|
|
158
163
|
logger;
|
|
159
164
|
// Pre-resolved credential-store file content (null = clear / no git auth).
|
|
160
165
|
resolvedGitCredentialsContent;
|
|
161
166
|
codeModeDispatcher;
|
|
162
167
|
codeModeTransport;
|
|
168
|
+
/** Cached from transport.getClientInstall after sandbox init (when Code Mode is configured). */
|
|
169
|
+
mcpClientInstall;
|
|
163
170
|
tools = [
|
|
164
171
|
(0, import_LocalToolMCP.defineTool)({
|
|
165
172
|
name: SANDBOX_EXEC_TOOL_NAME,
|
|
@@ -172,19 +179,24 @@ var Sandbox = class _Sandbox extends import_LocalToolMCP.LocalToolMCP {
|
|
|
172
179
|
super({ tracing: options.tracing });
|
|
173
180
|
this.provider = options.provider;
|
|
174
181
|
this.existingSandboxId = options.existingSandboxId;
|
|
175
|
-
this.tenantName = options.tenantName;
|
|
176
182
|
this.skillMounter = options.skillMounter;
|
|
177
183
|
this.fileDownloadEnabled = options.fileDownloadEnabled ?? false;
|
|
178
184
|
const mcpBoundTimeoutMs = options.mcpRequestTimeoutMs + options.mcpConnectTimeoutMs;
|
|
179
185
|
this.requestTimeoutSeconds = Math.ceil(mcpBoundTimeoutMs / 1e3) + NATS_REQUEST_TIMEOUT_BUFFER_SECONDS;
|
|
180
|
-
this.mcpClientScriptBase64 = Buffer.from(import_sandboxScripts.sandboxScripts.mcpClient, "utf-8").toString("base64");
|
|
181
186
|
this.logger = options.logger.child({ module: "Sandbox" });
|
|
182
187
|
this.resolvedGitCredentialsContent = options.resolvedGitCredentialsContent ?? null;
|
|
183
188
|
if (this.existingSandboxId) {
|
|
184
|
-
(0, import_SandboxErrors.validateSandboxOwnedByTenant)(this.existingSandboxId, this.tenantName);
|
|
185
189
|
this.existingSandboxInfo = { sandbox_id: this.existingSandboxId };
|
|
186
190
|
}
|
|
187
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
|
+
}
|
|
188
200
|
buildMcpServersEnvelope() {
|
|
189
201
|
const out = {};
|
|
190
202
|
for (const server of this.codeExecToolSets) {
|
|
@@ -214,7 +226,7 @@ var Sandbox = class _Sandbox extends import_LocalToolMCP.LocalToolMCP {
|
|
|
214
226
|
renderSkillsSection() {
|
|
215
227
|
if (this.cachedSkillsSection === void 0) {
|
|
216
228
|
const skills = new import_InstructionBuilder.InstructionBuilder("skills");
|
|
217
|
-
this.skillMounter?.instruction(skills);
|
|
229
|
+
this.skillMounter?.instruction(skills, { skillsDir: this.provider.getSkillsDir(this.promptSandboxId()) });
|
|
218
230
|
this.cachedSkillsSection = skills.build();
|
|
219
231
|
}
|
|
220
232
|
return this.cachedSkillsSection;
|
|
@@ -238,7 +250,7 @@ var Sandbox = class _Sandbox extends import_LocalToolMCP.LocalToolMCP {
|
|
|
238
250
|
buildFileUploadsSection(builder) {
|
|
239
251
|
builder.addSection(
|
|
240
252
|
SANDBOX_FILE_UPLOADS_TAG,
|
|
241
|
-
`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.`
|
|
242
254
|
);
|
|
243
255
|
}
|
|
244
256
|
buildSchemaSection(builder) {
|
|
@@ -360,86 +372,168 @@ var Sandbox = class _Sandbox extends import_LocalToolMCP.LocalToolMCP {
|
|
|
360
372
|
}
|
|
361
373
|
return this.existingSandboxInfo;
|
|
362
374
|
}
|
|
375
|
+
clearExistingSandbox() {
|
|
376
|
+
this.existingSandboxInfo = void 0;
|
|
377
|
+
this.sandboxCreationPromise = void 0;
|
|
378
|
+
this.sandboxInitPromise = void 0;
|
|
379
|
+
this.mcpClientInstall = void 0;
|
|
380
|
+
}
|
|
363
381
|
async ensureSandboxCreated() {
|
|
364
382
|
if (this.existingSandboxInfo) {
|
|
365
383
|
return { sandboxInfo: this.existingSandboxInfo, sandboxCreated: void 0 };
|
|
366
384
|
}
|
|
367
|
-
this.sandboxCreationPromise ??= this.provider.createSandbox().then(({ sandboxId }) => {
|
|
368
|
-
(0,
|
|
369
|
-
|
|
370
|
-
}).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) => {
|
|
371
388
|
this.sandboxCreationPromise = void 0;
|
|
372
389
|
throw e;
|
|
373
390
|
});
|
|
374
391
|
const sandboxInfo = await this.sandboxCreationPromise;
|
|
375
|
-
const
|
|
376
|
-
|
|
392
|
+
const raced = this.peekExistingSandboxInfo();
|
|
393
|
+
if (raced !== void 0) {
|
|
394
|
+
return { sandboxInfo: raced, sandboxCreated: void 0 };
|
|
395
|
+
}
|
|
377
396
|
this.existingSandboxInfo = sandboxInfo;
|
|
378
|
-
return { sandboxInfo, sandboxCreated:
|
|
397
|
+
return { sandboxInfo, sandboxCreated: sandboxInfo };
|
|
379
398
|
}
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
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();
|
|
383
417
|
try {
|
|
384
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());
|
|
385
434
|
} catch (e) {
|
|
386
435
|
this.logger.error("Sandbox initialization failed", (0, import_errorLogFields.extractErrorLogFields)(e));
|
|
387
436
|
const message = e instanceof Error ? e.message : "Sandbox initialization failed";
|
|
437
|
+
const fallback = this.existingSandboxInfo;
|
|
388
438
|
return (0, import_IMCPServer.toolResultResponse)({
|
|
389
439
|
text: `Sandbox initialization failed: ${message}`,
|
|
390
440
|
isError: true,
|
|
391
|
-
overrides: {
|
|
441
|
+
overrides: {
|
|
442
|
+
sandboxCreated: Boolean(fallback),
|
|
443
|
+
...fallback !== void 0 ? { sandboxInfo: fallback } : {}
|
|
444
|
+
}
|
|
392
445
|
});
|
|
393
446
|
}
|
|
394
|
-
const
|
|
447
|
+
const sandboxCreatedFlag = Boolean(sandboxCreated);
|
|
448
|
+
const rawId = this.providerSandboxId(sandboxInfo.sandbox_id);
|
|
449
|
+
const codeModeEnv = await this.ensureCodeModeStarted(rawId);
|
|
395
450
|
const mcpClientEnv = injectMCPClientEnv({
|
|
396
451
|
env: input.env,
|
|
397
452
|
mcpServers: this.buildMcpServersEnvelope(),
|
|
398
|
-
codeModeEnv
|
|
453
|
+
codeModeEnv,
|
|
454
|
+
mcpClientInstall: this.mcpClientInstall
|
|
399
455
|
});
|
|
400
|
-
const gitAuthEnv = this.resolvedGitCredentialsContent !== null ? buildGitCredentialHelperEnv(this.provider.getGitCredentialsPath(
|
|
456
|
+
const gitAuthEnv = this.resolvedGitCredentialsContent !== null ? buildGitCredentialHelperEnv(this.provider.getGitCredentialsPath(rawId)) : {};
|
|
401
457
|
const env = { ...mcpClientEnv, ...gitAuthEnv };
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
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
|
+
}
|
|
417
507
|
}
|
|
418
508
|
async getToolResultDumpDir() {
|
|
419
|
-
const { sandboxCreated } = await this.ensureSandboxCreated();
|
|
420
|
-
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(/\/+$/, "");
|
|
421
511
|
return { dir, sandboxCreated };
|
|
422
512
|
}
|
|
423
513
|
async uploadFile(params) {
|
|
424
|
-
const { sandboxCreated } = await this.
|
|
425
|
-
await this.ensureSandboxInitialized();
|
|
426
|
-
const { sandbox_id: sandboxId } = this.requiredSandboxInfo;
|
|
514
|
+
const { sandboxCreated, sandboxInfo } = await this.ensureReadySandbox();
|
|
427
515
|
const fileName = params.fileName.replace(/^\/+/, "");
|
|
428
516
|
const targetDir = params.targetDir.replace(/\/+$/, "");
|
|
429
517
|
const filePath = `${targetDir}/${fileName}`;
|
|
430
|
-
await this.provider.uploadFile({
|
|
518
|
+
await this.provider.uploadFile({
|
|
519
|
+
sandboxId: this.providerSandboxId(sandboxInfo.sandbox_id),
|
|
520
|
+
remotePath: filePath,
|
|
521
|
+
content: params.content
|
|
522
|
+
});
|
|
431
523
|
return { filePath, sandboxCreated };
|
|
432
524
|
}
|
|
433
525
|
async uploadUserFile(input) {
|
|
434
526
|
(0, import_SandboxErrors.validateNoPathTraversal)(input.fileName);
|
|
527
|
+
const { sandboxCreated, sandboxInfo } = await this.ensureReadySandbox();
|
|
435
528
|
const result = await this.uploadFile({
|
|
436
|
-
targetDir:
|
|
529
|
+
targetDir: this.provider.getFileUploadsDir(this.providerSandboxId(sandboxInfo.sandbox_id)),
|
|
437
530
|
fileName: input.fileName,
|
|
438
531
|
content: input.content
|
|
439
532
|
});
|
|
533
|
+
const created = sandboxCreated ?? result.sandboxCreated;
|
|
440
534
|
return {
|
|
441
535
|
filePath: result.filePath,
|
|
442
|
-
...
|
|
536
|
+
...created && { sandboxCreated: created }
|
|
443
537
|
};
|
|
444
538
|
}
|
|
445
539
|
async writeArtifact(input) {
|
|
@@ -468,7 +562,7 @@ var Sandbox = class _Sandbox extends import_LocalToolMCP.LocalToolMCP {
|
|
|
468
562
|
await this.sandboxInitPromise;
|
|
469
563
|
}
|
|
470
564
|
async writeGitCredentials() {
|
|
471
|
-
const sandboxId = this.requiredSandboxInfo.sandbox_id;
|
|
565
|
+
const sandboxId = this.providerSandboxId(this.requiredSandboxInfo.sandbox_id);
|
|
472
566
|
const credentialsPath = this.provider.getGitCredentialsPath(sandboxId);
|
|
473
567
|
const result = await this.provider.exec({
|
|
474
568
|
sandboxId,
|
|
@@ -477,30 +571,56 @@ var Sandbox = class _Sandbox extends import_LocalToolMCP.LocalToolMCP {
|
|
|
477
571
|
(0, import_Provider.ensureExecSuccess)(result);
|
|
478
572
|
}
|
|
479
573
|
async initSandboxEnvironment() {
|
|
480
|
-
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);
|
|
481
578
|
this.logger.info("Uploading MCP client script and preparing skills directory in sandbox");
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
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
|
+
});
|
|
491
609
|
if (skillInit) {
|
|
492
610
|
initSteps.push(skillInit.command);
|
|
493
611
|
}
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
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
|
+
}
|
|
502
622
|
this.logger.info(
|
|
503
|
-
`Sandbox initialized:
|
|
623
|
+
install === void 0 ? `Sandbox initialized: skills dir ${skillsDir}` : `Sandbox initialized: MCP client at ${install.remotePath}; skills dir ${skillsDir}`
|
|
504
624
|
);
|
|
505
625
|
await this.writeGitCredentials();
|
|
506
626
|
}
|