UNPKG

eve

Version:

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

2 lines 9.43 kB
import{resolveSandboxModelPath}from"#shared/skill-paths.js";import{WORKSPACE_ROOT}from"#runtime/workspace/types.js";import{streamToBuffer}from"#execution/sandbox/stream-utils.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{adaptMultiplexedCommandToSandboxProcess}from"#execution/sandbox/multiplexed-command.js";import{applyInitialVercelNetworkPolicy,createVercelNetworkPolicySetter,ensureVercelSandboxBaseRuntime,withBaseSetupNetworkPolicy}from"#execution/sandbox/bindings/vercel-base-runtime.js";import{createVercelEveImageSandbox}from"#execution/sandbox/bindings/vercel-create-sdk.js";import{ensureVercelSandboxTags,errorMessage,resolveVercelSandboxTags}from"#execution/sandbox/bindings/vercel-options.js";import{isVercelSandboxMissingError,isVercelSnapshotUnavailableError}from"#execution/sandbox/bindings/vercel-errors.js";import{getNamedVercelSandbox}from"#execution/sandbox/bindings/vercel-lookup.js";import{deleteUnusableVercelSandbox,deleteVercelSandbox,stopVercelSandbox}from"#execution/sandbox/bindings/vercel-lifecycle.js";import{normalizeVercelReadStream}from"#execution/sandbox/bindings/vercel-read-stream.js";function createVercelSandbox(e={}){let t=e.loadSandboxModule??(async()=>await import(`#compiled/@vercel/sandbox-drives/index.js`)),n=e.loadDeleteSandboxModule??(async()=>await import(`#compiled/@vercel/sandbox/index.js`)),r={timeout:DEFAULT_SANDBOX_TIMEOUT_MS,...e.createOptions},i=e.createSandbox??createVercelEveImageSandbox,a=new Map;return{name:`vercel`,async create(o){let s=resolveVercelSandboxTags(r.tags,o.tags),c=o.templateKey===null?null:await readTemplateForCreate({createOptions:r,loadSandboxModule:t,prewarmedTemplates:a,templateKey:o.templateKey}),l=await t(),u={createOptions:r,createSandbox:i,existingMetadata:o.existingMetadata,resolveSessionCreateOptions:e.resolveSessionCreateOptions,sandboxModule:l,sessionId:o.tags?.sessionId??o.sessionKey,sessionKey:o.sessionKey,snapshotId:c?.snapshotId,tags:s},d;try{d=await ensureSession(u)}catch(e){throw c!==null&&isVercelSnapshotUnavailableError(e)?(a.delete(c.templateKey),await(await getNamedVercelSandbox({createOptions:r,sandboxModule:l,sandboxName:c.sandboxName}))?.delete(),new SandboxTemplateNotProvisionedError({backendName:`vercel`,templateKey:c.templateKey})):Error(`Failed to create sandbox session "${o.sessionKey}": ${errorMessage(e)}`,{cause:e})}try{d=await ensureUsableSession({input:u,loadDeleteSandboxModule:n,session:d}),c===null&&d.created&&await applyInitialVercelNetworkPolicy(d.sandbox,r.networkPolicy)}catch(e){throw Error(`Failed to initialize sandbox session "${o.sessionKey}": ${errorMessage(e)}`,{cause:e})}return createHandle({createOptions:r,loadDeleteSandboxModule:n,sandbox:d.sandbox,sessionKey:o.sessionKey})},async prewarm(e){let n;try{n=await ensureTemplateWithUnavailableRetry({bootstrap:e.bootstrap,createOptions:r,createSandbox:i,loadSandboxModule:t,log:e.log,seedFiles:e.seedFiles,templateKey:e.templateKey})}catch(t){throw Error(`Failed to prewarm Vercel sandbox template "${e.templateKey}": ${errorMessage(t)}`,{cause:t})}return a.set(e.templateKey,n.template),{reused:n.reused}}}}async function ensureTemplateWithUnavailableRetry(e){try{return await ensureTemplate(e)}catch(t){if(!isVercelSnapshotUnavailableError(t)&&!isVercelSandboxMissingError(t))throw t;return e.log?.(`cached template disappeared; rebuilding sandbox template`),await ensureTemplate(e)}}async function readTemplate(e){let t=e.prewarmedTemplates.get(e.templateKey);if(t!==void 0)return t;let n=await e.loadSandboxModule(),r=await getNamedVercelSandbox({createOptions:e.createOptions,sandboxModule:n,sandboxName:e.templateKey});if(r===null||typeof r.currentSnapshotId!=`string`)throw new SandboxTemplateNotProvisionedError({backendName:`vercel`,templateKey:e.templateKey});return{sandboxName:r.name,snapshotId:r.currentSnapshotId,templateKey:e.templateKey}}async function readTemplateForCreate(e){try{return await readTemplate(e)}catch(t){throw SandboxTemplateNotProvisionedError.is(t)?t:Error(`Failed to read sandbox template "${e.templateKey}": ${errorMessage(t)}`,{cause:t})}}async function ensureTemplate(e){let t=await e.loadSandboxModule(),n=await getNamedVercelSandbox({createOptions:e.createOptions,sandboxModule:t,sandboxName:e.templateKey}),r=resolveVercelSandboxTags(e.createOptions.tags,e.tags),i=extractAuthorSnapshotId(e.createOptions);if(n!==null&&isUnprovisionedTerminalTemplateSandbox(n,i)&&(await n.delete(),n=null),n===null?n=await e.createSandbox({sandboxModule:t,createOptions:withBaseSetupNetworkPolicy({...e.createOptions,name:e.templateKey,persistent:!0,tags:r})}):await ensureVercelSandboxTags(n,r),typeof n.currentSnapshotId==`string`&&n.currentSnapshotId.length>0&&n.currentSnapshotId!==i)return{reused:!0,template:{sandboxName:n.name,snapshotId:n.currentSnapshotId,templateKey:e.templateKey}};e.log?.(`preparing base runtime inside sandbox`),await ensureVercelSandboxBaseRuntime(n),await applyInitialVercelNetworkPolicy(n,e.createOptions.networkPolicy);let a=buildSandboxSession(createVercelInternalSandboxSession(n,e.templateKey),createVercelNetworkPolicySetter(n));await writeVercelSandboxSeedFiles({sandbox:n,seedFiles:e.seedFiles,session:a}),e.bootstrap!==void 0&&(e.log?.(`running sandbox bootstrap`),await e.bootstrap({use:async t=>(t!==void 0&&await n.update(t),createLoggingSandboxSession({log:e.log,session:a}))}));let o=await n.snapshot();return{reused:!1,template:{sandboxName:n.name,snapshotId:o.snapshotId,templateKey:e.templateKey}}}async function ensureUsableSession(e){try{return await ensureVercelSandboxBaseRuntime(e.session.sandbox),e.session}catch(t){if(e.session.created||!isVercelSnapshotUnavailableError(t))throw t}await deleteUnusableVercelSandbox({createOptions:e.input.createOptions,loadDeleteSandboxModule:e.loadDeleteSandboxModule,sandbox:e.session.sandbox});let t=await ensureSession({...e.input,existingMetadata:void 0});return await ensureVercelSandboxBaseRuntime(t.sandbox),t}async function ensureSession(e){let t=getVercelSandboxName(e.existingMetadata)??e.sessionKey,n=await getNamedVercelSandbox({createOptions:e.createOptions,sandboxModule:e.sandboxModule,sandboxName:t});if(n!==null)return await ensureVercelSandboxTags(n,e.tags),{created:!1,sandbox:n};let r=createSessionCreateParams(e,t,await e.resolveSessionCreateOptions?.({session:{id:e.sessionId}}));return e.tags!==void 0&&(r.tags=e.tags),{created:!0,sandbox:await e.createSandbox({createOptions:r,sandboxModule:e.sandboxModule})}}function createSessionCreateParams(e,t,n={}){let r={...e.createOptions,...n};if(e.snapshotId===void 0)return withBaseSetupNetworkPolicy({...r,name:t,persistent:!0});let{image:i,runtime:a,source:o,...s}=r;return{...s,name:t,persistent:!0,source:{snapshotId:e.snapshotId,type:`snapshot`}}}function createHandle(e){let{sandbox:t,sessionKey:n}=e;return{session:buildSandboxSession(createVercelInternalSandboxSession(t,n),createVercelNetworkPolicySetter(t)),useSessionFn:async e=>(e!==void 0&&await t.update(e),buildSandboxSession(createVercelInternalSandboxSession(t,n),createVercelNetworkPolicySetter(t))),async captureState(){return{backendName:`vercel`,metadata:{sandboxName:t.name},sessionKey:n}},async delete(n){await deleteVercelSandbox({createOptions:e.createOptions,loadDeleteSandboxModule:e.loadDeleteSandboxModule,sandbox:t,signal:n?.abortSignal})},async stop(){await stopVercelSandbox(t)},async shutdown(){try{await stopVercelSandbox(t)}catch{}}}}function createVercelInternalSandboxSession(e,t){return{id:t,resolvePath:resolveVercelSandboxPath,async spawn(t){let n=await e.runCommand({args:[`-lc`,t.command],cmd:`bash`,cwd:t.workingDirectory??WORKSPACE_ROOT,detached:!0,env:t.env,signal:t.abortSignal});return adaptMultiplexedCommandToSandboxProcess({command:n,getOutput:e=>e.stream})},async readFile(t){return normalizeVercelReadStream(await e.readFile({path:t.path}))},async writeFile(t){let n=await streamToBuffer(t.content),r=await resolveVercelWritePath(e,t.path,t.abortSignal);await e.writeFiles([{content:n,path:r}],{signal:t.abortSignal})},async removePath(t){await e.fs.rm(t.path,{force:t.force,recursive:t.recursive,signal:t.abortSignal})}}}async function writeVercelSandboxSeedFiles(e){if(e.seedFiles.length===0)return;let t=await Promise.all(e.seedFiles.map(async t=>({content:typeof t.content==`string`?Buffer.from(t.content):t.content,path:await resolveSandboxModelPath({path:t.path,sandbox:e.session})})));await e.sandbox.writeFiles(t)}function resolveVercelSandboxPath(e){return e.startsWith(`/`)?e:`${WORKSPACE_ROOT}/${e}`}async function resolveVercelWritePath(e,t,n){let r=await e.runCommand({args:[`-m`,`--`,t],cmd:`realpath`,signal:n}),i=(await r.stdout()).trim();if(r.exitCode!==0||!i.startsWith(`/`)||i.includes(` `))throw Error(`Failed to resolve Vercel Sandbox write path: ${t}`);return i}function isUnprovisionedTerminalTemplateSandbox(e,t){let n=e.currentSnapshotId;return typeof n==`string`&&n.length>0&&n!==t?!1:e.status===`aborted`||e.status===`failed`||e.status===`stopped`}function extractAuthorSnapshotId(e){let t=e.source;if(t?.type===`snapshot`&&typeof t.snapshotId==`string`)return t.snapshotId}function getVercelSandboxName(e){let t=e?.sandboxName;return typeof t==`string`?t:void 0}const DEFAULT_SANDBOX_TIMEOUT_MS=18e5;export{createVercelSandbox};