eve
Version:
Filesystem-first framework for durable backend AI agents that run anywhere.
1 lines • 3.9 kB
JavaScript
import{mkdir,readFile,rm,writeFile}from"node:fs/promises";import{dirname}from"node:path";import{WORKSPACE_ROOT}from"#runtime/workspace/types.js";import{createFileBackedInternalSandboxSession,pathExists}from"#execution/sandbox/bindings/local-provider-utils.js";import{shellQuote}from"#execution/sandbox/shell-quote.js";import{buildSandboxSession}from"#execution/sandbox/session.js";import{adaptMultiplexedCommandToSandboxProcess}from"#execution/sandbox/multiplexed-command.js";let justBashModulePromise;async function loadJustBashModule(e){return justBashModulePromise??=e.host.loadOptionalPackage({autoInstall:e.autoInstall,importModule:async()=>await import(`just-bash`),missingMessage:"The just-bash sandbox provider requires the `just-bash` package, which is not bundled with eve. Install it in your application (for example `pnpm add -D just-bash`), or use DockerSandbox or DefaultSandbox instead.",packageName:`just-bash`,ignoredOptionalDependencies:[`@mongodb-js/zstd`,`node-liblzma`]}).catch(e=>{throw justBashModulePromise=void 0,e}),await justBashModulePromise}async function createBashSandbox(e){let t=await loadJustBashModule({autoInstall:e.autoInstall,host:e.host}),{ReadWriteFs:n,Sandbox:r}=t,i=resolveLocalSandboxFilesystemRootPath(e.rootPath),a=resolveLocalSandboxMetadataPath(e.rootPath),o=await readLocalMetadata(a);await mkdir(i,{recursive:!0});let s=new n({allowSymlinks:!0,maxFileReadSize:2**53-1,root:i}),c=s;if(e.filesystem!==void 0)try{c=await e.filesystem({defaultFilesystem:s,resolveProjectPath:e.host.resolveProjectPath,storagePath:e.storagePath,justBash:t})}catch(e){throw Error(`Failed to create the custom just-bash filesystem.`,{cause:e})}await ensureLocalSandboxDirectories(c);let l=await r.create({cwd:WORKSPACE_ROOT,customCommands:e.customCommands===void 0?void 0:[...e.customCommands],env:o===null?void 0:{...o.env},fs:c,network:{dangerouslyAllowFullInternetAccess:!0}});return{async captureState(){return await writeLocalMetadata(a,{env:{...l.bashEnvInstance.getEnv()},version:1}),{rootPath:e.rootPath}},async dispose(){await l.stop()},async readFileBytes(e){let t;try{t=await c.readFileBuffer(e)}catch{return null}return Buffer.from(t)},async removePath(e){await c.rm(e.path,{force:e.force,recursive:e.recursive})},rootPath:e.rootPath,sessionKey:e.sessionKey,async spawn(e){if(e.abortSignal?.aborted)throw new DOMException(`The operation was aborted.`,`AbortError`);let t=e.workingDirectory===void 0?e.command:`( cd ${shellQuote(e.workingDirectory)} && ${e.command} )`,n=await l.runCommand({args:[t],cmd:`eval`,detached:!0,env:e.env,signal:e.abortSignal});return adaptMultiplexedCommandToSandboxProcess({command:n,getOutput:e=>e.type})},async writeFiles(e){for(let t of e){let e=dirname(t.path);await c.mkdir(e,{recursive:!0}),await c.writeFile(t.path,t.content)}}}}function createJustBashHandle(e){return{sandbox:buildSandboxSession(createFileBackedInternalSandboxSession({sandbox:e})),async onSessionDelete(){await e.dispose(),await rm(e.rootPath,{force:!0,recursive:!0})},async onSessionStop(){await e.dispose()},async onRuntimeShutdown(){await e.dispose()}}}function resolveLocalSandboxFilesystemRootPath(e){return`${e}/fs`}function resolveLocalSandboxMetadataPath(e){return`${e}/metadata.json`}async function ensureLocalSandboxDirectories(e){await e.mkdir(WORKSPACE_ROOT,{recursive:!0})}async function readLocalMetadata(e){if(!await pathExists(e))return null;let t=JSON.parse(await readFile(e,`utf8`));return!isRecord(t)||t.version!==1||!isStringRecord(t.env)?null:{env:t.env,version:1}}async function writeLocalMetadata(e,t){await mkdir(dirname(e),{recursive:!0}),await writeFile(e,`${JSON.stringify(t,null,2)}\n`)}function isRecord(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function isStringRecord(e){return typeof e==`object`&&!!e&&!Array.isArray(e)&&Object.values(e).every(e=>typeof e==`string`)}export{createBashSandbox,createJustBashHandle};