eve
Version:
Filesystem-first framework for durable backend AI agents that run anywhere.
1 lines • 4.23 kB
JavaScript
import{randomUUID}from"node:crypto";import{mkdir,readdir,rename,rm,stat}from"node:fs/promises";import{dirname,join}from"node:path";import"node:fs";import{resolveSandboxCacheDirectory}from"#internal/application/paths.js";import{copyDirectoryAtomically,createFileBackedInternalSandboxSession,pathExists,resolveLocalBackendSessionRootPath,resolveLocalBackendTemplateRootPath,resolveLocalBackendTemplatesDirectory,touchDirectory,writeSandboxSeedFiles}from"#execution/sandbox/bindings/local-backend-utils.js";import{LOCAL_SANDBOX_TEMPLATE_RECENT_WINDOW_MS,LOCAL_SANDBOX_TEMPLATE_RETAIN_COUNT,selectStaleTemplateEntries}from"#execution/sandbox/bindings/local-template-prune.js";import{createLoggingSandboxSession}from"#execution/sandbox/logging-session.js";import{buildSandboxSession}from"#execution/sandbox/session.js";import{SandboxTemplateNotProvisionedError}from"#public/definitions/sandbox-backend.js";import{createBashSandbox,createJustBashHandle,justBashSetNetworkPolicyUnsupported}from"#execution/sandbox/bindings/just-bash-runtime.js";const JUST_BASH_CACHE_DIRECTORY_NAME=`just-bash`,JUST_BASH_BACKEND_NAME=`just-bash`;function createJustBashSandboxBackend(e={}){let t=e.createOptions?.autoInstall??!0,n=e.createOptions?.customCommands,r=e.createOptions?.filesystem;return{name:JUST_BASH_BACKEND_NAME,async prewarm(e){let n=resolveTemplateRootPath(resolveSandboxCacheDirectory(e.runtimeContext.appRoot),e.templateKey);if(await pathExists(n))return await touchDirectory(n),{reused:!0};let r=`${n}.${randomUUID()}.tmp`,i=!1,a=await createBashSandbox({appRoot:e.runtimeContext.appRoot,autoInstall:t,rootPath:r,sessionKey:e.templateKey}),o=buildSandboxSession(createFileBackedInternalSandboxSession({id:a.sessionKey,sandbox:a}),justBashSetNetworkPolicyUnsupported);try{if(await writeSandboxSeedFiles(o,e.seedFiles),e.bootstrap!==void 0&&(e.log?.(`running sandbox bootstrap`),await e.bootstrap({use:async()=>createLoggingSandboxSession({log:e.log,session:o})})),await a.captureState()===null)throw Error(`Failed to capture local sandbox template state for "${e.templateKey}".`);await mkdir(dirname(n),{recursive:!0});try{await rename(r,n),i=!0}catch(e){if(await pathExists(n))return{reused:!0};throw e}}finally{await a.dispose(),i||await rm(r,{force:!0,recursive:!0}).catch(()=>{})}return{reused:!1}},async create(e){let i=resolveSandboxCacheDirectory(e.runtimeContext.appRoot),a=getLocalRootPath(e.existingMetadata)??resolveSessionRootPath(i,e.sessionKey);if(!await pathExists(a)){if(e.templateKey===null)await mkdir(a,{recursive:!0});else{let t=resolveTemplateRootPath(i,e.templateKey);if(!await pathExists(t))throw new SandboxTemplateNotProvisionedError({backendName:JUST_BASH_BACKEND_NAME,templateKey:e.templateKey});await copyDirectoryAtomically(t,a)}}let o=await createBashSandbox({appRoot:e.runtimeContext.appRoot,autoInstall:t,customCommands:n,filesystem:r,rootPath:a,sessionKey:e.sessionKey});return createJustBashHandle(o,JUST_BASH_BACKEND_NAME)}}}async function pruneJustBashSandboxTemplates(e){let t=resolveLocalBackendTemplatesDirectory(resolveSandboxCacheDirectory(e.appRoot),JUST_BASH_CACHE_DIRECTORY_NAME),n=e.now??Date.now(),r=e.recentWindowMs??LOCAL_SANDBOX_TEMPLATE_RECENT_WINDOW_MS,i=e.retainCount??LOCAL_SANDBOX_TEMPLATE_RETAIN_COUNT,a;try{a=await readdir(t,{withFileTypes:!0})}catch(e){if(e instanceof Error&&`code`in e&&e.code===`ENOENT`)return;throw e}let o=await Promise.all(a.filter(e=>e.isDirectory()).map(async e=>{let n=join(t,e.name);return{isTemporary:e.name.endsWith(`.tmp`),mtimeMs:(await stat(n)).mtimeMs,path:n}})),s=selectStaleTemplateEntries(o.filter(e=>!e.isTemporary),{now:n,recentWindowMs:r,retainCount:i}),c=selectStaleTemplateEntries(o.filter(e=>e.isTemporary),{now:n,recentWindowMs:r,retainCount:0});await Promise.all([...s,...c].map(async e=>await rm(e.path,{force:!0,recursive:!0})))}function resolveTemplateRootPath(e,t){return resolveLocalBackendTemplateRootPath(e,JUST_BASH_CACHE_DIRECTORY_NAME,t)}function resolveSessionRootPath(e,t){return resolveLocalBackendSessionRootPath(e,JUST_BASH_CACHE_DIRECTORY_NAME,t)}function getLocalRootPath(e){let t=e?.rootPath;return typeof t==`string`?t:void 0}export{JUST_BASH_BACKEND_NAME,createJustBashSandboxBackend,pruneJustBashSandboxTemplates};