@axiom-lattice/core 2.1.50 → 2.1.52
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/index.d.mts +269 -237
- package/dist/index.d.ts +269 -237
- package/dist/index.js +409 -202
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +406 -207
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
package/dist/index.mjs
CHANGED
|
@@ -3266,39 +3266,68 @@ ${serverKeys.map(
|
|
|
3266
3266
|
// src/tool_lattice/code_eval/index.ts
|
|
3267
3267
|
import z15 from "zod";
|
|
3268
3268
|
|
|
3269
|
-
// src/
|
|
3270
|
-
|
|
3271
|
-
|
|
3272
|
-
|
|
3269
|
+
// src/deep_agent_new/backends/volumeFilesystem.ts
|
|
3270
|
+
var VolumeFilesystem = class {
|
|
3271
|
+
constructor(client) {
|
|
3272
|
+
this.client = client;
|
|
3273
3273
|
}
|
|
3274
|
-
|
|
3275
|
-
|
|
3276
|
-
|
|
3277
|
-
|
|
3278
|
-
|
|
3279
|
-
|
|
3280
|
-
|
|
3281
|
-
|
|
3282
|
-
`Sandbox name "${name}" cannot be normalized to a valid RFC 1123 subdomain name`
|
|
3283
|
-
);
|
|
3274
|
+
async lsInfo(path4) {
|
|
3275
|
+
const entries = await this.client.list(path4);
|
|
3276
|
+
return entries.map((entry) => ({
|
|
3277
|
+
path: entry.path,
|
|
3278
|
+
is_dir: entry.kind === "directory",
|
|
3279
|
+
size: entry.size,
|
|
3280
|
+
modified_at: entry.modified ? new Date(entry.modified).toISOString() : void 0
|
|
3281
|
+
}));
|
|
3284
3282
|
}
|
|
3285
|
-
|
|
3286
|
-
|
|
3283
|
+
async read(filePath, offset = 0, limit = 2e3) {
|
|
3284
|
+
const raw = await this.client.read(filePath);
|
|
3285
|
+
const lines = raw.split("\n");
|
|
3286
|
+
const start = Math.max(0, offset);
|
|
3287
|
+
const end = Math.min(lines.length, start + limit);
|
|
3288
|
+
const sliced = lines.slice(start, end);
|
|
3289
|
+
return sliced.map((line, i) => {
|
|
3290
|
+
const lineNum = (start + i + 1).toString().padStart(6, " ");
|
|
3291
|
+
return `${lineNum}|${line}`;
|
|
3292
|
+
}).join("\n");
|
|
3287
3293
|
}
|
|
3288
|
-
|
|
3289
|
-
|
|
3294
|
+
async readRaw(filePath) {
|
|
3295
|
+
const content = await this.client.read(filePath);
|
|
3296
|
+
const lines = content.split("\n");
|
|
3297
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
3298
|
+
return {
|
|
3299
|
+
content: lines,
|
|
3300
|
+
created_at: now,
|
|
3301
|
+
modified_at: now
|
|
3302
|
+
};
|
|
3290
3303
|
}
|
|
3291
|
-
|
|
3292
|
-
|
|
3293
|
-
|
|
3294
|
-
|
|
3295
|
-
|
|
3296
|
-
|
|
3297
|
-
|
|
3298
|
-
|
|
3304
|
+
grepRaw(_pattern, _path, _glob) {
|
|
3305
|
+
throw new Error("Not supported on volume backend");
|
|
3306
|
+
}
|
|
3307
|
+
globInfo(_pattern, _path) {
|
|
3308
|
+
throw new Error("Not supported on volume backend");
|
|
3309
|
+
}
|
|
3310
|
+
async write(filePath, content) {
|
|
3311
|
+
try {
|
|
3312
|
+
await this.client.write(filePath, content);
|
|
3313
|
+
return { path: filePath, filesUpdate: null };
|
|
3314
|
+
} catch (err) {
|
|
3315
|
+
return { error: String(err) };
|
|
3299
3316
|
}
|
|
3300
3317
|
}
|
|
3301
|
-
|
|
3318
|
+
edit(_filePath, _oldString, _newString, _replaceAll) {
|
|
3319
|
+
throw new Error("Not supported on volume backend");
|
|
3320
|
+
}
|
|
3321
|
+
};
|
|
3322
|
+
|
|
3323
|
+
// src/sandbox_lattice/utils.ts
|
|
3324
|
+
import { createHash } from "crypto";
|
|
3325
|
+
function normalizeSandboxName(name) {
|
|
3326
|
+
if (!name || typeof name !== "string") {
|
|
3327
|
+
throw new Error("Sandbox name must be a non-empty string");
|
|
3328
|
+
}
|
|
3329
|
+
const hash = createHash("sha256").update(name).digest("hex").slice(0, 16);
|
|
3330
|
+
return `n${hash}`;
|
|
3302
3331
|
}
|
|
3303
3332
|
function isValidSandboxName(name) {
|
|
3304
3333
|
if (!name || typeof name !== "string") {
|
|
@@ -3307,6 +3336,24 @@ function isValidSandboxName(name) {
|
|
|
3307
3336
|
const rfc1123Pattern = /^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$/;
|
|
3308
3337
|
return rfc1123Pattern.test(name.toLowerCase());
|
|
3309
3338
|
}
|
|
3339
|
+
function buildSandboxMetadataEnv(config) {
|
|
3340
|
+
if (!config) {
|
|
3341
|
+
return {};
|
|
3342
|
+
}
|
|
3343
|
+
const vars = {};
|
|
3344
|
+
if (config.tenantId) vars.LATTICE_TENANT_ID = config.tenantId;
|
|
3345
|
+
if (config.assistant_id) vars.LATTICE_ASSISTANT_ID = config.assistant_id;
|
|
3346
|
+
if (config.projectId) vars.LATTICE_PROJECT_ID = config.projectId;
|
|
3347
|
+
if (config.workspaceId) vars.LATTICE_WORKSPACE_ID = config.workspaceId;
|
|
3348
|
+
return vars;
|
|
3349
|
+
}
|
|
3350
|
+
|
|
3351
|
+
// src/sandbox_lattice/volumeFsUtils.ts
|
|
3352
|
+
import { createHash as createHash2 } from "crypto";
|
|
3353
|
+
function buildNamedVolumeName(prefix, ...parts) {
|
|
3354
|
+
const hash = createHash2("sha256").update(parts.filter((part) => part !== void 0).join("\0")).digest("hex").slice(0, 16);
|
|
3355
|
+
return `${prefix}${hash}`;
|
|
3356
|
+
}
|
|
3310
3357
|
|
|
3311
3358
|
// src/sandbox_lattice/SandboxLatticeManager.ts
|
|
3312
3359
|
function computeSandboxName(config) {
|
|
@@ -3317,7 +3364,7 @@ function computeSandboxName(config) {
|
|
|
3317
3364
|
return normalizeSandboxName(`${config.tenantId ?? "default"}-${config.assistant_id}`);
|
|
3318
3365
|
case "project":
|
|
3319
3366
|
return normalizeSandboxName(
|
|
3320
|
-
`${config.tenantId ?? "default"}-${config.
|
|
3367
|
+
`${config.tenantId ?? "default"}-${config.assistant_id ?? "default"}-${config.projectId ?? "default"}`
|
|
3321
3368
|
);
|
|
3322
3369
|
}
|
|
3323
3370
|
}
|
|
@@ -3379,6 +3426,19 @@ var SandboxLatticeManager = class _SandboxLatticeManager extends BaseLatticeMana
|
|
|
3379
3426
|
});
|
|
3380
3427
|
return this.createSandbox(name, config);
|
|
3381
3428
|
}
|
|
3429
|
+
async getVolumeBackend(config) {
|
|
3430
|
+
const provider = this._requireProvider();
|
|
3431
|
+
if (!provider.createVolumeFsClient) {
|
|
3432
|
+
return null;
|
|
3433
|
+
}
|
|
3434
|
+
const tenantId = config.tenantId ?? "default";
|
|
3435
|
+
if (!config.projectId) {
|
|
3436
|
+
return null;
|
|
3437
|
+
}
|
|
3438
|
+
const volumeName = buildNamedVolumeName("p", "project", tenantId, config.workspaceId, config.projectId);
|
|
3439
|
+
const client = provider.createVolumeFsClient(volumeName);
|
|
3440
|
+
return new VolumeFilesystem(client);
|
|
3441
|
+
}
|
|
3382
3442
|
async createSandbox(name, config) {
|
|
3383
3443
|
const provider = this._requireProvider();
|
|
3384
3444
|
return provider.createSandbox(name, config);
|
|
@@ -4414,13 +4474,6 @@ import { HumanMessage as HumanMessage3 } from "@langchain/core/messages";
|
|
|
4414
4474
|
// src/agent_lattice/types.ts
|
|
4415
4475
|
import {
|
|
4416
4476
|
AgentType,
|
|
4417
|
-
AgentConfig,
|
|
4418
|
-
ReactAgentConfig,
|
|
4419
|
-
DeepAgentConfig,
|
|
4420
|
-
TeamAgentConfig,
|
|
4421
|
-
TeamTeammateConfig,
|
|
4422
|
-
AgentConfigWithTools,
|
|
4423
|
-
GraphBuildOptions,
|
|
4424
4477
|
hasTools,
|
|
4425
4478
|
isDeepAgentConfig,
|
|
4426
4479
|
isTeamAgentConfig,
|
|
@@ -5011,21 +5064,28 @@ function truncateIfTooLong(result) {
|
|
|
5011
5064
|
}
|
|
5012
5065
|
return result;
|
|
5013
5066
|
}
|
|
5014
|
-
function validatePath(
|
|
5015
|
-
const pathStr =
|
|
5067
|
+
function validatePath(path4) {
|
|
5068
|
+
const pathStr = path4 || "/";
|
|
5016
5069
|
if (!pathStr || pathStr.trim() === "") {
|
|
5017
5070
|
throw new Error("Path cannot be empty");
|
|
5018
5071
|
}
|
|
5019
|
-
let normalized
|
|
5072
|
+
let normalized;
|
|
5073
|
+
if (pathStr === "~") {
|
|
5074
|
+
normalized = "~/";
|
|
5075
|
+
} else if (pathStr.startsWith("~/")) {
|
|
5076
|
+
normalized = pathStr;
|
|
5077
|
+
} else {
|
|
5078
|
+
normalized = pathStr.startsWith("/") ? pathStr : "/" + pathStr;
|
|
5079
|
+
}
|
|
5020
5080
|
if (!normalized.endsWith("/")) {
|
|
5021
5081
|
normalized += "/";
|
|
5022
5082
|
}
|
|
5023
5083
|
return normalized;
|
|
5024
5084
|
}
|
|
5025
|
-
function globSearchFiles(files, pattern,
|
|
5085
|
+
function globSearchFiles(files, pattern, path4 = "/") {
|
|
5026
5086
|
let normalizedPath;
|
|
5027
5087
|
try {
|
|
5028
|
-
normalizedPath = validatePath(
|
|
5088
|
+
normalizedPath = validatePath(path4);
|
|
5029
5089
|
} catch {
|
|
5030
5090
|
return "No files found";
|
|
5031
5091
|
}
|
|
@@ -5077,7 +5137,7 @@ function formatGrepResults(results, outputMode) {
|
|
|
5077
5137
|
}
|
|
5078
5138
|
return lines.join("\n");
|
|
5079
5139
|
}
|
|
5080
|
-
function grepSearchFiles(files, pattern,
|
|
5140
|
+
function grepSearchFiles(files, pattern, path4 = null, glob = null, outputMode = "files_with_matches") {
|
|
5081
5141
|
let regex;
|
|
5082
5142
|
try {
|
|
5083
5143
|
regex = new RegExp(pattern);
|
|
@@ -5086,7 +5146,7 @@ function grepSearchFiles(files, pattern, path3 = null, glob = null, outputMode =
|
|
|
5086
5146
|
}
|
|
5087
5147
|
let normalizedPath;
|
|
5088
5148
|
try {
|
|
5089
|
-
normalizedPath = validatePath(
|
|
5149
|
+
normalizedPath = validatePath(path4);
|
|
5090
5150
|
} catch {
|
|
5091
5151
|
return "No matches found";
|
|
5092
5152
|
}
|
|
@@ -5118,7 +5178,7 @@ function grepSearchFiles(files, pattern, path3 = null, glob = null, outputMode =
|
|
|
5118
5178
|
}
|
|
5119
5179
|
return formatGrepResults(results, outputMode);
|
|
5120
5180
|
}
|
|
5121
|
-
function grepMatchesFromFiles(files, pattern,
|
|
5181
|
+
function grepMatchesFromFiles(files, pattern, path4 = null, glob = null) {
|
|
5122
5182
|
let regex;
|
|
5123
5183
|
try {
|
|
5124
5184
|
regex = new RegExp(pattern);
|
|
@@ -5127,7 +5187,7 @@ function grepMatchesFromFiles(files, pattern, path3 = null, glob = null) {
|
|
|
5127
5187
|
}
|
|
5128
5188
|
let normalizedPath;
|
|
5129
5189
|
try {
|
|
5130
|
-
normalizedPath = validatePath(
|
|
5190
|
+
normalizedPath = validatePath(path4);
|
|
5131
5191
|
} catch {
|
|
5132
5192
|
return [];
|
|
5133
5193
|
}
|
|
@@ -5188,11 +5248,11 @@ var StateBackend = class {
|
|
|
5188
5248
|
* @returns List of FileInfo objects for files and directories directly in the directory.
|
|
5189
5249
|
* Directories have a trailing / in their path and is_dir=true.
|
|
5190
5250
|
*/
|
|
5191
|
-
lsInfo(
|
|
5251
|
+
lsInfo(path4) {
|
|
5192
5252
|
const files = this.getFiles();
|
|
5193
5253
|
const infos = [];
|
|
5194
5254
|
const subdirs = /* @__PURE__ */ new Set();
|
|
5195
|
-
const normalizedPath =
|
|
5255
|
+
const normalizedPath = path4.endsWith("/") ? path4 : path4 + "/";
|
|
5196
5256
|
for (const [k, fd] of Object.entries(files)) {
|
|
5197
5257
|
if (!k.startsWith(normalizedPath)) {
|
|
5198
5258
|
continue;
|
|
@@ -5298,16 +5358,16 @@ var StateBackend = class {
|
|
|
5298
5358
|
/**
|
|
5299
5359
|
* Structured search results or error string for invalid input.
|
|
5300
5360
|
*/
|
|
5301
|
-
grepRaw(pattern,
|
|
5361
|
+
grepRaw(pattern, path4 = "/", glob = null) {
|
|
5302
5362
|
const files = this.getFiles();
|
|
5303
|
-
return grepMatchesFromFiles(files, pattern,
|
|
5363
|
+
return grepMatchesFromFiles(files, pattern, path4, glob);
|
|
5304
5364
|
}
|
|
5305
5365
|
/**
|
|
5306
5366
|
* Structured glob matching returning FileInfo objects.
|
|
5307
5367
|
*/
|
|
5308
|
-
globInfo(pattern,
|
|
5368
|
+
globInfo(pattern, path4 = "/") {
|
|
5309
5369
|
const files = this.getFiles();
|
|
5310
|
-
const result = globSearchFiles(files, pattern,
|
|
5370
|
+
const result = globSearchFiles(files, pattern, path4);
|
|
5311
5371
|
if (result === "No files found") {
|
|
5312
5372
|
return [];
|
|
5313
5373
|
}
|
|
@@ -5401,10 +5461,10 @@ function createLsTool(backend, options) {
|
|
|
5401
5461
|
...runConfig
|
|
5402
5462
|
};
|
|
5403
5463
|
const resolvedBackend = await getBackend(backend, stateAndStore);
|
|
5404
|
-
const
|
|
5405
|
-
const infos = await resolvedBackend.lsInfo(
|
|
5464
|
+
const path4 = input.path || "/";
|
|
5465
|
+
const infos = await resolvedBackend.lsInfo(path4);
|
|
5406
5466
|
if (infos.length === 0) {
|
|
5407
|
-
return `No files found in ${
|
|
5467
|
+
return `No files found in ${path4}`;
|
|
5408
5468
|
}
|
|
5409
5469
|
const lines = [];
|
|
5410
5470
|
for (const info of infos) {
|
|
@@ -5547,8 +5607,8 @@ function createGlobTool(backend, options) {
|
|
|
5547
5607
|
...runConfig
|
|
5548
5608
|
};
|
|
5549
5609
|
const resolvedBackend = await getBackend(backend, stateAndStore);
|
|
5550
|
-
const { pattern, path:
|
|
5551
|
-
const infos = await resolvedBackend.globInfo(pattern,
|
|
5610
|
+
const { pattern, path: path4 = "/" } = input;
|
|
5611
|
+
const infos = await resolvedBackend.globInfo(pattern, path4);
|
|
5552
5612
|
if (infos.length === 0) {
|
|
5553
5613
|
return `No files found matching pattern '${pattern}'`;
|
|
5554
5614
|
}
|
|
@@ -5575,8 +5635,8 @@ function createGrepTool(backend, options) {
|
|
|
5575
5635
|
...runConfig
|
|
5576
5636
|
};
|
|
5577
5637
|
const resolvedBackend = await getBackend(backend, stateAndStore);
|
|
5578
|
-
const { pattern, path:
|
|
5579
|
-
const result = await resolvedBackend.grepRaw(pattern,
|
|
5638
|
+
const { pattern, path: path4 = "/", glob = null } = input;
|
|
5639
|
+
const result = await resolvedBackend.grepRaw(pattern, path4, glob);
|
|
5580
5640
|
if (typeof result === "string") {
|
|
5581
5641
|
return result;
|
|
5582
5642
|
}
|
|
@@ -12995,13 +13055,13 @@ var StoreBackend = class {
|
|
|
12995
13055
|
* @returns List of FileInfo objects for files and directories directly in the directory.
|
|
12996
13056
|
* Directories have a trailing / in their path and is_dir=true.
|
|
12997
13057
|
*/
|
|
12998
|
-
async lsInfo(
|
|
13058
|
+
async lsInfo(path4) {
|
|
12999
13059
|
const store = this.getStore();
|
|
13000
13060
|
const namespace = this.getNamespace();
|
|
13001
13061
|
const items = await this.searchStorePaginated(store, namespace);
|
|
13002
13062
|
const infos = [];
|
|
13003
13063
|
const subdirs = /* @__PURE__ */ new Set();
|
|
13004
|
-
const normalizedPath =
|
|
13064
|
+
const normalizedPath = path4.endsWith("/") ? path4 : path4 + "/";
|
|
13005
13065
|
for (const item of items) {
|
|
13006
13066
|
const itemKey = String(item.key);
|
|
13007
13067
|
if (!itemKey.startsWith(normalizedPath)) {
|
|
@@ -13119,7 +13179,7 @@ var StoreBackend = class {
|
|
|
13119
13179
|
/**
|
|
13120
13180
|
* Structured search results or error string for invalid input.
|
|
13121
13181
|
*/
|
|
13122
|
-
async grepRaw(pattern,
|
|
13182
|
+
async grepRaw(pattern, path4 = "/", glob = null) {
|
|
13123
13183
|
const store = this.getStore();
|
|
13124
13184
|
const namespace = this.getNamespace();
|
|
13125
13185
|
const items = await this.searchStorePaginated(store, namespace);
|
|
@@ -13131,12 +13191,12 @@ var StoreBackend = class {
|
|
|
13131
13191
|
continue;
|
|
13132
13192
|
}
|
|
13133
13193
|
}
|
|
13134
|
-
return grepMatchesFromFiles(files, pattern,
|
|
13194
|
+
return grepMatchesFromFiles(files, pattern, path4, glob);
|
|
13135
13195
|
}
|
|
13136
13196
|
/**
|
|
13137
13197
|
* Structured glob matching returning FileInfo objects.
|
|
13138
13198
|
*/
|
|
13139
|
-
async globInfo(pattern,
|
|
13199
|
+
async globInfo(pattern, path4 = "/") {
|
|
13140
13200
|
const store = this.getStore();
|
|
13141
13201
|
const namespace = this.getNamespace();
|
|
13142
13202
|
const items = await this.searchStorePaginated(store, namespace);
|
|
@@ -13148,7 +13208,7 @@ var StoreBackend = class {
|
|
|
13148
13208
|
continue;
|
|
13149
13209
|
}
|
|
13150
13210
|
}
|
|
13151
|
-
const result = globSearchFiles(files, pattern,
|
|
13211
|
+
const result = globSearchFiles(files, pattern, path4);
|
|
13152
13212
|
if (result === "No files found") {
|
|
13153
13213
|
return [];
|
|
13154
13214
|
}
|
|
@@ -13197,8 +13257,9 @@ var FilesystemBackend = class {
|
|
|
13197
13257
|
*/
|
|
13198
13258
|
resolvePath(key) {
|
|
13199
13259
|
if (this.virtualMode) {
|
|
13200
|
-
const
|
|
13201
|
-
|
|
13260
|
+
const normalizedKey = key === "~" ? "/" : key.startsWith("~/") ? `/${key.slice(2)}` : key;
|
|
13261
|
+
const vpath = normalizedKey.startsWith("/") ? normalizedKey : "/" + normalizedKey;
|
|
13262
|
+
if (vpath.includes("..") || vpath.includes("~")) {
|
|
13202
13263
|
throw new Error("Path traversal not allowed");
|
|
13203
13264
|
}
|
|
13204
13265
|
const full = path2.resolve(this.cwd, vpath.substring(1));
|
|
@@ -13723,10 +13784,10 @@ var CompositeBackend = class {
|
|
|
13723
13784
|
* @returns List of FileInfo objects with route prefixes added, for files and directories
|
|
13724
13785
|
* directly in the directory. Directories have a trailing / in their path and is_dir=true.
|
|
13725
13786
|
*/
|
|
13726
|
-
async lsInfo(
|
|
13787
|
+
async lsInfo(path4) {
|
|
13727
13788
|
for (const [routePrefix, backend] of this.sortedRoutes) {
|
|
13728
|
-
if (
|
|
13729
|
-
const suffix =
|
|
13789
|
+
if (path4.startsWith(routePrefix.replace(/\/$/, ""))) {
|
|
13790
|
+
const suffix = path4.substring(routePrefix.length);
|
|
13730
13791
|
const searchPath = suffix ? "/" + suffix : "/";
|
|
13731
13792
|
const infos = await backend.lsInfo(searchPath);
|
|
13732
13793
|
const prefixed = [];
|
|
@@ -13739,9 +13800,9 @@ var CompositeBackend = class {
|
|
|
13739
13800
|
return prefixed;
|
|
13740
13801
|
}
|
|
13741
13802
|
}
|
|
13742
|
-
if (
|
|
13803
|
+
if (path4 === "/") {
|
|
13743
13804
|
const results = [];
|
|
13744
|
-
const defaultInfos = await this.default.lsInfo(
|
|
13805
|
+
const defaultInfos = await this.default.lsInfo(path4);
|
|
13745
13806
|
results.push(...defaultInfos);
|
|
13746
13807
|
for (const [routePrefix] of this.sortedRoutes) {
|
|
13747
13808
|
results.push({
|
|
@@ -13754,7 +13815,7 @@ var CompositeBackend = class {
|
|
|
13754
13815
|
results.sort((a, b) => a.path.localeCompare(b.path));
|
|
13755
13816
|
return results;
|
|
13756
13817
|
}
|
|
13757
|
-
return await this.default.lsInfo(
|
|
13818
|
+
return await this.default.lsInfo(path4);
|
|
13758
13819
|
}
|
|
13759
13820
|
/**
|
|
13760
13821
|
* Read file content, routing to appropriate backend.
|
|
@@ -13781,10 +13842,10 @@ var CompositeBackend = class {
|
|
|
13781
13842
|
/**
|
|
13782
13843
|
* Structured search results or error string for invalid input.
|
|
13783
13844
|
*/
|
|
13784
|
-
async grepRaw(pattern,
|
|
13845
|
+
async grepRaw(pattern, path4 = "/", glob = null) {
|
|
13785
13846
|
for (const [routePrefix, backend] of this.sortedRoutes) {
|
|
13786
|
-
if (
|
|
13787
|
-
const searchPath =
|
|
13847
|
+
if (path4.startsWith(routePrefix.replace(/\/$/, ""))) {
|
|
13848
|
+
const searchPath = path4.substring(routePrefix.length - 1);
|
|
13788
13849
|
const raw = await backend.grepRaw(pattern, searchPath || "/", glob);
|
|
13789
13850
|
if (typeof raw === "string") {
|
|
13790
13851
|
return raw;
|
|
@@ -13796,7 +13857,7 @@ var CompositeBackend = class {
|
|
|
13796
13857
|
}
|
|
13797
13858
|
}
|
|
13798
13859
|
const allMatches = [];
|
|
13799
|
-
const rawDefault = await this.default.grepRaw(pattern,
|
|
13860
|
+
const rawDefault = await this.default.grepRaw(pattern, path4, glob);
|
|
13800
13861
|
if (typeof rawDefault === "string") {
|
|
13801
13862
|
return rawDefault;
|
|
13802
13863
|
}
|
|
@@ -13818,11 +13879,11 @@ var CompositeBackend = class {
|
|
|
13818
13879
|
/**
|
|
13819
13880
|
* Structured glob matching returning FileInfo objects.
|
|
13820
13881
|
*/
|
|
13821
|
-
async globInfo(pattern,
|
|
13882
|
+
async globInfo(pattern, path4 = "/") {
|
|
13822
13883
|
const results = [];
|
|
13823
13884
|
for (const [routePrefix, backend] of this.sortedRoutes) {
|
|
13824
|
-
if (
|
|
13825
|
-
const searchPath =
|
|
13885
|
+
if (path4.startsWith(routePrefix.replace(/\/$/, ""))) {
|
|
13886
|
+
const searchPath = path4.substring(routePrefix.length - 1);
|
|
13826
13887
|
const infos = await backend.globInfo(pattern, searchPath || "/");
|
|
13827
13888
|
return infos.map((fi) => ({
|
|
13828
13889
|
...fi,
|
|
@@ -13830,7 +13891,7 @@ var CompositeBackend = class {
|
|
|
13830
13891
|
}));
|
|
13831
13892
|
}
|
|
13832
13893
|
}
|
|
13833
|
-
const defaultInfos = await this.default.globInfo(pattern,
|
|
13894
|
+
const defaultInfos = await this.default.globInfo(pattern, path4);
|
|
13834
13895
|
results.push(...defaultInfos);
|
|
13835
13896
|
for (const [routePrefix, backend] of Object.entries(this.routes)) {
|
|
13836
13897
|
const infos = await backend.globInfo(pattern, "/");
|
|
@@ -13878,11 +13939,11 @@ var MemoryBackend = class {
|
|
|
13878
13939
|
getFiles() {
|
|
13879
13940
|
return Object.fromEntries(this.files);
|
|
13880
13941
|
}
|
|
13881
|
-
lsInfo(
|
|
13942
|
+
lsInfo(path4) {
|
|
13882
13943
|
const files = this.getFiles();
|
|
13883
13944
|
const infos = [];
|
|
13884
13945
|
const subdirs = /* @__PURE__ */ new Set();
|
|
13885
|
-
const normalizedPath =
|
|
13946
|
+
const normalizedPath = path4.endsWith("/") ? path4 : path4 + "/";
|
|
13886
13947
|
for (const [k, fd] of Object.entries(files)) {
|
|
13887
13948
|
if (!k.startsWith(normalizedPath)) {
|
|
13888
13949
|
continue;
|
|
@@ -13957,13 +14018,13 @@ var MemoryBackend = class {
|
|
|
13957
14018
|
this.files.set(filePath, newFileData);
|
|
13958
14019
|
return { path: filePath, filesUpdate: null, occurrences };
|
|
13959
14020
|
}
|
|
13960
|
-
grepRaw(pattern,
|
|
14021
|
+
grepRaw(pattern, path4 = "/", glob = null) {
|
|
13961
14022
|
const files = this.getFiles();
|
|
13962
|
-
return grepMatchesFromFiles(files, pattern,
|
|
14023
|
+
return grepMatchesFromFiles(files, pattern, path4, glob);
|
|
13963
14024
|
}
|
|
13964
|
-
globInfo(pattern,
|
|
14025
|
+
globInfo(pattern, path4 = "/") {
|
|
13965
14026
|
const files = this.getFiles();
|
|
13966
|
-
const result = globSearchFiles(files, pattern,
|
|
14027
|
+
const result = globSearchFiles(files, pattern, path4);
|
|
13967
14028
|
if (result === "No files found") {
|
|
13968
14029
|
return [];
|
|
13969
14030
|
}
|
|
@@ -18011,22 +18072,30 @@ var mcpManager = McpLatticeManager.getInstance();
|
|
|
18011
18072
|
import { Sandbox } from "microsandbox";
|
|
18012
18073
|
|
|
18013
18074
|
// src/sandbox_lattice/MicrosandboxInstance.ts
|
|
18075
|
+
function exec(native, cmd, opts) {
|
|
18076
|
+
return native.execWith(cmd, (b) => {
|
|
18077
|
+
if (opts?.args) b.args(opts.args);
|
|
18078
|
+
if (opts?.cwd) b.cwd(opts.cwd);
|
|
18079
|
+
if (opts?.timeoutMs) b.timeout(opts.timeoutMs);
|
|
18080
|
+
return b;
|
|
18081
|
+
});
|
|
18082
|
+
}
|
|
18014
18083
|
var MicrosandboxInstance = class {
|
|
18015
18084
|
constructor(name, native) {
|
|
18016
18085
|
this.native = native;
|
|
18017
18086
|
this.file = {
|
|
18018
18087
|
readFile: async (file) => {
|
|
18019
18088
|
const fs3 = this.native.fs();
|
|
18020
|
-
const content = await fs3.
|
|
18089
|
+
const content = await fs3.readToString(file);
|
|
18021
18090
|
return { content };
|
|
18022
18091
|
},
|
|
18023
18092
|
writeFile: async (file, content) => {
|
|
18024
18093
|
const fs3 = this.native.fs();
|
|
18025
18094
|
await fs3.write(file, Buffer.from(content));
|
|
18026
18095
|
},
|
|
18027
|
-
listPath: async (
|
|
18096
|
+
listPath: async (path4, options) => {
|
|
18028
18097
|
const fs3 = this.native.fs();
|
|
18029
|
-
const entries = await fs3.list(
|
|
18098
|
+
const entries = await fs3.list(path4);
|
|
18030
18099
|
const files = (entries || []).map((e) => ({
|
|
18031
18100
|
path: e.path,
|
|
18032
18101
|
is_dir: e.kind === "directory",
|
|
@@ -18035,17 +18104,15 @@ var MicrosandboxInstance = class {
|
|
|
18035
18104
|
}));
|
|
18036
18105
|
return { files };
|
|
18037
18106
|
},
|
|
18038
|
-
findFiles: async (
|
|
18039
|
-
const output = await this.native
|
|
18040
|
-
|
|
18041
|
-
args: ["-c", `find "${path3}" -name "${glob}" -type f`]
|
|
18107
|
+
findFiles: async (path4, glob) => {
|
|
18108
|
+
const output = await exec(this.native, "sh", {
|
|
18109
|
+
args: ["-c", `find "${path4}" -name "${glob}" -type f`]
|
|
18042
18110
|
});
|
|
18043
18111
|
const lines = output.stdout().split("\n").filter(Boolean);
|
|
18044
18112
|
return { files: lines };
|
|
18045
18113
|
},
|
|
18046
18114
|
searchInFile: async (file, regex) => {
|
|
18047
|
-
const output = await this.native
|
|
18048
|
-
cmd: "grep",
|
|
18115
|
+
const output = await exec(this.native, "grep", {
|
|
18049
18116
|
args: ["-n", "-E", regex, file]
|
|
18050
18117
|
});
|
|
18051
18118
|
const lines = output.stdout().split("\n").filter(Boolean);
|
|
@@ -18062,14 +18129,13 @@ var MicrosandboxInstance = class {
|
|
|
18062
18129
|
return { matches, line_numbers };
|
|
18063
18130
|
},
|
|
18064
18131
|
strReplaceEditor: async (params) => {
|
|
18065
|
-
const { path:
|
|
18132
|
+
const { path: path4, old_str, new_str, replace_mode } = params;
|
|
18066
18133
|
const delim = "#";
|
|
18067
18134
|
const escapedOld = old_str.replace(new RegExp(`[\\\\${delim}]`, "g"), "\\$&").replace(/\n/g, "\\n");
|
|
18068
18135
|
const escapedNew = new_str.replace(new RegExp(`[\\\\${delim}]`, "g"), "\\$&").replace(/\n/g, "\\n");
|
|
18069
18136
|
const flag = replace_mode === "ALL" ? "g" : "";
|
|
18070
|
-
await this.native
|
|
18071
|
-
|
|
18072
|
-
args: ["-c", `sed -i 's${delim}${escapedOld}${delim}${escapedNew}${delim}${flag}' "${path3}"`]
|
|
18137
|
+
await exec(this.native, "sh", {
|
|
18138
|
+
args: ["-c", `sed -i 's${delim}${escapedOld}${delim}${escapedNew}${delim}${flag}' "${path4}"`]
|
|
18073
18139
|
});
|
|
18074
18140
|
},
|
|
18075
18141
|
uploadFile: async (params) => {
|
|
@@ -18084,8 +18150,7 @@ var MicrosandboxInstance = class {
|
|
|
18084
18150
|
};
|
|
18085
18151
|
this.shell = {
|
|
18086
18152
|
execCommand: async (params) => {
|
|
18087
|
-
const output = await this.native
|
|
18088
|
-
cmd: "sh",
|
|
18153
|
+
const output = await exec(this.native, "sh", {
|
|
18089
18154
|
args: ["-c", params.command],
|
|
18090
18155
|
cwd: params.exec_dir,
|
|
18091
18156
|
timeoutMs: params.timeout ? params.timeout * 1e3 : void 0
|
|
@@ -18108,7 +18173,7 @@ var MicrosandboxInstance = class {
|
|
|
18108
18173
|
}
|
|
18109
18174
|
async getStatus() {
|
|
18110
18175
|
try {
|
|
18111
|
-
await this.native.
|
|
18176
|
+
await this.native.exec("echo", ["ok"]);
|
|
18112
18177
|
return "running";
|
|
18113
18178
|
} catch {
|
|
18114
18179
|
return "unknown";
|
|
@@ -18135,7 +18200,7 @@ var MicrosandboxProvider = class {
|
|
|
18135
18200
|
this.instances = /* @__PURE__ */ new Map();
|
|
18136
18201
|
this.creating = /* @__PURE__ */ new Map();
|
|
18137
18202
|
}
|
|
18138
|
-
async createSandbox(name) {
|
|
18203
|
+
async createSandbox(name, config) {
|
|
18139
18204
|
const existing = this.instances.get(name);
|
|
18140
18205
|
if (existing) {
|
|
18141
18206
|
return existing;
|
|
@@ -18162,13 +18227,11 @@ var MicrosandboxProvider = class {
|
|
|
18162
18227
|
native = void 0;
|
|
18163
18228
|
}
|
|
18164
18229
|
if (!native) {
|
|
18165
|
-
|
|
18166
|
-
|
|
18167
|
-
|
|
18168
|
-
cpus: this.config.cpus ?? 1,
|
|
18169
|
-
memoryMib: this.config.memoryMib ?? 512,
|
|
18170
|
-
env: this.config.env
|
|
18230
|
+
const builder = Sandbox.builder(name).image(this.config.image ?? "python:3.11-slim").cpus(this.config.cpus ?? 1).memory(this.config.memoryMib ?? 512).envs({
|
|
18231
|
+
...this.config.env,
|
|
18232
|
+
...buildSandboxMetadataEnv(config)
|
|
18171
18233
|
});
|
|
18234
|
+
native = await builder.createDetached();
|
|
18172
18235
|
}
|
|
18173
18236
|
const instance = new MicrosandboxInstance(name, native);
|
|
18174
18237
|
this.instances.set(name, instance);
|
|
@@ -18208,31 +18271,92 @@ var MicrosandboxProvider = class {
|
|
|
18208
18271
|
}
|
|
18209
18272
|
};
|
|
18210
18273
|
|
|
18274
|
+
// src/sandbox_lattice/pathUtils.ts
|
|
18275
|
+
import path3 from "path";
|
|
18276
|
+
var SANDBOX_HOME_DIR = "/home/daytona";
|
|
18277
|
+
function normalizeExternalSandboxPath(inputPath) {
|
|
18278
|
+
if (inputPath === "~") {
|
|
18279
|
+
return "~/";
|
|
18280
|
+
}
|
|
18281
|
+
if (inputPath === SANDBOX_HOME_DIR) {
|
|
18282
|
+
return "~/";
|
|
18283
|
+
}
|
|
18284
|
+
if (inputPath.startsWith(`${SANDBOX_HOME_DIR}/`)) {
|
|
18285
|
+
return `~/${inputPath.slice(SANDBOX_HOME_DIR.length + 1)}`;
|
|
18286
|
+
}
|
|
18287
|
+
if (inputPath.startsWith("~/")) {
|
|
18288
|
+
return inputPath;
|
|
18289
|
+
}
|
|
18290
|
+
if (inputPath.startsWith("/")) {
|
|
18291
|
+
return `~${inputPath}`;
|
|
18292
|
+
}
|
|
18293
|
+
return inputPath;
|
|
18294
|
+
}
|
|
18295
|
+
function toSandboxRelativePath(inputPath) {
|
|
18296
|
+
const canonicalPath = normalizeExternalSandboxPath(inputPath);
|
|
18297
|
+
return canonicalPath === "~/" ? "" : canonicalPath.slice(2);
|
|
18298
|
+
}
|
|
18299
|
+
function toSandboxAbsolutePath(inputPath, homeDir = SANDBOX_HOME_DIR) {
|
|
18300
|
+
const relativePath = toSandboxRelativePath(inputPath);
|
|
18301
|
+
return relativePath ? path3.posix.join(homeDir, relativePath) : homeDir;
|
|
18302
|
+
}
|
|
18303
|
+
function fromSandboxExecutionPath(inputPath, homeDir = SANDBOX_HOME_DIR) {
|
|
18304
|
+
if (inputPath === homeDir) {
|
|
18305
|
+
return "~/";
|
|
18306
|
+
}
|
|
18307
|
+
if (inputPath.startsWith(`${homeDir}/`)) {
|
|
18308
|
+
return `~/${inputPath.slice(homeDir.length + 1)}`;
|
|
18309
|
+
}
|
|
18310
|
+
return normalizeExternalSandboxPath(inputPath);
|
|
18311
|
+
}
|
|
18312
|
+
|
|
18211
18313
|
// src/sandbox_lattice/MicrosandboxRemoteInstance.ts
|
|
18212
18314
|
var MicrosandboxRemoteInstance = class {
|
|
18213
18315
|
constructor(name, client) {
|
|
18214
18316
|
this.client = client;
|
|
18215
18317
|
this.file = {
|
|
18216
18318
|
readFile: async (file) => {
|
|
18217
|
-
const result = await this.client.readFile(
|
|
18319
|
+
const result = await this.client.readFile(
|
|
18320
|
+
this.name,
|
|
18321
|
+
toSandboxAbsolutePath(file, SANDBOX_HOME_DIR)
|
|
18322
|
+
);
|
|
18218
18323
|
return { content: result.content };
|
|
18219
18324
|
},
|
|
18220
18325
|
writeFile: async (file, content) => {
|
|
18221
|
-
await this.client.writeFile(
|
|
18326
|
+
await this.client.writeFile(
|
|
18327
|
+
this.name,
|
|
18328
|
+
toSandboxAbsolutePath(file, SANDBOX_HOME_DIR),
|
|
18329
|
+
content
|
|
18330
|
+
);
|
|
18222
18331
|
},
|
|
18223
|
-
listPath: async (
|
|
18224
|
-
const result = await this.client.listPath(
|
|
18332
|
+
listPath: async (path4, options) => {
|
|
18333
|
+
const result = await this.client.listPath(
|
|
18334
|
+
this.name,
|
|
18335
|
+
toSandboxAbsolutePath(path4, SANDBOX_HOME_DIR),
|
|
18336
|
+
options?.recursive
|
|
18337
|
+
);
|
|
18225
18338
|
const files = result.entries.map((entry) => ({
|
|
18226
|
-
path: entry.path,
|
|
18227
|
-
is_dir: entry.type === "
|
|
18339
|
+
path: fromSandboxExecutionPath(entry.path, SANDBOX_HOME_DIR),
|
|
18340
|
+
is_dir: entry.type === "directory"
|
|
18228
18341
|
}));
|
|
18229
18342
|
return { files };
|
|
18230
18343
|
},
|
|
18231
|
-
findFiles: async (
|
|
18232
|
-
|
|
18344
|
+
findFiles: async (path4, glob) => {
|
|
18345
|
+
const result = await this.client.findFiles(
|
|
18346
|
+
this.name,
|
|
18347
|
+
toSandboxAbsolutePath(path4, SANDBOX_HOME_DIR),
|
|
18348
|
+
glob
|
|
18349
|
+
);
|
|
18350
|
+
return {
|
|
18351
|
+
files: result.files.map((filePath) => fromSandboxExecutionPath(filePath, SANDBOX_HOME_DIR))
|
|
18352
|
+
};
|
|
18233
18353
|
},
|
|
18234
18354
|
searchInFile: async (file, regex) => {
|
|
18235
|
-
const result = await this.client.searchInFile(
|
|
18355
|
+
const result = await this.client.searchInFile(
|
|
18356
|
+
this.name,
|
|
18357
|
+
toSandboxAbsolutePath(file, SANDBOX_HOME_DIR),
|
|
18358
|
+
regex
|
|
18359
|
+
);
|
|
18236
18360
|
return {
|
|
18237
18361
|
matches: result.matches.map((match) => match.content),
|
|
18238
18362
|
line_numbers: result.matches.map((match) => match.line)
|
|
@@ -18240,16 +18364,23 @@ var MicrosandboxRemoteInstance = class {
|
|
|
18240
18364
|
},
|
|
18241
18365
|
strReplaceEditor: async (params) => {
|
|
18242
18366
|
await this.client.replaceInFile(this.name, {
|
|
18243
|
-
path: params.path,
|
|
18367
|
+
path: toSandboxAbsolutePath(params.path, SANDBOX_HOME_DIR),
|
|
18244
18368
|
search: params.old_str,
|
|
18245
18369
|
replace: params.new_str
|
|
18246
18370
|
});
|
|
18247
18371
|
},
|
|
18248
18372
|
uploadFile: async (params) => {
|
|
18249
|
-
await this.client.uploadFile(
|
|
18373
|
+
await this.client.uploadFile(
|
|
18374
|
+
this.name,
|
|
18375
|
+
toSandboxAbsolutePath(params.file, SANDBOX_HOME_DIR),
|
|
18376
|
+
params.data
|
|
18377
|
+
);
|
|
18250
18378
|
},
|
|
18251
18379
|
downloadFile: async (params) => {
|
|
18252
|
-
const result = await this.client.downloadFile(
|
|
18380
|
+
const result = await this.client.downloadFile(
|
|
18381
|
+
this.name,
|
|
18382
|
+
toSandboxAbsolutePath(params.file, SANDBOX_HOME_DIR)
|
|
18383
|
+
);
|
|
18253
18384
|
if (result.contentBase64) {
|
|
18254
18385
|
return Buffer.from(result.contentBase64, "base64");
|
|
18255
18386
|
}
|
|
@@ -18294,6 +18425,7 @@ var MicrosandboxRemoteInstance = class {
|
|
|
18294
18425
|
var MicrosandboxServiceClient = class {
|
|
18295
18426
|
constructor(config) {
|
|
18296
18427
|
this.baseURL = config.baseURL.replace(/\/$/, "");
|
|
18428
|
+
this.apiKey = config.apiKey;
|
|
18297
18429
|
}
|
|
18298
18430
|
async ensureSandbox(name, input) {
|
|
18299
18431
|
return this.request(`/api/sandboxes/${encodeURIComponent(name)}`, {
|
|
@@ -18326,34 +18458,34 @@ var MicrosandboxServiceClient = class {
|
|
|
18326
18458
|
method: "GET"
|
|
18327
18459
|
});
|
|
18328
18460
|
}
|
|
18329
|
-
async readFile(sandboxName,
|
|
18461
|
+
async readFile(sandboxName, path4) {
|
|
18330
18462
|
return this.request("/api/files/read", {
|
|
18331
18463
|
method: "POST",
|
|
18332
|
-
body: { sandboxName, path:
|
|
18464
|
+
body: { sandboxName, path: path4 }
|
|
18333
18465
|
});
|
|
18334
18466
|
}
|
|
18335
|
-
async writeFile(sandboxName,
|
|
18467
|
+
async writeFile(sandboxName, path4, content) {
|
|
18336
18468
|
return this.request("/api/files/write", {
|
|
18337
18469
|
method: "POST",
|
|
18338
|
-
body: { sandboxName, path:
|
|
18470
|
+
body: { sandboxName, path: path4, content }
|
|
18339
18471
|
});
|
|
18340
18472
|
}
|
|
18341
|
-
async listPath(sandboxName,
|
|
18473
|
+
async listPath(sandboxName, path4, recursive) {
|
|
18342
18474
|
return this.request("/api/files/list", {
|
|
18343
18475
|
method: "POST",
|
|
18344
|
-
body: { sandboxName, path:
|
|
18476
|
+
body: { sandboxName, path: path4, recursive }
|
|
18345
18477
|
});
|
|
18346
18478
|
}
|
|
18347
|
-
async findFiles(sandboxName,
|
|
18479
|
+
async findFiles(sandboxName, path4, pattern) {
|
|
18348
18480
|
return this.request("/api/files/find", {
|
|
18349
18481
|
method: "POST",
|
|
18350
|
-
body: { sandboxName, path:
|
|
18482
|
+
body: { sandboxName, path: path4, pattern }
|
|
18351
18483
|
});
|
|
18352
18484
|
}
|
|
18353
|
-
async searchInFile(sandboxName,
|
|
18485
|
+
async searchInFile(sandboxName, path4, query) {
|
|
18354
18486
|
return this.request("/api/files/search", {
|
|
18355
18487
|
method: "POST",
|
|
18356
|
-
body: { sandboxName, path:
|
|
18488
|
+
body: { sandboxName, path: path4, query }
|
|
18357
18489
|
});
|
|
18358
18490
|
}
|
|
18359
18491
|
async replaceInFile(sandboxName, input) {
|
|
@@ -18362,14 +18494,14 @@ var MicrosandboxServiceClient = class {
|
|
|
18362
18494
|
body: { sandboxName, ...input }
|
|
18363
18495
|
});
|
|
18364
18496
|
}
|
|
18365
|
-
async uploadFile(sandboxName,
|
|
18497
|
+
async uploadFile(sandboxName, path4, content) {
|
|
18366
18498
|
return this.request("/api/files/upload", {
|
|
18367
18499
|
method: "POST",
|
|
18368
|
-
body: { sandboxName, path:
|
|
18500
|
+
body: { sandboxName, path: path4, contentBase64: content.toString("base64") }
|
|
18369
18501
|
});
|
|
18370
18502
|
}
|
|
18371
|
-
async downloadFile(sandboxName,
|
|
18372
|
-
const query = new URLSearchParams({ sandboxName, path:
|
|
18503
|
+
async downloadFile(sandboxName, path4) {
|
|
18504
|
+
const query = new URLSearchParams({ sandboxName, path: path4 });
|
|
18373
18505
|
return this.request(`/api/files/download?${query.toString()}`, {
|
|
18374
18506
|
method: "GET"
|
|
18375
18507
|
});
|
|
@@ -18380,33 +18512,109 @@ var MicrosandboxServiceClient = class {
|
|
|
18380
18512
|
body: input
|
|
18381
18513
|
});
|
|
18382
18514
|
}
|
|
18383
|
-
async
|
|
18384
|
-
const
|
|
18515
|
+
async volumeFsRead(volumeName, path4) {
|
|
18516
|
+
const result = await this.request(
|
|
18517
|
+
`/api/volumes/${encodeURIComponent(volumeName)}/fs/read`,
|
|
18518
|
+
{
|
|
18519
|
+
method: "POST",
|
|
18520
|
+
body: { path: path4 }
|
|
18521
|
+
}
|
|
18522
|
+
);
|
|
18523
|
+
return result.content;
|
|
18524
|
+
}
|
|
18525
|
+
async volumeFsWrite(volumeName, path4, content) {
|
|
18526
|
+
await this.request(
|
|
18527
|
+
`/api/volumes/${encodeURIComponent(volumeName)}/fs/write`,
|
|
18528
|
+
{
|
|
18529
|
+
method: "POST",
|
|
18530
|
+
body: { path: path4, content }
|
|
18531
|
+
}
|
|
18532
|
+
);
|
|
18533
|
+
}
|
|
18534
|
+
async volumeFsList(volumeName, path4) {
|
|
18535
|
+
const result = await this.request(
|
|
18536
|
+
`/api/volumes/${encodeURIComponent(volumeName)}/fs/list`,
|
|
18537
|
+
{
|
|
18538
|
+
method: "POST",
|
|
18539
|
+
body: { path: path4 }
|
|
18540
|
+
}
|
|
18541
|
+
);
|
|
18542
|
+
return result.entries;
|
|
18543
|
+
}
|
|
18544
|
+
async volumeFsDownload(volumeName, path4) {
|
|
18545
|
+
const result = await this.request(
|
|
18546
|
+
`/api/volumes/${encodeURIComponent(volumeName)}/fs/download?path=${encodeURIComponent(path4)}`,
|
|
18547
|
+
{
|
|
18548
|
+
method: "GET"
|
|
18549
|
+
}
|
|
18550
|
+
);
|
|
18551
|
+
return Buffer.from(result.contentBase64, "base64");
|
|
18552
|
+
}
|
|
18553
|
+
async volumeFsUpload(volumeName, path4, data) {
|
|
18554
|
+
await this.request(
|
|
18555
|
+
`/api/volumes/${encodeURIComponent(volumeName)}/fs/upload`,
|
|
18556
|
+
{
|
|
18557
|
+
method: "POST",
|
|
18558
|
+
body: { path: path4, contentBase64: data.toString("base64") }
|
|
18559
|
+
}
|
|
18560
|
+
);
|
|
18561
|
+
}
|
|
18562
|
+
async request(path4, init) {
|
|
18563
|
+
const headers = {};
|
|
18564
|
+
if (init.body) {
|
|
18565
|
+
headers["content-type"] = "application/json";
|
|
18566
|
+
}
|
|
18567
|
+
if (this.apiKey) {
|
|
18568
|
+
headers.Authorization = `Bearer ${this.apiKey}`;
|
|
18569
|
+
}
|
|
18570
|
+
const response = await fetch(`${this.baseURL}${path4}`, {
|
|
18385
18571
|
method: init.method,
|
|
18386
|
-
headers:
|
|
18572
|
+
headers: Object.keys(headers).length > 0 ? headers : void 0,
|
|
18387
18573
|
body: init.body ? JSON.stringify(init.body) : void 0
|
|
18388
18574
|
});
|
|
18389
18575
|
if (!response.ok) {
|
|
18390
18576
|
throw new Error(`Microsandbox service request failed: ${response.status} ${response.statusText}`);
|
|
18391
18577
|
}
|
|
18392
18578
|
const payload = await response.json();
|
|
18579
|
+
if (payload?.success === false) {
|
|
18580
|
+
throw new Error(`Microsandbox service request failed: ${payload.error ?? "unsuccessful response envelope"}`);
|
|
18581
|
+
}
|
|
18582
|
+
if (payload?.success !== true || !("data" in payload)) {
|
|
18583
|
+
throw new Error("Microsandbox service returned an invalid success envelope");
|
|
18584
|
+
}
|
|
18393
18585
|
return payload.data;
|
|
18394
18586
|
}
|
|
18395
18587
|
};
|
|
18396
18588
|
|
|
18397
18589
|
// src/sandbox_lattice/providers/MicrosandboxRemoteProvider.ts
|
|
18398
|
-
|
|
18399
|
-
|
|
18400
|
-
|
|
18401
|
-
|
|
18402
|
-
}
|
|
18590
|
+
function parseOptionalNumberEnv(name, fallback) {
|
|
18591
|
+
const rawValue = process.env[name];
|
|
18592
|
+
if (rawValue === void 0) {
|
|
18593
|
+
return fallback;
|
|
18594
|
+
}
|
|
18595
|
+
const parsedValue = Number(rawValue);
|
|
18596
|
+
if (!Number.isFinite(parsedValue)) {
|
|
18597
|
+
throw new Error(`Invalid ${name} environment value: ${rawValue}`);
|
|
18598
|
+
}
|
|
18599
|
+
return parsedValue;
|
|
18600
|
+
}
|
|
18601
|
+
function getDefaultMicrosandboxRemoteConfig() {
|
|
18602
|
+
return {
|
|
18603
|
+
image: process.env.MICROSANDBOX_IMAGE ?? "daytona-cn-shanghai.cr.volces.com/daytona/sandbox:0.0.2",
|
|
18604
|
+
//"daytonaio/sandbox:0.6.0",
|
|
18605
|
+
cpus: parseOptionalNumberEnv("MICROSANDBOX_CPUS", 1),
|
|
18606
|
+
memoryMib: parseOptionalNumberEnv("MICROSANDBOX_MEMORY", 512),
|
|
18607
|
+
user: "root"
|
|
18608
|
+
};
|
|
18609
|
+
}
|
|
18403
18610
|
var MicrosandboxRemoteProvider = class {
|
|
18404
18611
|
constructor(config) {
|
|
18405
18612
|
this.config = config;
|
|
18406
18613
|
this.instances = /* @__PURE__ */ new Map();
|
|
18407
18614
|
this.creating = /* @__PURE__ */ new Map();
|
|
18408
18615
|
this.client = config.client ?? new MicrosandboxServiceClient({
|
|
18409
|
-
baseURL: config.baseURL
|
|
18616
|
+
baseURL: config.baseURL,
|
|
18617
|
+
apiKey: config.apiKey ?? process.env.MICROSANDBOX_API_KEY
|
|
18410
18618
|
});
|
|
18411
18619
|
}
|
|
18412
18620
|
async createSandbox(name, config) {
|
|
@@ -18425,9 +18633,14 @@ var MicrosandboxRemoteProvider = class {
|
|
|
18425
18633
|
return instance;
|
|
18426
18634
|
})();
|
|
18427
18635
|
this.creating.set(name, creation);
|
|
18428
|
-
creation.
|
|
18429
|
-
|
|
18430
|
-
|
|
18636
|
+
creation.then(
|
|
18637
|
+
() => {
|
|
18638
|
+
this.creating.delete(name);
|
|
18639
|
+
},
|
|
18640
|
+
() => {
|
|
18641
|
+
this.creating.delete(name);
|
|
18642
|
+
}
|
|
18643
|
+
);
|
|
18431
18644
|
return creation;
|
|
18432
18645
|
}
|
|
18433
18646
|
async getSandbox(name) {
|
|
@@ -18445,37 +18658,49 @@ var MicrosandboxRemoteProvider = class {
|
|
|
18445
18658
|
await this.client.deleteSandbox(name);
|
|
18446
18659
|
this.instances.delete(name);
|
|
18447
18660
|
}
|
|
18661
|
+
createVolumeFsClient(volumeName) {
|
|
18662
|
+
return {
|
|
18663
|
+
read: (path4) => this.client.volumeFsRead(volumeName, path4),
|
|
18664
|
+
write: (path4, content) => this.client.volumeFsWrite(volumeName, path4, content),
|
|
18665
|
+
list: (path4) => this.client.volumeFsList(volumeName, path4),
|
|
18666
|
+
readRaw: (path4) => this.client.volumeFsDownload(volumeName, path4),
|
|
18667
|
+
writeRaw: (path4, data) => this.client.volumeFsUpload(volumeName, path4, data)
|
|
18668
|
+
};
|
|
18669
|
+
}
|
|
18448
18670
|
async listSandboxes() {
|
|
18449
18671
|
return Array.from(this.instances.values());
|
|
18450
18672
|
}
|
|
18451
18673
|
buildEnsureInput(config) {
|
|
18674
|
+
const defaultMicrosandboxRemoteConfig = getDefaultMicrosandboxRemoteConfig();
|
|
18452
18675
|
return {
|
|
18453
18676
|
image: this.config.image ?? defaultMicrosandboxRemoteConfig.image,
|
|
18454
18677
|
cpus: this.config.cpus ?? defaultMicrosandboxRemoteConfig.cpus,
|
|
18455
18678
|
memoryMib: this.config.memoryMib ?? defaultMicrosandboxRemoteConfig.memoryMib,
|
|
18456
|
-
env:
|
|
18679
|
+
env: {
|
|
18680
|
+
...this.config.env,
|
|
18681
|
+
...buildSandboxMetadataEnv(config)
|
|
18682
|
+
},
|
|
18457
18683
|
volumes: config?.volumes ?? this.buildDefaultVolumes(config)
|
|
18458
18684
|
};
|
|
18459
18685
|
}
|
|
18460
18686
|
buildDefaultVolumes(config) {
|
|
18461
18687
|
const tenantId = config?.tenantId ?? "default";
|
|
18462
18688
|
const volumes = {
|
|
18463
|
-
"/home/
|
|
18689
|
+
"/home/daytona/.agents/skills": {
|
|
18464
18690
|
type: "named",
|
|
18465
|
-
name:
|
|
18691
|
+
name: buildNamedVolumeName("s", "skills", tenantId)
|
|
18466
18692
|
}
|
|
18467
18693
|
};
|
|
18468
18694
|
if (config?.assistant_id) {
|
|
18469
|
-
volumes["/home/
|
|
18695
|
+
volumes["/home/daytona/agent"] = {
|
|
18470
18696
|
type: "named",
|
|
18471
|
-
name:
|
|
18697
|
+
name: buildNamedVolumeName("a", "agent", tenantId, config.assistant_id)
|
|
18472
18698
|
};
|
|
18473
18699
|
}
|
|
18474
18700
|
if (config?.projectId) {
|
|
18475
|
-
|
|
18476
|
-
volumes["/home/microsandbox/project"] = {
|
|
18701
|
+
volumes["/home/daytona/project"] = {
|
|
18477
18702
|
type: "named",
|
|
18478
|
-
name:
|
|
18703
|
+
name: buildNamedVolumeName("p", "project", tenantId, config.workspaceId, config.projectId)
|
|
18479
18704
|
};
|
|
18480
18705
|
}
|
|
18481
18706
|
return volumes;
|
|
@@ -18503,9 +18728,9 @@ var RemoteSandboxInstance = class {
|
|
|
18503
18728
|
throw new Error(String(result.error));
|
|
18504
18729
|
}
|
|
18505
18730
|
},
|
|
18506
|
-
listPath: async (
|
|
18731
|
+
listPath: async (path4, options) => {
|
|
18507
18732
|
const result = await this.client.file.listPath({
|
|
18508
|
-
path:
|
|
18733
|
+
path: path4,
|
|
18509
18734
|
recursive: options?.recursive ?? false
|
|
18510
18735
|
});
|
|
18511
18736
|
if (!result.ok) {
|
|
@@ -18519,8 +18744,8 @@ var RemoteSandboxInstance = class {
|
|
|
18519
18744
|
}));
|
|
18520
18745
|
return { files };
|
|
18521
18746
|
},
|
|
18522
|
-
findFiles: async (
|
|
18523
|
-
const result = await this.client.file.findFiles({ path:
|
|
18747
|
+
findFiles: async (path4, glob) => {
|
|
18748
|
+
const result = await this.client.file.findFiles({ path: path4, glob });
|
|
18524
18749
|
if (!result.ok) {
|
|
18525
18750
|
throw new Error(String(result.error));
|
|
18526
18751
|
}
|
|
@@ -18657,8 +18882,8 @@ var E2BInstance = class {
|
|
|
18657
18882
|
writeFile: async (file, content) => {
|
|
18658
18883
|
await this.native.files.write(file, content);
|
|
18659
18884
|
},
|
|
18660
|
-
listPath: async (
|
|
18661
|
-
const entries = await this.native.files.list(
|
|
18885
|
+
listPath: async (path4, options) => {
|
|
18886
|
+
const entries = await this.native.files.list(path4);
|
|
18662
18887
|
const files = entries.map((e) => ({
|
|
18663
18888
|
path: e.path,
|
|
18664
18889
|
is_dir: e.type === "dir",
|
|
@@ -18667,9 +18892,9 @@ var E2BInstance = class {
|
|
|
18667
18892
|
}));
|
|
18668
18893
|
return { files };
|
|
18669
18894
|
},
|
|
18670
|
-
findFiles: async (
|
|
18895
|
+
findFiles: async (path4, glob) => {
|
|
18671
18896
|
const result = await this.native.commands.run(
|
|
18672
|
-
`find "${
|
|
18897
|
+
`find "${path4}" -name "${glob}" -type f`
|
|
18673
18898
|
);
|
|
18674
18899
|
const lines = result.stdout.split("\n").filter(Boolean);
|
|
18675
18900
|
return { files: lines };
|
|
@@ -18692,13 +18917,13 @@ var E2BInstance = class {
|
|
|
18692
18917
|
return { matches, line_numbers };
|
|
18693
18918
|
},
|
|
18694
18919
|
strReplaceEditor: async (params) => {
|
|
18695
|
-
const { path:
|
|
18920
|
+
const { path: path4, old_str, new_str, replace_mode } = params;
|
|
18696
18921
|
const delim = "#";
|
|
18697
18922
|
const escapedOld = old_str.replace(new RegExp(`[\\\\${delim}]`, "g"), "\\$&").replace(/\n/g, "\\n");
|
|
18698
18923
|
const escapedNew = new_str.replace(new RegExp(`[\\\\${delim}]`, "g"), "\\$&").replace(/\n/g, "\\n");
|
|
18699
18924
|
const flag = replace_mode === "ALL" ? "g" : "";
|
|
18700
18925
|
await this.native.commands.run(
|
|
18701
|
-
`sed -i 's${delim}${escapedOld}${delim}${escapedNew}${delim}${flag}' "${
|
|
18926
|
+
`sed -i 's${delim}${escapedOld}${delim}${escapedNew}${delim}${flag}' "${path4}"`
|
|
18702
18927
|
);
|
|
18703
18928
|
},
|
|
18704
18929
|
uploadFile: async (params) => {
|
|
@@ -18814,26 +19039,18 @@ var DaytonaInstance = class {
|
|
|
18814
19039
|
this.native = native;
|
|
18815
19040
|
this.file = {
|
|
18816
19041
|
readFile: async (file) => {
|
|
18817
|
-
const buffer2 = await this.native.fs.downloadFile(
|
|
19042
|
+
const buffer2 = await this.native.fs.downloadFile(toSandboxRelativePath(file));
|
|
18818
19043
|
return { content: buffer2.toString("utf-8") };
|
|
18819
19044
|
},
|
|
18820
19045
|
writeFile: async (file, content) => {
|
|
18821
|
-
await this.native.fs.uploadFile(Buffer.from(content, "utf-8"),
|
|
19046
|
+
await this.native.fs.uploadFile(Buffer.from(content, "utf-8"), toSandboxRelativePath(file));
|
|
18822
19047
|
},
|
|
18823
|
-
listPath: async (
|
|
18824
|
-
const entries = await this.native.fs.listFiles(
|
|
19048
|
+
listPath: async (path4, options) => {
|
|
19049
|
+
const entries = await this.native.fs.listFiles(toSandboxRelativePath(path4));
|
|
18825
19050
|
const files = entries.map((e) => {
|
|
18826
|
-
|
|
18827
|
-
while (name.startsWith("~/") || name.startsWith("/")) {
|
|
18828
|
-
if (name.startsWith("~/")) {
|
|
18829
|
-
name = name.slice(2);
|
|
18830
|
-
} else if (name.startsWith("/")) {
|
|
18831
|
-
name = name.slice(1);
|
|
18832
|
-
}
|
|
18833
|
-
}
|
|
18834
|
-
const fullPath = name ? `${path3}/${name}`.replace(/\/+/g, "/") : path3;
|
|
19051
|
+
const rawPath = e.name || "";
|
|
18835
19052
|
return {
|
|
18836
|
-
path:
|
|
19053
|
+
path: fromSandboxExecutionPath(rawPath),
|
|
18837
19054
|
is_dir: e.isDir ?? false,
|
|
18838
19055
|
size: e.size,
|
|
18839
19056
|
modified_at: e.modTime ? e.modTime : void 0
|
|
@@ -18841,12 +19058,12 @@ var DaytonaInstance = class {
|
|
|
18841
19058
|
});
|
|
18842
19059
|
return { files };
|
|
18843
19060
|
},
|
|
18844
|
-
findFiles: async (
|
|
18845
|
-
const result = await this.native.fs.searchFiles(
|
|
18846
|
-
return { files: result.files || [] };
|
|
19061
|
+
findFiles: async (path4, glob) => {
|
|
19062
|
+
const result = await this.native.fs.searchFiles(toSandboxRelativePath(path4), glob);
|
|
19063
|
+
return { files: (result.files || []).map((filePath) => fromSandboxExecutionPath(filePath)) };
|
|
18847
19064
|
},
|
|
18848
19065
|
searchInFile: async (file, regex) => {
|
|
18849
|
-
const matches = await this.native.fs.findFiles(
|
|
19066
|
+
const matches = await this.native.fs.findFiles(toSandboxRelativePath(file), regex);
|
|
18850
19067
|
const line_numbers = [];
|
|
18851
19068
|
const matchTexts = [];
|
|
18852
19069
|
for (const match of matches) {
|
|
@@ -18856,8 +19073,8 @@ var DaytonaInstance = class {
|
|
|
18856
19073
|
return { matches: matchTexts, line_numbers };
|
|
18857
19074
|
},
|
|
18858
19075
|
strReplaceEditor: async (params) => {
|
|
18859
|
-
const { path:
|
|
18860
|
-
const relPath =
|
|
19076
|
+
const { path: path4, old_str, new_str, replace_mode } = params;
|
|
19077
|
+
const relPath = toSandboxRelativePath(path4);
|
|
18861
19078
|
if (replace_mode === "ALL") {
|
|
18862
19079
|
await this.native.fs.replaceInFiles([relPath], old_str, new_str);
|
|
18863
19080
|
} else {
|
|
@@ -18871,10 +19088,10 @@ var DaytonaInstance = class {
|
|
|
18871
19088
|
}
|
|
18872
19089
|
},
|
|
18873
19090
|
uploadFile: async (params) => {
|
|
18874
|
-
await this.native.fs.uploadFile(params.data,
|
|
19091
|
+
await this.native.fs.uploadFile(params.data, toSandboxRelativePath(params.file));
|
|
18875
19092
|
},
|
|
18876
19093
|
downloadFile: async (params) => {
|
|
18877
|
-
const buffer2 = await this.native.fs.downloadFile(
|
|
19094
|
+
const buffer2 = await this.native.fs.downloadFile(toSandboxRelativePath(params.file));
|
|
18878
19095
|
return Buffer.isBuffer(buffer2) ? buffer2 : Buffer.from(buffer2);
|
|
18879
19096
|
}
|
|
18880
19097
|
};
|
|
@@ -18895,25 +19112,6 @@ var DaytonaInstance = class {
|
|
|
18895
19112
|
};
|
|
18896
19113
|
this.name = name;
|
|
18897
19114
|
}
|
|
18898
|
-
/**
|
|
18899
|
-
* All sandbox file operations live under the user's home directory (~).
|
|
18900
|
-
* The AI uses virtual paths like "~/agent/file.txt". Daytona SDK expects
|
|
18901
|
-
* relative paths for file operations (they are resolved against ~ automatically),
|
|
18902
|
-
* so we strip the leading "~/" or "/" here.
|
|
18903
|
-
*
|
|
18904
|
-
* Handles edge cases like "~/~/agent/file.txt" by repeatedly stripping prefixes.
|
|
18905
|
-
*/
|
|
18906
|
-
toSandboxHomePath(path3) {
|
|
18907
|
-
let result = path3;
|
|
18908
|
-
while (result.startsWith("~/") || result.startsWith("/")) {
|
|
18909
|
-
if (result.startsWith("~/")) {
|
|
18910
|
-
result = result.slice(2);
|
|
18911
|
-
} else if (result.startsWith("/")) {
|
|
18912
|
-
result = result.slice(1);
|
|
18913
|
-
}
|
|
18914
|
-
}
|
|
18915
|
-
return result;
|
|
18916
|
-
}
|
|
18917
19115
|
async start() {
|
|
18918
19116
|
await this.native.start();
|
|
18919
19117
|
}
|
|
@@ -19254,7 +19452,6 @@ function clearEncryptionKeyCache() {
|
|
|
19254
19452
|
export {
|
|
19255
19453
|
AGENT_TASK_EVENT,
|
|
19256
19454
|
Agent,
|
|
19257
|
-
AgentConfig,
|
|
19258
19455
|
AgentInstanceManager,
|
|
19259
19456
|
AgentLatticeManager,
|
|
19260
19457
|
AgentManager,
|
|
@@ -19273,7 +19470,6 @@ export {
|
|
|
19273
19470
|
EmbeddingsLatticeManager,
|
|
19274
19471
|
FileSystemSkillStore,
|
|
19275
19472
|
FilesystemBackend,
|
|
19276
|
-
GraphBuildOptions,
|
|
19277
19473
|
HumanMessage3 as HumanMessage,
|
|
19278
19474
|
InMemoryAssistantStore,
|
|
19279
19475
|
InMemoryChunkBuffer,
|
|
@@ -19327,9 +19523,12 @@ export {
|
|
|
19327
19523
|
ThreadStatus2 as ThreadStatus,
|
|
19328
19524
|
ToolLatticeManager,
|
|
19329
19525
|
VectorStoreLatticeManager,
|
|
19526
|
+
VolumeFilesystem,
|
|
19330
19527
|
agentInstanceManager,
|
|
19331
19528
|
agentLatticeManager,
|
|
19332
19529
|
buildGrepResultsDict,
|
|
19530
|
+
buildNamedVolumeName,
|
|
19531
|
+
buildSandboxMetadataEnv,
|
|
19333
19532
|
buildSkillFile,
|
|
19334
19533
|
checkEmptyContent,
|
|
19335
19534
|
clearEncryptionKeyCache,
|