@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.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
- throw new Error("MySQL support not yet implemented");
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.shell.execCommand({
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
- const deleteResult = await sandbox.shell.execCommand({
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 result = await this.client.file.readFile({ file });
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(String(result.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 result = await this.client.file.writeFile({ file, content });
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(String(result.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: path3,
21754
+ path: resolved,
21551
21755
  recursive: options?.recursive ?? false
21552
21756
  });
21553
21757
  if (!result.ok) {
21554
- throw new Error(String(result.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 ?? false,
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 result = await this.client.file.findFiles({ path: path3, glob });
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(String(result.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 result = await this.client.file.searchInFile({ file, regex });
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(String(result.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: params.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(String(result.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: params.file
21804
+ path: resolved
21597
21805
  });
21598
21806
  if (!result.ok) {
21599
- throw new Error(String(result.error));
21807
+ throw new Error(`uploadFile failed: ${extractFetcherError(result.error)}`);
21600
21808
  }
21601
21809
  },
21602
21810
  downloadFile: async (params) => {
21603
- const result = await this.client.file.downloadFile({ path: params.file });
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(String(result.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(String(result.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 instance = new RemoteSandboxInstance(name, this.client);
21664
- this.instances.set(name, instance);
21665
- return instance;
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
- const instance = this.instances.get(name);
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,