UNPKG

eve

Version:

Filesystem-first framework for durable backend AI agents that run anywhere.

1 lines 4.13 kB
import"node:fs";import{dirname,join}from"node:path";import{mkdir,readdir,rename,rm,stat}from"node:fs/promises";import{resolveSandboxCacheDirectory}from"#internal/application/paths.js";import{randomUUID}from"node:crypto";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(t={}){let r=t.createOptions?.autoInstall??!0;return{name:JUST_BASH_BACKEND_NAME,async prewarm(t){let a=resolveTemplateRootPath(resolveSandboxCacheDirectory(t.runtimeContext.appRoot),t.templateKey);if(await pathExists(a))return await touchDirectory(a),{reused:!0};let s=`${a}.${randomUUID()}.tmp`,u=!1,d=await createBashSandbox({appRoot:t.runtimeContext.appRoot,autoInstall:r,rootPath:s,sessionKey:t.templateKey}),f=buildSandboxSession(createFileBackedInternalSandboxSession({id:d.sessionKey,sandbox:d}),justBashSetNetworkPolicyUnsupported);try{if(t.bootstrap!==void 0&&(t.log?.(`running sandbox bootstrap`),await t.bootstrap({use:async()=>createLoggingSandboxSession({log:t.log,session:f})})),await writeSandboxSeedFiles(f,t.seedFiles),await d.captureState()===null)throw Error(`Failed to capture local sandbox template state for "${t.templateKey}".`);await mkdir(dirname(a),{recursive:!0});try{await rename(s,a),u=!0}catch(e){if(await pathExists(a))return{reused:!0};throw e}}finally{await d.dispose(),u||await rm(s,{force:!0,recursive:!0}).catch(()=>{})}return{reused:!1}},async create(e){let t=resolveSandboxCacheDirectory(e.runtimeContext.appRoot),i=getLocalRootPath(e.existingMetadata)??resolveSessionRootPath(t,e.sessionKey);if(!await pathExists(i))if(e.templateKey===null)await mkdir(i,{recursive:!0});else{let n=resolveTemplateRootPath(t,e.templateKey);if(!await pathExists(n))throw new SandboxTemplateNotProvisionedError({backendName:JUST_BASH_BACKEND_NAME,templateKey:e.templateKey});await copyDirectoryAtomically(n,i)}return createJustBashHandle(await createBashSandbox({appRoot:e.runtimeContext.appRoot,autoInstall:r,rootPath:i,sessionKey:e.sessionKey}),JUST_BASH_BACKEND_NAME)}}}async function pruneJustBashSandboxTemplates(e){let n=resolveLocalBackendTemplatesDirectory(resolveSandboxCacheDirectory(e.appRoot),JUST_BASH_CACHE_DIRECTORY_NAME),i=e.now??Date.now(),o=e.recentWindowMs??LOCAL_SANDBOX_TEMPLATE_RECENT_WINDOW_MS,s=e.retainCount??LOCAL_SANDBOX_TEMPLATE_RETAIN_COUNT,c;try{c=await readdir(n,{withFileTypes:!0})}catch(e){if(e instanceof Error&&`code`in e&&e.code===`ENOENT`)return;throw e}let l=await Promise.all(c.filter(e=>e.isDirectory()).map(async e=>{let r=join(n,e.name);return{isTemporary:e.name.endsWith(`.tmp`),mtimeMs:(await stat(r)).mtimeMs,path:r}})),u=selectStaleTemplateEntries(l.filter(e=>!e.isTemporary),{now:i,recentWindowMs:o,retainCount:s}),d=selectStaleTemplateEntries(l.filter(e=>e.isTemporary),{now:i,recentWindowMs:o,retainCount:0});await Promise.all([...u,...d].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};