UNPKG

eve

Version:

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

1 lines • 3.45 kB
import{createHash,randomUUID}from"node:crypto";import{access,mkdir,readFile,readdir,rename,rm,writeFile}from"node:fs/promises";import{dirname,join,relative}from"node:path";import{expectDockerSuccess}from"#execution/sandbox/bindings/docker-utils.js";async function materializeSandboxDockerfile(e){let t;try{t=await e.files.read(`Dockerfile`)}catch(e){if(e instanceof Error&&`code`in e&&e.code===`ENOENT`)return;throw e}let n=await e.files.list(),r=createHash(`sha256`),i=await Promise.all(n.map(async t=>({content:await e.files.read(t),path:t})));for(let e of i)r.update(e.path).update(`\0`).update(e.content).update(`\0`);let a=r.digest(`hex`),o=join(e.storagePath,`dockerfiles`,a);try{return await access(join(o,`Dockerfile`)),{contentHash:a,contextPath:o,path:join(o,`Dockerfile`)}}catch(e){if(!isFileNotFoundError(e))throw e}let s=`${o}.${randomUUID()}.tmp`;await Promise.all(i.map(async e=>{let t=join(s,e.path);await mkdir(dirname(t),{recursive:!0}),await writeFile(t,e.content)})),n.includes(`Dockerfile`)||(await mkdir(s,{recursive:!0}),await writeFile(join(s,`Dockerfile`),t)),await mkdir(dirname(o),{recursive:!0});try{await rename(s,o)}catch(e){try{await access(join(o,`Dockerfile`))}catch{throw e}}finally{await rm(s,{force:!0,recursive:!0})}return{contentHash:a,contextPath:o,path:join(o,`Dockerfile`)}}async function resolveSandboxDockerfile(e){let t=join(e,`sandbox`,`Dockerfile`);try{await readFile(t)}catch(e){if(isFileNotFoundError(e))return;throw e}let n=dirname(t);return{contextPath:n,contentHash:await hashDirectory(n),path:t}}function dockerfileImageReference(e){return`eve-sandbox-dockerfile:${createHash(`sha256`).update(`${e.templateKey}:${e.dockerfile.contentHash}`).digest(`hex`).slice(0,24)}`}async function buildSandboxDockerfile(e){expectDockerSuccess(await e.cli.run([`build`,`--file`,e.dockerfile.path,`--tag`,e.imageReference,e.dockerfile.contextPath]),`build sandbox Dockerfile "${e.dockerfile.path}"`)}const LOCAL_REGISTRY_CONTAINER=`eve-sandbox-registry`,LOCAL_REGISTRY_HOST=`127.0.0.1:51921`;async function publishDockerImageForMicrosandbox(e){let t=await e.cli.run([`container`,`inspect`,`--format`,`{{.State.Running}}`,LOCAL_REGISTRY_CONTAINER]);t.exitCode===0?t.stdout.trim()!==`true`&&expectDockerSuccess(await e.cli.run([`start`,LOCAL_REGISTRY_CONTAINER]),`restart the local microsandbox image registry`):expectDockerSuccess(await e.cli.run([`run`,`--detach`,`--name`,LOCAL_REGISTRY_CONTAINER,`--publish`,`${LOCAL_REGISTRY_HOST}:5000`,`registry:2`]),`start the local microsandbox image registry`);let n=`${LOCAL_REGISTRY_HOST}/eve/${e.imageReference.replace(`:`,`-`)}`;return expectDockerSuccess(await e.cli.run([`tag`,e.imageReference,n]),`tag microsandbox image "${n}"`),expectDockerSuccess(await e.cli.run([`push`,n]),`publish microsandbox image "${n}"`),n}function isFileNotFoundError(e){return e instanceof Error&&`code`in e&&e.code===`ENOENT`}async function hashDirectory(e){let t=createHash(`sha256`),n=await collectFilePaths(e);for(let r of n)t.update(relative(e,r)),t.update(`\0`),t.update(await readFile(r)),t.update(`\0`);return t.digest(`hex`)}async function collectFilePaths(e){let t=[];for(let n of await readdir(e,{withFileTypes:!0})){let r=join(e,n.name);n.isDirectory()?t.push(...await collectFilePaths(r)):n.isFile()&&t.push(r)}return t.sort()}export{buildSandboxDockerfile,dockerfileImageReference,materializeSandboxDockerfile,publishDockerImageForMicrosandbox,resolveSandboxDockerfile};