@axiom-lattice/core 2.1.73 → 2.1.75
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 +33 -6
- package/dist/index.d.ts +33 -6
- package/dist/index.js +398 -39
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +396 -39
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -2
package/dist/index.js
CHANGED
|
@@ -79,6 +79,7 @@ __export(index_exports, {
|
|
|
79
79
|
MicrosandboxRemoteProvider: () => MicrosandboxRemoteProvider,
|
|
80
80
|
MicrosandboxServiceClient: () => MicrosandboxServiceClient,
|
|
81
81
|
ModelLatticeManager: () => ModelLatticeManager,
|
|
82
|
+
MysqlDatabase: () => MysqlDatabase,
|
|
82
83
|
PinoLoggerClient: () => PinoLoggerClient,
|
|
83
84
|
PostgresDatabase: () => PostgresDatabase,
|
|
84
85
|
PrometheusClient: () => PrometheusClient,
|
|
@@ -143,6 +144,7 @@ __export(index_exports, {
|
|
|
143
144
|
ensureBuiltinAgentsForTenant: () => ensureBuiltinAgentsForTenant,
|
|
144
145
|
eventBus: () => eventBus,
|
|
145
146
|
eventBusDefault: () => event_bus_default,
|
|
147
|
+
extractFetcherError: () => extractFetcherError,
|
|
146
148
|
fileDataToString: () => fileDataToString,
|
|
147
149
|
formatContentWithLineNumbers: () => formatContentWithLineNumbers,
|
|
148
150
|
formatGrepMatches: () => formatGrepMatches,
|
|
@@ -3284,6 +3286,168 @@ var PostgresDatabase = class {
|
|
|
3284
3286
|
}
|
|
3285
3287
|
}
|
|
3286
3288
|
};
|
|
3289
|
+
var MysqlDatabase = class {
|
|
3290
|
+
constructor(config) {
|
|
3291
|
+
// mysql2.Pool
|
|
3292
|
+
this.connected = false;
|
|
3293
|
+
this.config = config;
|
|
3294
|
+
}
|
|
3295
|
+
async connect() {
|
|
3296
|
+
if (this.connected && this.pool) return;
|
|
3297
|
+
try {
|
|
3298
|
+
const mysql = await import("mysql2/promise");
|
|
3299
|
+
const poolConfig = this.config.connectionString ? { uri: this.config.connectionString } : {
|
|
3300
|
+
host: this.config.host || "localhost",
|
|
3301
|
+
port: this.config.port || 3306,
|
|
3302
|
+
database: this.config.database,
|
|
3303
|
+
user: this.config.user,
|
|
3304
|
+
password: this.config.password,
|
|
3305
|
+
ssl: this.config.ssl ? { rejectUnauthorized: false } : void 0
|
|
3306
|
+
};
|
|
3307
|
+
this.pool = mysql.createPool({
|
|
3308
|
+
...poolConfig,
|
|
3309
|
+
waitForConnections: true,
|
|
3310
|
+
connectionLimit: 10,
|
|
3311
|
+
maxIdle: 10,
|
|
3312
|
+
idleTimeout: 6e4,
|
|
3313
|
+
queueLimit: 0,
|
|
3314
|
+
enableKeepAlive: true,
|
|
3315
|
+
keepAliveInitialDelay: 0
|
|
3316
|
+
});
|
|
3317
|
+
const connection = await this.pool.getConnection();
|
|
3318
|
+
try {
|
|
3319
|
+
await connection.query("SELECT 1");
|
|
3320
|
+
} finally {
|
|
3321
|
+
connection.release();
|
|
3322
|
+
}
|
|
3323
|
+
this.connected = true;
|
|
3324
|
+
} catch (error) {
|
|
3325
|
+
this.connected = false;
|
|
3326
|
+
throw new Error(`Failed to connect to MySQL: ${error}`);
|
|
3327
|
+
}
|
|
3328
|
+
}
|
|
3329
|
+
async disconnect() {
|
|
3330
|
+
if (this.pool) {
|
|
3331
|
+
try {
|
|
3332
|
+
await this.pool.end();
|
|
3333
|
+
} catch (error) {
|
|
3334
|
+
console.warn("Warning: Error closing MySQL pool:", error);
|
|
3335
|
+
} finally {
|
|
3336
|
+
this.pool = null;
|
|
3337
|
+
this.connected = false;
|
|
3338
|
+
}
|
|
3339
|
+
}
|
|
3340
|
+
}
|
|
3341
|
+
async listTables() {
|
|
3342
|
+
await this.ensureConnected();
|
|
3343
|
+
const query = `
|
|
3344
|
+
SELECT TABLE_NAME, TABLE_SCHEMA
|
|
3345
|
+
FROM information_schema.TABLES
|
|
3346
|
+
WHERE TABLE_SCHEMA NOT IN ('mysql', 'information_schema', 'performance_schema', 'sys')
|
|
3347
|
+
AND TABLE_SCHEMA = DATABASE()
|
|
3348
|
+
AND TABLE_TYPE = 'BASE TABLE'
|
|
3349
|
+
ORDER BY TABLE_SCHEMA, TABLE_NAME
|
|
3350
|
+
`;
|
|
3351
|
+
const [rows] = await this.pool.query(query);
|
|
3352
|
+
return rows.map((row) => ({
|
|
3353
|
+
name: row.TABLE_NAME,
|
|
3354
|
+
schema: row.TABLE_SCHEMA
|
|
3355
|
+
}));
|
|
3356
|
+
}
|
|
3357
|
+
async getTableInfo(tables) {
|
|
3358
|
+
await this.ensureConnected();
|
|
3359
|
+
const schemas = [];
|
|
3360
|
+
for (const tableName of tables) {
|
|
3361
|
+
const rawName = tableName.includes(".") ? tableName.split(".").pop() : tableName;
|
|
3362
|
+
const columnQuery = `
|
|
3363
|
+
SELECT
|
|
3364
|
+
c.COLUMN_NAME,
|
|
3365
|
+
c.DATA_TYPE,
|
|
3366
|
+
c.IS_NULLABLE,
|
|
3367
|
+
c.COLUMN_DEFAULT
|
|
3368
|
+
FROM information_schema.COLUMNS c
|
|
3369
|
+
WHERE c.TABLE_NAME = ?
|
|
3370
|
+
AND c.TABLE_SCHEMA = DATABASE()
|
|
3371
|
+
ORDER BY c.ORDINAL_POSITION
|
|
3372
|
+
`;
|
|
3373
|
+
const pkQuery = `
|
|
3374
|
+
SELECT k.COLUMN_NAME
|
|
3375
|
+
FROM information_schema.TABLE_CONSTRAINTS t
|
|
3376
|
+
JOIN information_schema.KEY_COLUMN_USAGE k
|
|
3377
|
+
ON t.CONSTRAINT_NAME = k.CONSTRAINT_NAME
|
|
3378
|
+
AND t.TABLE_SCHEMA = k.TABLE_SCHEMA
|
|
3379
|
+
AND t.TABLE_NAME = k.TABLE_NAME
|
|
3380
|
+
WHERE t.CONSTRAINT_TYPE = 'PRIMARY KEY'
|
|
3381
|
+
AND t.TABLE_NAME = ?
|
|
3382
|
+
AND t.TABLE_SCHEMA = DATABASE()
|
|
3383
|
+
`;
|
|
3384
|
+
const fkQuery = `
|
|
3385
|
+
SELECT
|
|
3386
|
+
k.COLUMN_NAME,
|
|
3387
|
+
k.REFERENCED_TABLE_NAME,
|
|
3388
|
+
k.REFERENCED_COLUMN_NAME
|
|
3389
|
+
FROM information_schema.KEY_COLUMN_USAGE k
|
|
3390
|
+
WHERE k.TABLE_NAME = ?
|
|
3391
|
+
AND k.TABLE_SCHEMA = DATABASE()
|
|
3392
|
+
AND k.REFERENCED_TABLE_NAME IS NOT NULL
|
|
3393
|
+
`;
|
|
3394
|
+
const [columnRows] = await this.pool.query(columnQuery, [rawName]);
|
|
3395
|
+
const [pkRows] = await this.pool.query(pkQuery, [rawName]);
|
|
3396
|
+
const [fkRows] = await this.pool.query(fkQuery, [rawName]);
|
|
3397
|
+
const pkColumns = new Set(pkRows.map((r) => r.COLUMN_NAME));
|
|
3398
|
+
const fkMap = /* @__PURE__ */ new Map();
|
|
3399
|
+
for (const row of fkRows) {
|
|
3400
|
+
fkMap.set(row.COLUMN_NAME, {
|
|
3401
|
+
foreignTable: row.REFERENCED_TABLE_NAME,
|
|
3402
|
+
foreignColumn: row.REFERENCED_COLUMN_NAME
|
|
3403
|
+
});
|
|
3404
|
+
}
|
|
3405
|
+
const columns = columnRows.map((row) => {
|
|
3406
|
+
const fkRef = fkMap.get(row.COLUMN_NAME);
|
|
3407
|
+
return {
|
|
3408
|
+
name: row.COLUMN_NAME,
|
|
3409
|
+
type: row.DATA_TYPE,
|
|
3410
|
+
nullable: row.IS_NULLABLE === "YES",
|
|
3411
|
+
default: row.COLUMN_DEFAULT,
|
|
3412
|
+
isPrimaryKey: pkColumns.has(row.COLUMN_NAME),
|
|
3413
|
+
isForeignKey: fkRef !== void 0,
|
|
3414
|
+
foreignKeyRef: fkRef ? `${fkRef.foreignTable}.${fkRef.foreignColumn}` : void 0
|
|
3415
|
+
};
|
|
3416
|
+
});
|
|
3417
|
+
let sampleRows = [];
|
|
3418
|
+
try {
|
|
3419
|
+
const sampleQuery = `SELECT * FROM \`${rawName}\` LIMIT 3`;
|
|
3420
|
+
const [sampleResult] = await this.pool.query(sampleQuery);
|
|
3421
|
+
sampleRows = sampleResult;
|
|
3422
|
+
} catch {
|
|
3423
|
+
}
|
|
3424
|
+
schemas.push({
|
|
3425
|
+
tableName,
|
|
3426
|
+
columns,
|
|
3427
|
+
sampleRows
|
|
3428
|
+
});
|
|
3429
|
+
}
|
|
3430
|
+
return schemas;
|
|
3431
|
+
}
|
|
3432
|
+
async executeQuery(query) {
|
|
3433
|
+
await this.ensureConnected();
|
|
3434
|
+
const [rows, fields] = await this.pool.query(query);
|
|
3435
|
+
const isSelectResult = Array.isArray(rows);
|
|
3436
|
+
return {
|
|
3437
|
+
rows: isSelectResult ? rows : [],
|
|
3438
|
+
rowCount: isSelectResult ? rows.length : rows.affectedRows || 0,
|
|
3439
|
+
fields: fields?.map((f) => f.name)
|
|
3440
|
+
};
|
|
3441
|
+
}
|
|
3442
|
+
getDatabaseType() {
|
|
3443
|
+
return "mysql";
|
|
3444
|
+
}
|
|
3445
|
+
async ensureConnected() {
|
|
3446
|
+
if (!this.connected) {
|
|
3447
|
+
await this.connect();
|
|
3448
|
+
}
|
|
3449
|
+
}
|
|
3450
|
+
};
|
|
3287
3451
|
var SqlDatabaseManager = class _SqlDatabaseManager {
|
|
3288
3452
|
constructor() {
|
|
3289
3453
|
this.databases = /* @__PURE__ */ new Map();
|
|
@@ -3323,7 +3487,8 @@ var SqlDatabaseManager = class _SqlDatabaseManager {
|
|
|
3323
3487
|
database = new PostgresDatabase(config);
|
|
3324
3488
|
break;
|
|
3325
3489
|
case "mysql":
|
|
3326
|
-
|
|
3490
|
+
database = new MysqlDatabase(config);
|
|
3491
|
+
break;
|
|
3327
3492
|
case "sqlite":
|
|
3328
3493
|
throw new Error("SQLite support not yet implemented");
|
|
3329
3494
|
default:
|
|
@@ -5858,7 +6023,7 @@ var SandboxLatticeManager = class _SandboxLatticeManager extends BaseLatticeMana
|
|
|
5858
6023
|
const tenantId = config.tenantId ?? "default";
|
|
5859
6024
|
const mapping = this._resolveVolumeForPath(config, tenantId, filePath);
|
|
5860
6025
|
if (!mapping) return null;
|
|
5861
|
-
const client = provider.createVolumeFsClient(mapping.volumeName);
|
|
6026
|
+
const client = provider.createVolumeFsClient(mapping.volumeName, mapping.pathPrefix);
|
|
5862
6027
|
return new VolumeFilesystem(stripPrefixClient(client, mapping.pathPrefix), mapping.pathPrefix);
|
|
5863
6028
|
}
|
|
5864
6029
|
_resolveVolumeForPath(config, tenantId, filePath) {
|
|
@@ -18233,9 +18398,7 @@ ${body}` : `${frontmatter}
|
|
|
18233
18398
|
} catch (listError) {
|
|
18234
18399
|
console.log(`[SandboxSkillStore] Skills directory not found, creating: ${skillsDir}`);
|
|
18235
18400
|
try {
|
|
18236
|
-
await sandbox.
|
|
18237
|
-
command: `mkdir -p /root/.agents/skills`
|
|
18238
|
-
});
|
|
18401
|
+
await sandbox.file.createDirectory(skillsDir);
|
|
18239
18402
|
} catch (mkdirError) {
|
|
18240
18403
|
console.error(`[SandboxSkillStore] Failed to create skills directory: ${mkdirError.message}`);
|
|
18241
18404
|
return [];
|
|
@@ -18376,12 +18539,7 @@ ${body}` : `${frontmatter}
|
|
|
18376
18539
|
try {
|
|
18377
18540
|
const sandbox = await this.getSandbox(tenantId, context);
|
|
18378
18541
|
const dirPath = this.getSkillDirectoryPath(tenantId, id);
|
|
18379
|
-
|
|
18380
|
-
command: `rm -rf ${dirPath}`
|
|
18381
|
-
});
|
|
18382
|
-
if (deleteResult.exit_code !== 0) {
|
|
18383
|
-
return false;
|
|
18384
|
-
}
|
|
18542
|
+
await sandbox.file.deletePath(dirPath);
|
|
18385
18543
|
return true;
|
|
18386
18544
|
} catch (error) {
|
|
18387
18545
|
console.error(`Error deleting skill ${id}:`, error);
|
|
@@ -21192,6 +21350,20 @@ var MicrosandboxRemoteInstance = class {
|
|
|
21192
21350
|
return Buffer.from(result.contentBase64, "base64");
|
|
21193
21351
|
}
|
|
21194
21352
|
return Buffer.from(result.content ?? "");
|
|
21353
|
+
},
|
|
21354
|
+
deletePath: async (path3) => {
|
|
21355
|
+
const resolved = normalizeExternalSandboxPath(path3);
|
|
21356
|
+
await this.client.execCommand({
|
|
21357
|
+
sandboxName: this.name,
|
|
21358
|
+
command: `rm -rf "${resolved}"`
|
|
21359
|
+
});
|
|
21360
|
+
},
|
|
21361
|
+
createDirectory: async (path3) => {
|
|
21362
|
+
const resolved = normalizeExternalSandboxPath(path3);
|
|
21363
|
+
await this.client.execCommand({
|
|
21364
|
+
sandboxName: this.name,
|
|
21365
|
+
command: `mkdir -p "${resolved}"`
|
|
21366
|
+
});
|
|
21195
21367
|
}
|
|
21196
21368
|
};
|
|
21197
21369
|
this.shell = {
|
|
@@ -21471,7 +21643,7 @@ var MicrosandboxRemoteProvider = class {
|
|
|
21471
21643
|
this.instances.delete(name);
|
|
21472
21644
|
await this.client.deleteSandbox(name);
|
|
21473
21645
|
}
|
|
21474
|
-
createVolumeFsClient(volumeName) {
|
|
21646
|
+
createVolumeFsClient(volumeName, _pathPrefix) {
|
|
21475
21647
|
return {
|
|
21476
21648
|
read: (path3) => this.client.volumeFsRead(volumeName, path3),
|
|
21477
21649
|
write: (path3, content) => this.client.volumeFsWrite(volumeName, path3, content),
|
|
@@ -21528,50 +21700,84 @@ var MicrosandboxRemoteProvider = class {
|
|
|
21528
21700
|
var import_sandbox23 = require("@agent-infra/sandbox");
|
|
21529
21701
|
|
|
21530
21702
|
// src/sandbox_lattice/RemoteSandboxInstance.ts
|
|
21703
|
+
function extractFetcherError(error) {
|
|
21704
|
+
if (typeof error === "string") {
|
|
21705
|
+
return error;
|
|
21706
|
+
}
|
|
21707
|
+
if (error && typeof error === "object") {
|
|
21708
|
+
const e = error;
|
|
21709
|
+
if (typeof e.reason === "string") {
|
|
21710
|
+
switch (e.reason) {
|
|
21711
|
+
case "status-code":
|
|
21712
|
+
return `HTTP ${e.statusCode}: ${JSON.stringify(e.body)}`;
|
|
21713
|
+
case "non-json":
|
|
21714
|
+
return `HTTP ${e.statusCode}: ${e.rawBody}`;
|
|
21715
|
+
case "timeout":
|
|
21716
|
+
return "Request timed out";
|
|
21717
|
+
case "unknown":
|
|
21718
|
+
return typeof e.errorMessage === "string" ? e.errorMessage : "Unknown error";
|
|
21719
|
+
}
|
|
21720
|
+
}
|
|
21721
|
+
if (typeof e.message === "string") {
|
|
21722
|
+
return e.message;
|
|
21723
|
+
}
|
|
21724
|
+
if (typeof e.error === "string") {
|
|
21725
|
+
return e.error;
|
|
21726
|
+
}
|
|
21727
|
+
return JSON.stringify(error);
|
|
21728
|
+
}
|
|
21729
|
+
return String(error);
|
|
21730
|
+
}
|
|
21531
21731
|
var RemoteSandboxInstance = class {
|
|
21532
|
-
constructor(name, client) {
|
|
21732
|
+
constructor(name, client, workspace) {
|
|
21533
21733
|
this.client = client;
|
|
21734
|
+
this.workspace = workspace;
|
|
21534
21735
|
this.file = {
|
|
21535
21736
|
readFile: async (file) => {
|
|
21536
|
-
const
|
|
21737
|
+
const resolved = this.resolvePath(file);
|
|
21738
|
+
const result = await this.client.file.readFile({ file: resolved });
|
|
21537
21739
|
if (!result.ok) {
|
|
21538
|
-
throw new Error(
|
|
21740
|
+
throw new Error(`readFile failed: ${extractFetcherError(result.error)}`);
|
|
21539
21741
|
}
|
|
21540
21742
|
return { content: result.body.data?.content ?? "" };
|
|
21541
21743
|
},
|
|
21542
21744
|
writeFile: async (file, content) => {
|
|
21543
|
-
const
|
|
21745
|
+
const resolved = this.resolvePath(file);
|
|
21746
|
+
const result = await this.client.file.writeFile({ file: resolved, content });
|
|
21544
21747
|
if (!result.ok) {
|
|
21545
|
-
throw new Error(
|
|
21748
|
+
throw new Error(`writeFile failed: ${extractFetcherError(result.error)}`);
|
|
21546
21749
|
}
|
|
21547
21750
|
},
|
|
21548
21751
|
listPath: async (path3, options) => {
|
|
21752
|
+
const resolved = this.resolvePath(path3);
|
|
21549
21753
|
const result = await this.client.file.listPath({
|
|
21550
|
-
path:
|
|
21754
|
+
path: resolved,
|
|
21551
21755
|
recursive: options?.recursive ?? false
|
|
21552
21756
|
});
|
|
21553
21757
|
if (!result.ok) {
|
|
21554
|
-
throw new Error(
|
|
21758
|
+
throw new Error(`listPath failed: ${extractFetcherError(result.error)}`);
|
|
21555
21759
|
}
|
|
21556
21760
|
const files = (result.body.data?.files || []).map((f) => ({
|
|
21557
21761
|
path: f.path,
|
|
21558
|
-
is_dir: f.is_dir
|
|
21559
|
-
size: f.size,
|
|
21762
|
+
is_dir: f.is_dir === true || f.size === null,
|
|
21763
|
+
size: f.size ?? void 0,
|
|
21560
21764
|
modified_at: f.modified_at
|
|
21561
21765
|
}));
|
|
21562
21766
|
return { files };
|
|
21563
21767
|
},
|
|
21564
21768
|
findFiles: async (path3, glob) => {
|
|
21565
|
-
const
|
|
21769
|
+
const resolved = this.resolvePath(path3);
|
|
21770
|
+
const result = await this.client.file.findFiles({ path: resolved, glob });
|
|
21566
21771
|
if (!result.ok) {
|
|
21567
|
-
throw new Error(
|
|
21772
|
+
throw new Error(`findFiles failed: ${extractFetcherError(result.error)}`);
|
|
21568
21773
|
}
|
|
21569
21774
|
return { files: result.body.data?.files || [] };
|
|
21570
21775
|
},
|
|
21571
21776
|
searchInFile: async (file, regex) => {
|
|
21572
|
-
const
|
|
21777
|
+
const resolved = this.resolvePath(file);
|
|
21778
|
+
const result = await this.client.file.searchInFile({ file: resolved, regex });
|
|
21573
21779
|
if (!result.ok) {
|
|
21574
|
-
throw new Error(
|
|
21780
|
+
throw new Error(`searchInFile failed: ${extractFetcherError(result.error)}`);
|
|
21575
21781
|
}
|
|
21576
21782
|
return {
|
|
21577
21783
|
matches: result.body.data?.matches || [],
|
|
@@ -21579,44 +21785,65 @@ var RemoteSandboxInstance = class {
|
|
|
21579
21785
|
};
|
|
21580
21786
|
},
|
|
21581
21787
|
strReplaceEditor: async (params) => {
|
|
21788
|
+
const resolved = this.resolvePath(params.path);
|
|
21582
21789
|
const result = await this.client.file.strReplaceEditor({
|
|
21583
21790
|
command: params.command,
|
|
21584
|
-
path:
|
|
21791
|
+
path: resolved,
|
|
21585
21792
|
old_str: params.old_str,
|
|
21586
21793
|
new_str: params.new_str,
|
|
21587
21794
|
replace_mode: params.replace_mode
|
|
21588
21795
|
});
|
|
21589
21796
|
if (!result.ok) {
|
|
21590
|
-
throw new Error(
|
|
21797
|
+
throw new Error(`strReplaceEditor failed: ${extractFetcherError(result.error)}`);
|
|
21591
21798
|
}
|
|
21592
21799
|
},
|
|
21593
21800
|
uploadFile: async (params) => {
|
|
21801
|
+
const resolved = this.resolvePath(params.file);
|
|
21594
21802
|
const result = await this.client.file.uploadFile({
|
|
21595
21803
|
file: params.data,
|
|
21596
|
-
path:
|
|
21804
|
+
path: resolved
|
|
21597
21805
|
});
|
|
21598
21806
|
if (!result.ok) {
|
|
21599
|
-
throw new Error(
|
|
21807
|
+
throw new Error(`uploadFile failed: ${extractFetcherError(result.error)}`);
|
|
21600
21808
|
}
|
|
21601
21809
|
},
|
|
21602
21810
|
downloadFile: async (params) => {
|
|
21603
|
-
const
|
|
21811
|
+
const resolved = this.resolvePath(params.file);
|
|
21812
|
+
const result = await this.client.file.downloadFile({ path: resolved });
|
|
21604
21813
|
if (!result.ok) {
|
|
21605
|
-
throw new Error(
|
|
21814
|
+
throw new Error(`downloadFile failed: ${extractFetcherError(result.error)}`);
|
|
21606
21815
|
}
|
|
21607
21816
|
const buffer2 = await result.body.arrayBuffer();
|
|
21608
21817
|
return Buffer.from(buffer2);
|
|
21818
|
+
},
|
|
21819
|
+
deletePath: async (path3) => {
|
|
21820
|
+
const resolved = this.resolvePath(path3);
|
|
21821
|
+
const result = await this.client.shell.execCommand({
|
|
21822
|
+
command: `rm -rf "${resolved}"`
|
|
21823
|
+
});
|
|
21824
|
+
if (!result.ok) {
|
|
21825
|
+
throw new Error(`deletePath failed: ${extractFetcherError(result.error)}`);
|
|
21826
|
+
}
|
|
21827
|
+
},
|
|
21828
|
+
createDirectory: async (path3) => {
|
|
21829
|
+
const resolved = this.resolvePath(path3);
|
|
21830
|
+
const result = await this.client.shell.execCommand({
|
|
21831
|
+
command: `mkdir -p "${resolved}"`
|
|
21832
|
+
});
|
|
21833
|
+
if (!result.ok) {
|
|
21834
|
+
throw new Error(`createDirectory failed: ${extractFetcherError(result.error)}`);
|
|
21835
|
+
}
|
|
21609
21836
|
}
|
|
21610
21837
|
};
|
|
21611
21838
|
this.shell = {
|
|
21612
21839
|
execCommand: async (params) => {
|
|
21613
21840
|
const result = await this.client.shell.execCommand({
|
|
21614
21841
|
command: params.command,
|
|
21615
|
-
exec_dir: params.exec_dir,
|
|
21842
|
+
exec_dir: params.exec_dir ? this.resolvePath(params.exec_dir) : void 0,
|
|
21616
21843
|
timeout: params.timeout
|
|
21617
21844
|
});
|
|
21618
21845
|
if (!result.ok) {
|
|
21619
|
-
throw new Error(
|
|
21846
|
+
throw new Error(`execCommand failed: ${extractFetcherError(result.error)}`);
|
|
21620
21847
|
}
|
|
21621
21848
|
return {
|
|
21622
21849
|
output: result.body.data?.output ?? "",
|
|
@@ -21626,6 +21853,15 @@ var RemoteSandboxInstance = class {
|
|
|
21626
21853
|
};
|
|
21627
21854
|
this.name = name;
|
|
21628
21855
|
}
|
|
21856
|
+
resolvePath(file) {
|
|
21857
|
+
if (file.startsWith(this.workspace)) {
|
|
21858
|
+
return file;
|
|
21859
|
+
}
|
|
21860
|
+
if (!file.startsWith("/")) {
|
|
21861
|
+
return `${this.workspace}/${file}`;
|
|
21862
|
+
}
|
|
21863
|
+
return `${this.workspace}${file}`;
|
|
21864
|
+
}
|
|
21629
21865
|
async start() {
|
|
21630
21866
|
}
|
|
21631
21867
|
async stop() {
|
|
@@ -21646,23 +21882,58 @@ var RemoteSandboxInstance = class {
|
|
|
21646
21882
|
};
|
|
21647
21883
|
|
|
21648
21884
|
// src/sandbox_lattice/providers/RemoteSandboxProvider.ts
|
|
21885
|
+
var DEFAULT_WORKSPACE = "/home/gem";
|
|
21649
21886
|
var RemoteSandboxProvider = class {
|
|
21650
21887
|
constructor(config) {
|
|
21651
21888
|
this.config = config;
|
|
21652
21889
|
this.instances = /* @__PURE__ */ new Map();
|
|
21890
|
+
this.creating = /* @__PURE__ */ new Map();
|
|
21891
|
+
this.workspace = DEFAULT_WORKSPACE;
|
|
21892
|
+
this.workspaceResolved = false;
|
|
21653
21893
|
this.client = new import_sandbox23.SandboxClient({
|
|
21654
21894
|
baseUrl: config.baseURL,
|
|
21655
21895
|
environment: ""
|
|
21656
21896
|
});
|
|
21657
21897
|
}
|
|
21898
|
+
async resolveWorkspace() {
|
|
21899
|
+
if (this.workspaceResolved) {
|
|
21900
|
+
return this.workspace;
|
|
21901
|
+
}
|
|
21902
|
+
try {
|
|
21903
|
+
const result = await this.client.sandbox.getContext();
|
|
21904
|
+
if (result.ok && result.body.home_dir) {
|
|
21905
|
+
this.workspace = result.body.home_dir;
|
|
21906
|
+
}
|
|
21907
|
+
} catch {
|
|
21908
|
+
}
|
|
21909
|
+
this.workspaceResolved = true;
|
|
21910
|
+
return this.workspace;
|
|
21911
|
+
}
|
|
21658
21912
|
async createSandbox(name, _config) {
|
|
21659
21913
|
const existing = this.instances.get(name);
|
|
21660
21914
|
if (existing) {
|
|
21661
21915
|
return existing;
|
|
21662
21916
|
}
|
|
21663
|
-
const
|
|
21664
|
-
|
|
21665
|
-
|
|
21917
|
+
const inFlight = this.creating.get(name);
|
|
21918
|
+
if (inFlight) {
|
|
21919
|
+
return inFlight;
|
|
21920
|
+
}
|
|
21921
|
+
const creation = (async () => {
|
|
21922
|
+
const workspace = await this.resolveWorkspace();
|
|
21923
|
+
const instance = new RemoteSandboxInstance(name, this.client, workspace);
|
|
21924
|
+
this.instances.set(name, instance);
|
|
21925
|
+
return instance;
|
|
21926
|
+
})();
|
|
21927
|
+
this.creating.set(name, creation);
|
|
21928
|
+
creation.then(
|
|
21929
|
+
() => {
|
|
21930
|
+
this.creating.delete(name);
|
|
21931
|
+
},
|
|
21932
|
+
() => {
|
|
21933
|
+
this.creating.delete(name);
|
|
21934
|
+
}
|
|
21935
|
+
);
|
|
21936
|
+
return creation;
|
|
21666
21937
|
}
|
|
21667
21938
|
async getSandbox(name) {
|
|
21668
21939
|
const instance = this.instances.get(name);
|
|
@@ -21672,9 +21943,7 @@ var RemoteSandboxProvider = class {
|
|
|
21672
21943
|
return instance;
|
|
21673
21944
|
}
|
|
21674
21945
|
async stopSandbox(name) {
|
|
21675
|
-
|
|
21676
|
-
if (instance) {
|
|
21677
|
-
}
|
|
21946
|
+
this.instances.delete(name);
|
|
21678
21947
|
}
|
|
21679
21948
|
async deleteSandbox(name) {
|
|
21680
21949
|
this.instances.delete(name);
|
|
@@ -21682,6 +21951,82 @@ var RemoteSandboxProvider = class {
|
|
|
21682
21951
|
async listSandboxes() {
|
|
21683
21952
|
return Array.from(this.instances.values());
|
|
21684
21953
|
}
|
|
21954
|
+
createVolumeFsClient(_volumeName, pathPrefix) {
|
|
21955
|
+
const workspace = this.workspace;
|
|
21956
|
+
const resolve3 = (p) => {
|
|
21957
|
+
if (!p || p === "/") {
|
|
21958
|
+
if (pathPrefix) {
|
|
21959
|
+
return `${workspace}${pathPrefix}`;
|
|
21960
|
+
}
|
|
21961
|
+
return workspace;
|
|
21962
|
+
}
|
|
21963
|
+
if (p.startsWith(workspace)) {
|
|
21964
|
+
return p;
|
|
21965
|
+
}
|
|
21966
|
+
if (p.startsWith("/")) {
|
|
21967
|
+
return `${workspace}${p}`;
|
|
21968
|
+
}
|
|
21969
|
+
if (pathPrefix) {
|
|
21970
|
+
const mountDir = pathPrefix.replace(/^\//, "");
|
|
21971
|
+
return `${workspace}/${mountDir}/${p}`;
|
|
21972
|
+
}
|
|
21973
|
+
return `${workspace}/${p}`;
|
|
21974
|
+
};
|
|
21975
|
+
return {
|
|
21976
|
+
read: async (path3) => {
|
|
21977
|
+
const resolved = resolve3(path3);
|
|
21978
|
+
const result = await this.client.file.readFile({ file: resolved });
|
|
21979
|
+
if (!result.ok) {
|
|
21980
|
+
throw new Error(`Volume read failed: ${extractFetcherError(result.error)}`);
|
|
21981
|
+
}
|
|
21982
|
+
return result.body.data?.content ?? "";
|
|
21983
|
+
},
|
|
21984
|
+
write: async (path3, content) => {
|
|
21985
|
+
const resolved = resolve3(path3);
|
|
21986
|
+
const result = await this.client.file.writeFile({ file: resolved, content });
|
|
21987
|
+
if (!result.ok) {
|
|
21988
|
+
throw new Error(`Volume write failed: ${extractFetcherError(result.error)}`);
|
|
21989
|
+
}
|
|
21990
|
+
},
|
|
21991
|
+
list: async (path3) => {
|
|
21992
|
+
const resolved = resolve3(path3);
|
|
21993
|
+
const result = await this.client.file.listPath({
|
|
21994
|
+
path: resolved,
|
|
21995
|
+
recursive: false
|
|
21996
|
+
});
|
|
21997
|
+
if (!result.ok) {
|
|
21998
|
+
throw new Error(`Volume list failed: ${extractFetcherError(result.error)}`);
|
|
21999
|
+
}
|
|
22000
|
+
const entries = (result.body.data?.files || []).map((f) => ({
|
|
22001
|
+
path: f.path.startsWith(workspace) ? f.path.slice(workspace.length) : f.path,
|
|
22002
|
+
kind: f.is_dir === true || f.size === null ? "directory" : "file",
|
|
22003
|
+
size: f.size ?? 0,
|
|
22004
|
+
mode: 0,
|
|
22005
|
+
modified: f.modified_at ?? null
|
|
22006
|
+
}));
|
|
22007
|
+
return entries;
|
|
22008
|
+
},
|
|
22009
|
+
readRaw: async (path3) => {
|
|
22010
|
+
const resolved = resolve3(path3);
|
|
22011
|
+
const result = await this.client.file.downloadFile({ path: resolved });
|
|
22012
|
+
if (!result.ok) {
|
|
22013
|
+
throw new Error(`Volume download failed: ${extractFetcherError(result.error)}`);
|
|
22014
|
+
}
|
|
22015
|
+
const buffer2 = await result.body.arrayBuffer();
|
|
22016
|
+
return Buffer.from(buffer2);
|
|
22017
|
+
},
|
|
22018
|
+
writeRaw: async (path3, data) => {
|
|
22019
|
+
const resolved = resolve3(path3);
|
|
22020
|
+
const result = await this.client.file.uploadFile({
|
|
22021
|
+
file: data,
|
|
22022
|
+
path: resolved
|
|
22023
|
+
});
|
|
22024
|
+
if (!result.ok) {
|
|
22025
|
+
throw new Error(`Volume upload failed: ${extractFetcherError(result.error)}`);
|
|
22026
|
+
}
|
|
22027
|
+
}
|
|
22028
|
+
};
|
|
22029
|
+
}
|
|
21685
22030
|
};
|
|
21686
22031
|
|
|
21687
22032
|
// src/sandbox_lattice/providers/E2BProvider.ts
|
|
@@ -21751,6 +22096,12 @@ var E2BInstance = class {
|
|
|
21751
22096
|
downloadFile: async (params) => {
|
|
21752
22097
|
const data = await this.native.files.read(params.file, { format: "bytes" });
|
|
21753
22098
|
return Buffer.isBuffer(data) ? data : Buffer.from(data);
|
|
22099
|
+
},
|
|
22100
|
+
deletePath: async (path3) => {
|
|
22101
|
+
await this.native.commands.run(`rm -rf "${path3}"`);
|
|
22102
|
+
},
|
|
22103
|
+
createDirectory: async (path3) => {
|
|
22104
|
+
await this.native.commands.run(`mkdir -p "${path3}"`);
|
|
21754
22105
|
}
|
|
21755
22106
|
};
|
|
21756
22107
|
this.shell = {
|
|
@@ -21917,6 +22268,12 @@ var DaytonaInstance = class {
|
|
|
21917
22268
|
downloadFile: async (params) => {
|
|
21918
22269
|
const buffer2 = await this.native.fs.downloadFile(toRelativePath(params.file));
|
|
21919
22270
|
return Buffer.isBuffer(buffer2) ? buffer2 : Buffer.from(buffer2);
|
|
22271
|
+
},
|
|
22272
|
+
deletePath: async (path3) => {
|
|
22273
|
+
await this.native.process.executeCommand(`rm -rf "${toRelativePath(path3)}"`, void 0, void 0);
|
|
22274
|
+
},
|
|
22275
|
+
createDirectory: async (path3) => {
|
|
22276
|
+
await this.native.process.executeCommand(`mkdir -p "${toRelativePath(path3)}"`, void 0, void 0);
|
|
21920
22277
|
}
|
|
21921
22278
|
};
|
|
21922
22279
|
this.shell = {
|
|
@@ -22323,6 +22680,7 @@ function clearEncryptionKeyCache() {
|
|
|
22323
22680
|
MicrosandboxRemoteProvider,
|
|
22324
22681
|
MicrosandboxServiceClient,
|
|
22325
22682
|
ModelLatticeManager,
|
|
22683
|
+
MysqlDatabase,
|
|
22326
22684
|
PinoLoggerClient,
|
|
22327
22685
|
PostgresDatabase,
|
|
22328
22686
|
PrometheusClient,
|
|
@@ -22387,6 +22745,7 @@ function clearEncryptionKeyCache() {
|
|
|
22387
22745
|
ensureBuiltinAgentsForTenant,
|
|
22388
22746
|
eventBus,
|
|
22389
22747
|
eventBusDefault,
|
|
22748
|
+
extractFetcherError,
|
|
22390
22749
|
fileDataToString,
|
|
22391
22750
|
formatContentWithLineNumbers,
|
|
22392
22751
|
formatGrepMatches,
|