@evolvingmachines/e2b 0.0.59-train-2026-09-16-fs.20260917.41a409fa → 0.0.60

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1,8 +1,8 @@
1
- 'use strict';var codeInterpreter=require('@e2b/code-interpreter'),compareVersions=require('compare-versions');require('fs');var x=class extends Error{feature;provider;reason;constructor(e,t,n){super(`${t} does not support ${e}${n?`: ${n}`:""}`),this.name="SandboxFeatureUnsupportedError",this.feature=e,this.provider=t,this.reason=n;}},m=class extends Error{path;provider;constructor(e,t){super(`${t}: no such file or directory: ${e}`),this.name="SandboxPathNotFoundError",this.path=e,this.provider=t;}},g=class extends Error{sandboxId;provider;state;constructor(e,t,n){super(`${t} sandbox ${e} is not running (${n}); inspect never starts or resumes a sandbox`),this.name="SandboxNotRunningError",this.sandboxId=e,this.provider=t,this.state=n;}};function P(r,e){return !!r&&typeof r=="object"&&r.name===e}function q(r){return P(r,"SandboxFeatureUnsupportedError")}function W(r){return P(r,"SandboxPathNotFoundError")}function j(r){return P(r,"SandboxNotRunningError")}function E(r){if(!Number.isInteger(r.offset)||r.offset<0)throw new RangeError(`offset must be a non-negative integer, got ${r.offset}`);if(!Number.isInteger(r.length)||r.length<0)throw new RangeError(`length must be a non-negative integer, got ${r.length}`)}function z(r){return r.padStart(4,"0")}var X=/^(-|[dalTLDpSugct?]+)([-r][-w][-x]){3}$/;function N(r){if(!X.test(r))throw new RangeError(`not a Go file mode string: ${r}`);let e=r.slice(0,-9),t=r.slice(-9),n=e.includes("d")?"dir":e.includes("L")?"symlink":/[DpSc?]/.test(e)?"other":"file",s=(e.includes("u")?2048:0)|(e.includes("g")?1024:0)|(e.includes("t")?512:0);for(let o=0;o<9;o++)t[o]!=="-"&&(s|=1<<8-o);return {type:n,mode:z(s.toString(8))}}function v(r){let e=r instanceof Date?r:typeof r=="number"?new Date(r*1e3):new Date(r);if(Number.isNaN(e.getTime()))throw new RangeError(`not a timestamp: ${String(r)}`);return e.toISOString()}function D(r,e){return r.endsWith("/")?`${r}${e}`:`${r}/${e}`}async function $(r,e,t){if(E(e),e.length===0)return new Uint8Array(0);let n=e.offset+e.length-1,s=await fetch(r,{headers:{Range:`bytes=${e.offset}-${n}`},signal:AbortSignal.timeout(t.timeoutMs)});if(s.status===206){let o=new Uint8Array(await s.arrayBuffer());return o.length>e.length?o.subarray(0,e.length):o}if(s.status===200)return Y(s,e);if(s.status===416)return await s.body?.cancel().catch(()=>{}),new Uint8Array(0);throw await s.body?.cancel().catch(()=>{}),s.status===404?new m(t.path,t.provider):new Error(`${t.provider}: range read of ${t.path} failed (HTTP ${s.status})`)}async function Y(r,e){if(!r.body)return new Uint8Array(0);let t=r.body.getReader(),n=[],s=0,o=0,a=e.offset+e.length;try{for(;;){let{done:c,value:p}=await t.read();if(c)break;let h=s;if(s+=p.length,s>e.offset){let d=Math.max(0,e.offset-h),u=Math.min(p.length,a-h);u>d&&(n.push(p.subarray(d,u)),o+=u-d);}if(s>=a)break}}finally{await t.cancel().catch(()=>{});}let i=new Uint8Array(o),l=0;for(let c of n)i.set(c,l),l+=c.length;return i}var b=3e5,_="0.2.5",ee=new Date(0);function I(r){if(!r||typeof r!="object")return false;if(r.name==="TimeoutError")return true;let e=r.message;return typeof e=="string"&&/timed?\s*out/i.test(e)}var L=100,K=100;function w(r){return r instanceof Date?r.toISOString():String(r)}function G(r){if(typeof r=="string"||r instanceof ArrayBuffer)return r;if(r instanceof Buffer)return new Uint8Array(r).buffer;if(r instanceof Uint8Array)return new Uint8Array(r).buffer;throw new Error(`Unsupported data type for file upload: ${typeof r}. Expected string, Buffer, ArrayBuffer, or Uint8Array.`)}var S=class extends Error{constructor(e){super(e),this.name="E2BResourcesError";}},te="2.25.0",A=class extends Error{constructor(e){super(e),this.name="E2BNetworkUpdateUnsupportedError";}};function T(r){if(r?.outbound==="open"&&r.allowedDestinations?.length)throw new Error("network.allowedDestinations is only valid when outbound is blocked");let e=r?.allowedDestinations??[],t=r?.outbound==="blocked"&&e.length>0;return {allowInternetAccess:r?.outbound!=="blocked"||t,network:t?{denyOut:["0.0.0.0/0"],allowOut:e}:void 0}}var B=class extends Error{constructor(){super("E2B takes no create-time boot command: the sandbox boots its template's own init, and a start command is a template-BUILD field (Template startCmd) this provider never sets. The boot is already inert \u2014 run the process by exec after create, or bake it into the template the `image` names."),this.name="E2BBootCommandError";}},M=class extends Error{constructor(){super("E2B has no idle timeout: its sandbox timeout is an ABSOLUTE lifetime that in-sandbox activity never extends. Use `timeoutMs` for the lifetime, and call setTimeout() to extend a sandbox you know is still working."),this.name="E2BIdleTimeoutError";}},R=class{constructor(e,t){this.sandbox=e;this.defaultUser=t;}async run(e,t){try{let n=await this.sandbox.commands.run(e,{timeoutMs:t?.timeoutMs,envs:t?.envs,cwd:t?.cwd,user:this.defaultUser,onStdout:t?.onStdout,onStderr:t?.onStderr});return {exitCode:n.exitCode,stdout:n.stdout,stderr:n.stderr}}catch(n){if(n&&typeof n=="object"&&"exitCode"in n){let s=n;return {exitCode:s.exitCode,stdout:s.stdout??"",stderr:s.stderr??""}}if(I(n))return {exitCode:124,stdout:"",stderr:n instanceof Error?n.message:"command timed out"};throw n}}async spawn(e,t){let n=await this.sandbox.commands.run(e,{background:true,stdin:t?.stdin??true,timeoutMs:t?.timeoutMs,envs:t?.envs,cwd:t?.cwd,user:this.defaultUser,onStdout:t?.onStdout,onStderr:t?.onStderr});return {processId:String(n.pid),wait:async()=>{try{let s=await n.wait();return {exitCode:s.exitCode,stdout:s.stdout,stderr:s.stderr}}catch(s){if(s&&typeof s=="object"&&"exitCode"in s){let o=s;return {exitCode:o.exitCode,stdout:o.stdout??"",stderr:o.stderr??""}}if(I(s))return {exitCode:124,stdout:"",stderr:s instanceof Error?s.message:"command timed out"};throw s}},kill:()=>this.sandbox.commands.kill(n.pid)}}async list(){return (await this.sandbox.commands.list()).map(t=>({...t,processId:String(t.pid)}))}async connect(e,t){let n=await this.sandbox.commands.connect(Number(e),{onStdout:t?.onStdout,onStderr:t?.onStderr,timeoutMs:t?.timeoutMs});return {processId:String(n.pid),wait:async()=>{try{let s=await n.wait();return {exitCode:s.exitCode,stdout:s.stdout,stderr:s.stderr}}catch(s){if(s&&typeof s=="object"&&"exitCode"in s){let o=s;return {exitCode:o.exitCode,stdout:o.stdout??"",stderr:o.stderr??""}}if(I(s))return {exitCode:124,stdout:"",stderr:s instanceof Error?s.message:"command timed out"};throw s}},kill:()=>this.sandbox.commands.kill(n.pid)}}async sendStdin(e,t){await this.sandbox.commands.sendStdin(Number(e),t);}async kill(e){return this.sandbox.commands.kill(Number(e))}},C=class{constructor(e,t,n){this.sandbox=e;this.defaultUser=t;this.envdVersion=n;}async assertEntryInfo(e){if(this.envdVersion??=(await this.sandbox.getInfo()).envdVersion,compareVersions.compareVersions(this.envdVersion,_)<0)throw new x(e,"e2b",`the sandbox runs envd ${this.envdVersion}; entry permissions, owner, group and mtime need envd ${_} or later (rebuild the template)`)}async read(e){let t=await this.sandbox.files.read(e,{format:"bytes",requestTimeoutMs:b,user:this.defaultUser});if(!t.includes(0))try{return new TextDecoder("utf-8",{fatal:!0,ignoreBOM:!0}).decode(t)}catch{}return t}async write(e,t){await this.sandbox.files.write(e,G(t),{requestTimeoutMs:b,user:this.defaultUser});}async writeBatch(e){let t=e.map(n=>({path:n.path,data:G(n.data)}));await this.sandbox.files.write(t,{requestTimeoutMs:b,user:this.defaultUser});}async makeDir(e){await this.sandbox.files.makeDir(e,{user:this.defaultUser});}async uploadUrl(e,t){return this.sandbox.uploadUrl(e,{user:this.defaultUser,...t?{useSignatureExpiration:t}:{}})}async downloadUrl(e,t){return this.sandbox.downloadUrl(e,{user:this.defaultUser,...t?{useSignatureExpiration:t}:{}})}async exists(e){return this.sandbox.files.exists(e,{user:this.defaultUser})}async list(e){await this.assertEntryInfo("files.list");try{return (await this.sandbox.files.list(e,{user:this.defaultUser})).map(n=>H(n))}catch(t){throw U(t)?new m(e,"e2b"):t}}async stat(e){await this.assertEntryInfo("files.stat");try{return H(await this.sandbox.files.getInfo(e,{user:this.defaultUser}))}catch(t){throw U(t)?new m(e,"e2b"):t}}async readRange(e,t){if(E(t),t.length===0)return new Uint8Array(0);let n=await this.sandbox.downloadUrl(e,{user:this.defaultUser,useSignatureExpiration:Math.ceil(b/1e3)});return $(n,t,{provider:"e2b",path:e,timeoutMs:b})}async remove(e){await this.sandbox.files.remove(e,{user:this.defaultUser});}async rename(e,t){await this.sandbox.files.rename(e,t,{user:this.defaultUser});}async readStream(e){return this.sandbox.files.read(e,{format:"stream",user:this.defaultUser})}async writeStream(e,t){await this.sandbox.files.write(e,t,{user:this.defaultUser});}async writeFromPath(e,t){let{createReadStream:n,statSync:s}=await import('fs'),{Readable:o}=await import('stream'),{randomBytes:a}=await import('crypto'),i=s(t).size,l=`----evolve${a(16).toString("hex")}`,c=Buffer.from(`--${l}\r
1
+ 'use strict';var codeInterpreter=require('@e2b/code-interpreter');function b(s){if(!s||typeof s!="object")return false;if(s.name==="TimeoutError")return true;let e=s.message;return typeof e=="string"&&/timed?\s*out/i.test(e)}var k=100,I=100;function u(s){return s instanceof Date?s.toISOString():String(s)}function U(s){if(typeof s=="string"||s instanceof ArrayBuffer)return s;if(s instanceof Buffer)return new Uint8Array(s).buffer;if(s instanceof Uint8Array)return new Uint8Array(s).buffer;throw new Error(`Unsupported data type for file upload: ${typeof s}. Expected string, Buffer, ArrayBuffer, or Uint8Array.`)}var l=class extends Error{constructor(e){super(e),this.name="E2BResourcesError";}},B="2.25.0",g=class extends Error{constructor(e){super(e),this.name="E2BNetworkUpdateUnsupportedError";}};function x(s){if(s?.outbound==="open"&&s.allowedDestinations?.length)throw new Error("network.allowedDestinations is only valid when outbound is blocked");let e=s?.allowedDestinations??[],t=s?.outbound==="blocked"&&e.length>0;return {allowInternetAccess:s?.outbound!=="blocked"||t,network:t?{denyOut:["0.0.0.0/0"],allowOut:e}:void 0}}var h=class extends Error{constructor(){super("E2B takes no create-time boot command: the sandbox boots its template's own init, and a start command is a template-BUILD field (Template startCmd) this provider never sets. The boot is already inert \u2014 run the process by exec after create, or bake it into the template the `image` names."),this.name="E2BBootCommandError";}},y=class extends Error{constructor(){super("E2B has no idle timeout: its sandbox timeout is an ABSOLUTE lifetime that in-sandbox activity never extends. Use `timeoutMs` for the lifetime, and call setTimeout() to extend a sandbox you know is still working."),this.name="E2BIdleTimeoutError";}},w=class{constructor(e,t){this.sandbox=e;this.defaultUser=t;}async run(e,t){try{let r=await this.sandbox.commands.run(e,{timeoutMs:t?.timeoutMs,envs:t?.envs,cwd:t?.cwd,user:this.defaultUser,onStdout:t?.onStdout,onStderr:t?.onStderr});return {exitCode:r.exitCode,stdout:r.stdout,stderr:r.stderr}}catch(r){if(r&&typeof r=="object"&&"exitCode"in r){let n=r;return {exitCode:n.exitCode,stdout:n.stdout??"",stderr:n.stderr??""}}if(b(r))return {exitCode:124,stdout:"",stderr:r instanceof Error?r.message:"command timed out"};throw r}}async spawn(e,t){let r=await this.sandbox.commands.run(e,{background:true,stdin:t?.stdin??true,timeoutMs:t?.timeoutMs,envs:t?.envs,cwd:t?.cwd,user:this.defaultUser,onStdout:t?.onStdout,onStderr:t?.onStderr});return {processId:String(r.pid),wait:async()=>{try{let n=await r.wait();return {exitCode:n.exitCode,stdout:n.stdout,stderr:n.stderr}}catch(n){if(n&&typeof n=="object"&&"exitCode"in n){let i=n;return {exitCode:i.exitCode,stdout:i.stdout??"",stderr:i.stderr??""}}if(b(n))return {exitCode:124,stdout:"",stderr:n instanceof Error?n.message:"command timed out"};throw n}},kill:()=>this.sandbox.commands.kill(r.pid)}}async list(){return (await this.sandbox.commands.list()).map(t=>({...t,processId:String(t.pid)}))}async connect(e,t){let r=await this.sandbox.commands.connect(Number(e),{onStdout:t?.onStdout,onStderr:t?.onStderr,timeoutMs:t?.timeoutMs});return {processId:String(r.pid),wait:async()=>{try{let n=await r.wait();return {exitCode:n.exitCode,stdout:n.stdout,stderr:n.stderr}}catch(n){if(n&&typeof n=="object"&&"exitCode"in n){let i=n;return {exitCode:i.exitCode,stdout:i.stdout??"",stderr:i.stderr??""}}if(b(n))return {exitCode:124,stdout:"",stderr:n instanceof Error?n.message:"command timed out"};throw n}},kill:()=>this.sandbox.commands.kill(r.pid)}}async sendStdin(e,t){await this.sandbox.commands.sendStdin(Number(e),t);}async kill(e){return this.sandbox.commands.kill(Number(e))}},S=class{constructor(e,t){this.sandbox=e;this.defaultUser=t;}async read(e){let t=await this.sandbox.files.read(e,{format:"bytes",requestTimeoutMs:3e5,user:this.defaultUser});if(!t.includes(0))try{return new TextDecoder("utf-8",{fatal:!0,ignoreBOM:!0}).decode(t)}catch{}return t}async write(e,t){await this.sandbox.files.write(e,U(t),{requestTimeoutMs:3e5,user:this.defaultUser});}async writeBatch(e){let t=e.map(r=>({path:r.path,data:U(r.data)}));await this.sandbox.files.write(t,{requestTimeoutMs:3e5,user:this.defaultUser});}async makeDir(e){await this.sandbox.files.makeDir(e,{user:this.defaultUser});}async uploadUrl(e,t){return this.sandbox.uploadUrl(e,{user:this.defaultUser,...t?{useSignatureExpiration:t}:{}})}async downloadUrl(e,t){return this.sandbox.downloadUrl(e,{user:this.defaultUser,...t?{useSignatureExpiration:t}:{}})}async exists(e){return this.sandbox.files.exists(e,{user:this.defaultUser})}async list(e){return (await this.sandbox.files.list(e,{user:this.defaultUser})).map(r=>({name:r.name,path:r.path,type:r.type==="dir"?"dir":"file"}))}async remove(e){await this.sandbox.files.remove(e,{user:this.defaultUser});}async rename(e,t){await this.sandbox.files.rename(e,t,{user:this.defaultUser});}async readStream(e){return this.sandbox.files.read(e,{format:"stream",user:this.defaultUser})}async writeStream(e,t){await this.sandbox.files.write(e,t,{user:this.defaultUser});}async writeFromPath(e,t){let{createReadStream:r,statSync:n}=await import('fs'),{Readable:i}=await import('stream'),{randomBytes:d}=await import('crypto'),a=n(t).size,p=`----evolve${d(16).toString("hex")}`,v=Buffer.from(`--${p}\r
2
2
  Content-Disposition: form-data; name="file"; filename="blob"\r
3
3
  Content-Type: application/octet-stream\r
4
4
  \r
5
- `),p=Buffer.from(`\r
6
- --${l}--\r
7
- `);async function*h(){yield c;for await(let d of n(t))yield d;yield p;}try{let d=await this.uploadUrl(e),u=await fetch(d,{method:"POST",body:o.toWeb(o.from(h())),headers:{"Content-Type":`multipart/form-data; boundary=${l}`,"Content-Length":String(c.length+i+p.length)},duplex:"half"});if(!u.ok)throw new Error(`streamed upload to ${e} failed (HTTP ${u.status})`)}catch(d){console.warn(`[e2b] streamed upload of ${t} failed, falling back to a buffered write:`,d instanceof Error?d.message:d);let u=o.toWeb(n(t));await this.writeStream(e,u);}}async watchDir(e,t,n){let s;try{s=await this.sandbox.files.watchDir(e,o=>{let a=o.type==="chmod"?"write":o.type;return t({path:D(e,o.name),type:a})},{recursive:n?.recursive??!1,timeoutMs:0,user:this.defaultUser});}catch(o){throw U(o)?new m(e,"e2b"):o}return {stop:()=>s.stop()}}};function U(r){let e=r&&typeof r=="object"?r.name:void 0;return e==="FileNotFoundError"||e==="NotFoundError"}function H(r){let{type:e,mode:t}=N(r.permissions),n={name:r.name,path:r.path,type:e,size:r.size,mtime:v(r.modifiedTime??ee),mode:t,owner:r.owner,group:r.group};return e==="symlink"&&r.symlinkTarget!==void 0&&r.symlinkTarget!==r.path&&(n.target=r.symlinkTarget),n}var f=class{constructor(e,t,n,s,o){this.sandbox=e;this.apiKey=t;this.apiUrl=n;this.commands=new R(e,s),this.files=new C(e,s,o);}commands;files;lastMetricsAt;get sandboxId(){return this.sandbox.sandboxId}async metrics(){let e=await this.sandbox.getMetrics(this.lastMetricsAt?{start:this.lastMetricsAt}:{}),t;for(let n of e)(!t||n.timestamp.getTime()>t.timestamp.getTime())&&(t=n);return t?(this.lastMetricsAt=t.timestamp,{cpuPct:t.cpuUsedPct,memUsedMb:t.memUsed/k,memTotalMb:t.memTotal/k,diskUsedMb:t.diskUsed/k,sampledAt:v(t.timestamp),source:"e2b:getMetrics"}):null}getHost(e){return Promise.resolve(this.sandbox.getHost(e))}async isRunning(){return this.sandbox.isRunning()}async getInfo(){let e=await this.sandbox.getInfo();return {sandboxId:e.sandboxId,image:e.templateId,name:e.name,metadata:e.metadata??{},startedAt:w(e.startedAt),endAt:e.endAt?w(e.endAt):void 0}}async updateNetwork(e){let t=T(e),n=this.sandbox;if(typeof n.updateNetwork!="function")throw new A(`The installed e2b client cannot change a running sandbox's network policy: Sandbox.updateNetwork requires e2b >= ${te}. Upgrade the e2b dependency (it is pulled in by @e2b/code-interpreter), or create the sandbox with the policy it needs for its whole lifetime.`);await n.updateNetwork({allowInternetAccess:t.allowInternetAccess,...t.network??{}});}async kill(){try{await this.sandbox.kill();}catch{await new Promise(e=>setTimeout(e,500)),await this.sandbox.kill();}}async pause(){await this.sandbox.betaPause({apiKey:this.apiKey,apiUrl:this.apiUrl});}},O=class{providerType="e2b";name="E2B";apiKey;apiUrl;defaultTimeoutMs;templateId;sandboxUsers=new Map;constructor(e){this.apiKey=e.apiKey,this.apiUrl=e.apiUrl,this.defaultTimeoutMs=e.defaultTimeoutMs??36e5,this.templateId=e.templateId;}async create(e){if(e.bootCommand!==void 0)throw new B;if(e.idleTimeoutMs!==void 0)throw new M;if(e.resources?.gpu!==void 0||e.resources?.gpuTypes!==void 0)throw new S("E2B offers no GPU allocation at any tier \u2014 a `resources.gpu` request cannot be enforced. Run GPU workloads on a provider that reserves GPUs (modal).");if(e.resources&&(e.resources.cpu!==void 0||e.resources.memory!==void 0||e.resources.disk!==void 0))throw new S("E2B cannot size a sandbox at create time: sizing is fixed by the template (Template.build cpuCount/memoryMB; disk is plan-fixed). Build a template with the desired resources and pass it as `image` instead of `resources`.");let t=e.timeoutMs??this.defaultTimeoutMs,n=e.image??this.templateId??"evolve-all";for(let a of e.phaseNetworkPolicies??[])T(a);let s=T(e.network),o=await codeInterpreter.Sandbox.create(n,{apiKey:this.apiKey,apiUrl:this.apiUrl,envs:e.envs,metadata:e.metadata,timeoutMs:t,...s});return e.workingDirectory&&await o.files.makeDir(e.workingDirectory,{user:e.user}),e.user&&this.sandboxUsers.set(o.sandboxId,e.user),new f(o,this.apiKey,this.apiUrl,e.user)}async connect(e,t){let n=await codeInterpreter.Sandbox.connect(e,{apiKey:this.apiKey,apiUrl:this.apiUrl,timeoutMs:t??this.defaultTimeoutMs});return new f(n,this.apiKey,this.apiUrl,this.sandboxUsers.get(e))}async inspect(e,t){let n=await this.fetchSandboxDetail(e);if(n.state!=="running")throw new g(e,"e2b",n.state);let s=F.attach({sandboxId:n.sandboxID,sandboxDomain:n.domain??void 0,envdVersion:n.envdVersion,envdAccessToken:n.envdAccessToken,trafficAccessToken:n.trafficAccessToken??void 0,apiKey:this.apiKey,apiUrl:this.apiUrl});return new f(s,this.apiKey,this.apiUrl,t?.user??this.sandboxUsers.get(e),n.envdVersion)}async fetchSandboxDetail(e){let t=new codeInterpreter.ConnectionConfig({apiKey:this.apiKey,apiUrl:this.apiUrl}),n=await new codeInterpreter.ApiClient(t).api.GET("/sandboxes/{sandboxID}",{params:{path:{sandboxID:e}}});if(n.error?.code===404||!n.data&&!n.error)throw new g(e,"e2b","not found");if(n.error)throw new Error(`E2B refused the sandbox record for ${e}: ${n.error.message??n.error.code}`);return n.data}async list(e){let t=await this.paginate(e);if(t.error&&!t.stoppedAtLimit)throw new Error(t.error);return t.sandboxes}async listAll(e){let{stoppedAtLimit:t,...n}=await this.paginate(e);return n}async paginate(e){let t=e?.limit;return V(codeInterpreter.Sandbox.list({apiKey:this.apiKey,apiUrl:this.apiUrl,query:{state:e?.state,metadata:e?.metadata},limit:t===void 0?L:Math.min(t,L)}),t)}};async function V(r,e){let t=[],n=0,s=new Set;for(;r.hasNext;){if(n>=K)return {sandboxes:t,complete:false,pagesFetched:n,stoppedAtLimit:false,error:`sandbox list exceeded ${K} pages`};let o=r.nextToken;if(o!==void 0){if(s.has(o))return {sandboxes:t,complete:false,pagesFetched:n,stoppedAtLimit:false,error:"pagination token repeated"};s.add(o);}let a;try{a=await r.nextItems();}catch(i){return {sandboxes:t,complete:false,pagesFetched:n,stoppedAtLimit:false,error:`sandbox list failed: ${i instanceof Error?i.message:String(i)}`}}n+=1;for(let i of a){if(e!==void 0&&t.length>=e)return {sandboxes:t,complete:false,pagesFetched:n,stoppedAtLimit:true,error:`stopped at the requested limit of ${e} with more sandboxes available`};t.push({sandboxId:i.sandboxId,image:i.templateId,name:i.name,metadata:i.metadata??{},startedAt:w(i.startedAt),endAt:i.endAt?w(i.endAt):void 0});}if(e!==void 0&&t.length>=e&&r.hasNext)return {sandboxes:t,complete:false,pagesFetched:n,stoppedAtLimit:true,error:`stopped at the requested limit of ${e} with more sandboxes available`};if(e!==void 0&&t.length>=e)break}return {sandboxes:t,complete:true,pagesFetched:n,stoppedAtLimit:false}}var ce=V,k=1024*1024,F=class r extends codeInterpreter.Sandbox{static attach(e){return new r(e)}};function le(r={}){let e=r.apiKey??process.env.E2B_API_KEY;if(!e)throw new Error("E2B API key required. Set E2B_API_KEY environment variable or pass apiKey in config. Get your key at https://e2b.dev/sign-in");return new O({...r,apiKey:e})}var pe=f;
8
- exports.E2BBootCommandError=B;exports.E2BCommands=R;exports.E2BFiles=C;exports.E2BIdleTimeoutError=M;exports.E2BNetworkUpdateUnsupportedError=A;exports.E2BProvider=O;exports.E2BResourcesError=S;exports.E2B_MAX_LIST_PAGES=K;exports.E2B_MAX_PAGE_SIZE=L;exports.E2B_MIN_UPDATE_NETWORK_VERSION=te;exports.SandboxFeatureUnsupportedError=x;exports.SandboxNotRunningError=g;exports.SandboxPathNotFoundError=m;exports._testCollectSandboxPages=ce;exports._testE2BSandboxImplCtor=pe;exports.createE2BProvider=le;exports.isSandboxFeatureUnsupportedError=q;exports.isSandboxNotRunningError=j;exports.isSandboxPathNotFoundError=W;
5
+ `),A=Buffer.from(`\r
6
+ --${p}--\r
7
+ `);async function*C(){yield v;for await(let o of r(t))yield o;yield A;}try{let o=await this.uploadUrl(e),m=await fetch(o,{method:"POST",body:i.toWeb(i.from(C())),headers:{"Content-Type":`multipart/form-data; boundary=${p}`,"Content-Length":String(v.length+a+A.length)},duplex:"half"});if(!m.ok)throw new Error(`streamed upload to ${e} failed (HTTP ${m.status})`)}catch(o){console.warn(`[e2b] streamed upload of ${t} failed, falling back to a buffered write:`,o instanceof Error?o.message:o);let m=i.toWeb(r(t));await this.writeStream(e,m);}}async watchDir(e,t,r){let n=await this.sandbox.files.watchDir(e,t,{recursive:r?.recursive,timeoutMs:r?.timeoutMs,user:this.defaultUser,onExit:r?.onExit});return {stop:()=>n.stop()}}},c=class{constructor(e,t,r,n){this.sandbox=e;this.apiKey=t;this.apiUrl=r;this.commands=new w(e,n),this.files=new S(e,n);}commands;files;get sandboxId(){return this.sandbox.sandboxId}getHost(e){return Promise.resolve(this.sandbox.getHost(e))}async isRunning(){return this.sandbox.isRunning()}async getInfo(){let e=await this.sandbox.getInfo();return {sandboxId:e.sandboxId,image:e.templateId,name:e.name,metadata:e.metadata??{},startedAt:u(e.startedAt),endAt:e.endAt?u(e.endAt):void 0}}async updateNetwork(e){let t=x(e),r=this.sandbox;if(typeof r.updateNetwork!="function")throw new g(`The installed e2b client cannot change a running sandbox's network policy: Sandbox.updateNetwork requires e2b >= ${B}. Upgrade the e2b dependency (it is pulled in by @e2b/code-interpreter), or create the sandbox with the policy it needs for its whole lifetime.`);await r.updateNetwork({allowInternetAccess:t.allowInternetAccess,...t.network??{}});}async kill(){try{await this.sandbox.kill();}catch{await new Promise(e=>setTimeout(e,500)),await this.sandbox.kill();}}async pause(){await this.sandbox.betaPause({apiKey:this.apiKey,apiUrl:this.apiUrl});}},P=class{providerType="e2b";name="E2B";apiKey;apiUrl;defaultTimeoutMs;templateId;sandboxUsers=new Map;constructor(e){this.apiKey=e.apiKey,this.apiUrl=e.apiUrl,this.defaultTimeoutMs=e.defaultTimeoutMs??36e5,this.templateId=e.templateId;}async create(e){if(e.bootCommand!==void 0)throw new h;if(e.idleTimeoutMs!==void 0)throw new y;if(e.resources?.gpu!==void 0||e.resources?.gpuTypes!==void 0)throw new l("E2B offers no GPU allocation at any tier \u2014 a `resources.gpu` request cannot be enforced. Run GPU workloads on a provider that reserves GPUs (modal).");if(e.resources&&(e.resources.cpu!==void 0||e.resources.memory!==void 0||e.resources.disk!==void 0))throw new l("E2B cannot size a sandbox at create time: sizing is fixed by the template (Template.build cpuCount/memoryMB; disk is plan-fixed). Build a template with the desired resources and pass it as `image` instead of `resources`.");let t=e.timeoutMs??this.defaultTimeoutMs,r=e.image??this.templateId??"evolve-all";for(let d of e.phaseNetworkPolicies??[])x(d);let n=x(e.network),i=await codeInterpreter.Sandbox.create(r,{apiKey:this.apiKey,apiUrl:this.apiUrl,envs:e.envs,metadata:e.metadata,timeoutMs:t,...n});return e.workingDirectory&&await i.files.makeDir(e.workingDirectory,{user:e.user}),e.user&&this.sandboxUsers.set(i.sandboxId,e.user),new c(i,this.apiKey,this.apiUrl,e.user)}async connect(e,t){let r=await codeInterpreter.Sandbox.connect(e,{apiKey:this.apiKey,apiUrl:this.apiUrl,timeoutMs:t??this.defaultTimeoutMs});return new c(r,this.apiKey,this.apiUrl,this.sandboxUsers.get(e))}async list(e){let t=await this.paginate(e);if(t.error&&!t.stoppedAtLimit)throw new Error(t.error);return t.sandboxes}async listAll(e){let{stoppedAtLimit:t,...r}=await this.paginate(e);return r}async paginate(e){let t=e?.limit;return E(codeInterpreter.Sandbox.list({apiKey:this.apiKey,apiUrl:this.apiUrl,query:{state:e?.state,metadata:e?.metadata},limit:t===void 0?k:Math.min(t,k)}),t)}};async function E(s,e){let t=[],r=0,n=new Set;for(;s.hasNext;){if(r>=I)return {sandboxes:t,complete:false,pagesFetched:r,stoppedAtLimit:false,error:`sandbox list exceeded ${I} pages`};let i=s.nextToken;if(i!==void 0){if(n.has(i))return {sandboxes:t,complete:false,pagesFetched:r,stoppedAtLimit:false,error:"pagination token repeated"};n.add(i);}let d;try{d=await s.nextItems();}catch(a){return {sandboxes:t,complete:false,pagesFetched:r,stoppedAtLimit:false,error:`sandbox list failed: ${a instanceof Error?a.message:String(a)}`}}r+=1;for(let a of d){if(e!==void 0&&t.length>=e)return {sandboxes:t,complete:false,pagesFetched:r,stoppedAtLimit:true,error:`stopped at the requested limit of ${e} with more sandboxes available`};t.push({sandboxId:a.sandboxId,image:a.templateId,name:a.name,metadata:a.metadata??{},startedAt:u(a.startedAt),endAt:a.endAt?u(a.endAt):void 0});}if(e!==void 0&&t.length>=e&&s.hasNext)return {sandboxes:t,complete:false,pagesFetched:r,stoppedAtLimit:true,error:`stopped at the requested limit of ${e} with more sandboxes available`};if(e!==void 0&&t.length>=e)break}return {sandboxes:t,complete:true,pagesFetched:r,stoppedAtLimit:false}}var T=E;function M(s={}){let e=s.apiKey??process.env.E2B_API_KEY;if(!e)throw new Error("E2B API key required. Set E2B_API_KEY environment variable or pass apiKey in config. Get your key at https://e2b.dev/sign-in");return new P({...s,apiKey:e})}
8
+ exports.E2BBootCommandError=h;exports.E2BCommands=w;exports.E2BFiles=S;exports.E2BIdleTimeoutError=y;exports.E2BNetworkUpdateUnsupportedError=g;exports.E2BProvider=P;exports.E2BResourcesError=l;exports.E2B_MAX_LIST_PAGES=I;exports.E2B_MAX_PAGE_SIZE=k;exports.E2B_MIN_UPDATE_NETWORK_VERSION=B;exports._testCollectSandboxPages=T;exports.createE2BProvider=M;
package/dist/index.d.cts CHANGED
@@ -1,37 +1,9 @@
1
1
  import { Sandbox } from '@e2b/code-interpreter';
2
2
 
3
- /** A capability this provider lacks: `feature` in dotted form (`files.watchDir`), `provider` type, optional `reason`. */
4
- declare class SandboxFeatureUnsupportedError extends Error {
5
- readonly feature: string;
6
- readonly provider: string;
7
- readonly reason?: string;
8
- constructor(feature: string, provider: string, reason?: string);
9
- }
10
- /** A path the sandbox does not have — never an empty success. */
11
- declare class SandboxPathNotFoundError extends Error {
12
- readonly path: string;
13
- readonly provider: string;
14
- constructor(path: string, provider: string);
15
- }
16
- /** An inspect refused because the sandbox is not running; `state` is the provider's own word (`paused`, `exited with code 137`). */
17
- declare class SandboxNotRunningError extends Error {
18
- readonly sandboxId: string;
19
- readonly provider: string;
20
- readonly state: string;
21
- constructor(sandboxId: string, provider: string, state: string);
22
- }
23
- /** True for a SandboxFeatureUnsupportedError from ANY package's copy. */
24
- declare function isSandboxFeatureUnsupportedError(err: unknown): err is SandboxFeatureUnsupportedError;
25
- /** True for a SandboxPathNotFoundError from ANY package's copy. */
26
- declare function isSandboxPathNotFoundError(err: unknown): err is SandboxPathNotFoundError;
27
- /** True for a SandboxNotRunningError from ANY package's copy. */
28
- declare function isSandboxNotRunningError(err: unknown): err is SandboxNotRunningError;
29
-
30
3
  /**
31
4
  * E2B Sandbox Provider - Clean Architecture
32
5
  *
33
- * @requires @e2b/code-interpreter >= 2.7.1 (pins e2b 2.39.0); every field and call this adapter uses is already
34
- * in e2b 2.10.3, the version the dashboard resolves (typings 2.10.3…2.39.0 unpacked and checked 2026-09-16)
6
+ * @requires @e2b/code-interpreter >= 1.0.0 or e2b >= 1.0.0
35
7
  * @requires Node.js >= 18 (for ReadableStream support)
36
8
  *
37
9
  * Design principles:
@@ -138,27 +110,18 @@ interface SandboxInfo {
138
110
  /** End time (undefined for running sandboxes) */
139
111
  endAt?: string;
140
112
  }
141
- /** The SDK contract's FileInfo (sdk-ts types.ts), the same entry on every provider. */
113
+ /** File or directory entry info */
142
114
  interface FileInfo {
143
115
  name: string;
144
116
  path: string;
145
- type: "file" | "dir" | "symlink" | "other";
146
- size: number;
147
- mtime: string;
148
- mode: string;
149
- owner: string;
150
- group: string;
151
- target?: string;
152
- }
153
- /** A byte range of a file (the SDK contract's FileRange). */
154
- interface FileRange {
155
- offset: number;
156
- length: number;
117
+ type: "file" | "dir";
157
118
  }
158
- /** One filesystem change from watchDir: an absolute path, four kinds. */
119
+ /** Filesystem event from watchDir */
159
120
  interface FilesystemEvent {
160
- path: string;
161
- type: "create" | "write" | "remove" | "rename";
121
+ /** Relative path to the changed file/directory */
122
+ name: string;
123
+ /** Type of filesystem operation */
124
+ type: "create" | "remove" | "rename" | "chmod" | "write";
162
125
  }
163
126
  /** Handle to stop watching a directory */
164
127
  interface WatchHandle {
@@ -166,21 +129,9 @@ interface WatchHandle {
166
129
  }
167
130
  /** Options for watching a directory */
168
131
  interface WatchOptions {
169
- /** Also report changes in every subdirectory. Default false. */
170
132
  recursive?: boolean;
171
- }
172
- /** One resource-usage sample (the SDK contract's SandboxMetrics). */
173
- interface SandboxMetrics {
174
- cpuPct: number;
175
- memUsedMb: number;
176
- memTotalMb: number;
177
- diskUsedMb?: number;
178
- sampledAt: string;
179
- source: string;
180
- }
181
- /** Options for an inspect-only attach (the SDK contract's SandboxInspectOptions). */
182
- interface SandboxInspectOptions {
183
- user?: string;
133
+ timeoutMs?: number;
134
+ onExit?: (err?: Error) => void | Promise<void>;
184
135
  }
185
136
  /** Options for blocking sandbox command execution */
186
137
  interface SandboxRunOptions {
@@ -334,10 +285,6 @@ interface SandboxFiles {
334
285
  remove(path: string): Promise<void>;
335
286
  /** Rename or move file/directory */
336
287
  rename(oldPath: string, newPath: string): Promise<void>;
337
- /** The entry at `path` itself; a symlink is never followed */
338
- stat(path: string): Promise<FileInfo>;
339
- /** Exactly the requested bytes, without moving the whole file when the range is small */
340
- readRange(path: string, range: FileRange): Promise<Uint8Array>;
341
288
  /** Watch directory for changes */
342
289
  watchDir(path: string, onEvent: (event: FilesystemEvent) => void | Promise<void>, options?: WatchOptions): Promise<WatchHandle>;
343
290
  }
@@ -352,8 +299,6 @@ interface SandboxInstance {
352
299
  isRunning(): Promise<boolean>;
353
300
  /** Get sandbox metadata and timing */
354
301
  getInfo(): Promise<SandboxInfo>;
355
- /** The newest resource-usage sample, or null while there is none yet */
356
- metrics(): Promise<SandboxMetrics | null>;
357
302
  /** Terminate sandbox */
358
303
  kill(): Promise<void>;
359
304
  /** Pause sandbox (preserves state) */
@@ -371,8 +316,6 @@ interface SandboxProvider {
371
316
  create(options: SandboxCreateOptions): Promise<SandboxInstance>;
372
317
  /** Connect to existing sandbox */
373
318
  connect(sandboxId: string, timeoutMs?: number): Promise<SandboxInstance>;
374
- /** Attach to a RUNNING sandbox for reads; never resumes it, never touches its lifetime */
375
- inspect(sandboxId: string, options?: SandboxInspectOptions): Promise<SandboxInstance>;
376
319
  /** List sandboxes, paginating to exhaustion. `limit` bounds items returned. */
377
320
  list(options?: SandboxListOptions): Promise<SandboxInfo[]>;
378
321
  /** The same enumeration for fleet bookkeeping: never throws, reports completeness. */
@@ -408,10 +351,7 @@ declare class E2BCommands implements SandboxCommands {
408
351
  declare class E2BFiles implements SandboxFiles {
409
352
  private sandbox;
410
353
  private defaultUser?;
411
- private envdVersion?;
412
- /** inspect() passes the record's envd version; a created or connected sandbox reads its record once. */
413
- constructor(sandbox: Sandbox, defaultUser?: string | undefined, envdVersion?: string | undefined);
414
- private assertEntryInfo;
354
+ constructor(sandbox: Sandbox, defaultUser?: string | undefined);
415
355
  read(path: string): Promise<string | Uint8Array>;
416
356
  write(path: string, content: string | Buffer | ArrayBuffer | Uint8Array): Promise<void>;
417
357
  writeBatch(files: Array<{
@@ -423,8 +363,6 @@ declare class E2BFiles implements SandboxFiles {
423
363
  downloadUrl(path: string, expiresInSeconds?: number): Promise<string>;
424
364
  exists(path: string): Promise<boolean>;
425
365
  list(path: string): Promise<FileInfo[]>;
426
- stat(path: string): Promise<FileInfo>;
427
- readRange(path: string, range: FileRange): Promise<Uint8Array>;
428
366
  remove(path: string): Promise<void>;
429
367
  rename(oldPath: string, newPath: string): Promise<void>;
430
368
  readStream(path: string): Promise<ReadableStream<Uint8Array>>;
@@ -460,11 +398,8 @@ declare class E2BSandboxImpl implements SandboxInstance {
460
398
  private apiUrl?;
461
399
  readonly commands: SandboxCommands;
462
400
  readonly files: SandboxFiles;
463
- /** Timestamp of the newest metrics sample seen, so later reads ask only for what is new. */
464
- private lastMetricsAt?;
465
- constructor(sandbox: Sandbox, apiKey: string, apiUrl?: string | undefined, defaultUser?: string, envdVersion?: string);
401
+ constructor(sandbox: Sandbox, apiKey: string, apiUrl?: string | undefined, defaultUser?: string);
466
402
  get sandboxId(): string;
467
- metrics(): Promise<SandboxMetrics | null>;
468
403
  getHost(port: number): Promise<string>;
469
404
  isRunning(): Promise<boolean>;
470
405
  getInfo(): Promise<SandboxInfo>;
@@ -509,8 +444,6 @@ declare class E2BProvider implements SandboxProvider {
509
444
  constructor(config: ResolvedE2BConfig);
510
445
  create(options: SandboxCreateOptions): Promise<SandboxInstance>;
511
446
  connect(sandboxId: string, timeoutMs?: number): Promise<SandboxInstance>;
512
- inspect(sandboxId: string, options?: SandboxInspectOptions): Promise<SandboxInstance>;
513
- protected fetchSandboxDetail(sandboxId: string): Promise<E2BSandboxDetail>;
514
447
  /**
515
448
  * List sandboxes, walking every page.
516
449
  *
@@ -567,15 +500,6 @@ declare function collectSandboxPages(paginator: E2BSandboxPaginator, wanted?: nu
567
500
  stoppedAtLimit: boolean;
568
501
  }>;
569
502
  declare const _testCollectSandboxPages: typeof collectSandboxPages;
570
- /** The fields of E2B's SandboxDetail record that inspect() reads. */
571
- interface E2BSandboxDetail {
572
- sandboxID: string;
573
- state: string;
574
- envdVersion: string;
575
- domain?: string | null;
576
- envdAccessToken?: string;
577
- trafficAccessToken?: string | null;
578
- }
579
503
  /**
580
504
  * Create E2B sandbox provider.
581
505
  *
@@ -591,7 +515,5 @@ declare function createE2BProvider(config?: E2BConfig): SandboxProvider;
591
515
  * the type (never the constructor) gives the seam the real methods to pin.
592
516
  */
593
517
  type _testE2BSandboxImpl = E2BSandboxImpl;
594
- /** The constructor, for the metrics unit test (a vendor sandbox double goes in). */
595
- declare const _testE2BSandboxImplCtor: typeof E2BSandboxImpl;
596
518
 
597
- export { E2BBootCommandError, E2BCommands, type E2BConfig, E2BFiles, E2BIdleTimeoutError, E2BNetworkUpdateUnsupportedError, E2BProvider, E2BResourcesError, type E2BSandboxPaginator, E2B_MAX_LIST_PAGES, E2B_MAX_PAGE_SIZE, E2B_MIN_UPDATE_NETWORK_VERSION, type FileInfo, type FileRange, type FilesystemEvent, type ProcessInfo, type SandboxCommandHandle, type SandboxCommandResult, type SandboxCommands, type SandboxConnectOptions, type SandboxCreateOptions, SandboxFeatureUnsupportedError, type SandboxFiles, type SandboxInfo, type SandboxInspectOptions, type SandboxInstance, type SandboxListOptions, type SandboxListPage, type SandboxMetrics, SandboxNotRunningError, SandboxPathNotFoundError, type SandboxProvider, type SandboxRunOptions, type SandboxSpawnOptions, type WatchHandle, type WatchOptions, _testCollectSandboxPages, type _testE2BSandboxImpl, _testE2BSandboxImplCtor, createE2BProvider, isSandboxFeatureUnsupportedError, isSandboxNotRunningError, isSandboxPathNotFoundError };
519
+ export { E2BBootCommandError, E2BCommands, type E2BConfig, E2BFiles, E2BIdleTimeoutError, E2BNetworkUpdateUnsupportedError, E2BProvider, E2BResourcesError, type E2BSandboxPaginator, E2B_MAX_LIST_PAGES, E2B_MAX_PAGE_SIZE, E2B_MIN_UPDATE_NETWORK_VERSION, type FileInfo, type FilesystemEvent, type ProcessInfo, type SandboxCommandHandle, type SandboxCommandResult, type SandboxCommands, type SandboxConnectOptions, type SandboxCreateOptions, type SandboxFiles, type SandboxInfo, type SandboxInstance, type SandboxListOptions, type SandboxListPage, type SandboxProvider, type SandboxRunOptions, type SandboxSpawnOptions, type WatchHandle, type WatchOptions, _testCollectSandboxPages, type _testE2BSandboxImpl, createE2BProvider };
package/dist/index.d.ts CHANGED
@@ -1,37 +1,9 @@
1
1
  import { Sandbox } from '@e2b/code-interpreter';
2
2
 
3
- /** A capability this provider lacks: `feature` in dotted form (`files.watchDir`), `provider` type, optional `reason`. */
4
- declare class SandboxFeatureUnsupportedError extends Error {
5
- readonly feature: string;
6
- readonly provider: string;
7
- readonly reason?: string;
8
- constructor(feature: string, provider: string, reason?: string);
9
- }
10
- /** A path the sandbox does not have — never an empty success. */
11
- declare class SandboxPathNotFoundError extends Error {
12
- readonly path: string;
13
- readonly provider: string;
14
- constructor(path: string, provider: string);
15
- }
16
- /** An inspect refused because the sandbox is not running; `state` is the provider's own word (`paused`, `exited with code 137`). */
17
- declare class SandboxNotRunningError extends Error {
18
- readonly sandboxId: string;
19
- readonly provider: string;
20
- readonly state: string;
21
- constructor(sandboxId: string, provider: string, state: string);
22
- }
23
- /** True for a SandboxFeatureUnsupportedError from ANY package's copy. */
24
- declare function isSandboxFeatureUnsupportedError(err: unknown): err is SandboxFeatureUnsupportedError;
25
- /** True for a SandboxPathNotFoundError from ANY package's copy. */
26
- declare function isSandboxPathNotFoundError(err: unknown): err is SandboxPathNotFoundError;
27
- /** True for a SandboxNotRunningError from ANY package's copy. */
28
- declare function isSandboxNotRunningError(err: unknown): err is SandboxNotRunningError;
29
-
30
3
  /**
31
4
  * E2B Sandbox Provider - Clean Architecture
32
5
  *
33
- * @requires @e2b/code-interpreter >= 2.7.1 (pins e2b 2.39.0); every field and call this adapter uses is already
34
- * in e2b 2.10.3, the version the dashboard resolves (typings 2.10.3…2.39.0 unpacked and checked 2026-09-16)
6
+ * @requires @e2b/code-interpreter >= 1.0.0 or e2b >= 1.0.0
35
7
  * @requires Node.js >= 18 (for ReadableStream support)
36
8
  *
37
9
  * Design principles:
@@ -138,27 +110,18 @@ interface SandboxInfo {
138
110
  /** End time (undefined for running sandboxes) */
139
111
  endAt?: string;
140
112
  }
141
- /** The SDK contract's FileInfo (sdk-ts types.ts), the same entry on every provider. */
113
+ /** File or directory entry info */
142
114
  interface FileInfo {
143
115
  name: string;
144
116
  path: string;
145
- type: "file" | "dir" | "symlink" | "other";
146
- size: number;
147
- mtime: string;
148
- mode: string;
149
- owner: string;
150
- group: string;
151
- target?: string;
152
- }
153
- /** A byte range of a file (the SDK contract's FileRange). */
154
- interface FileRange {
155
- offset: number;
156
- length: number;
117
+ type: "file" | "dir";
157
118
  }
158
- /** One filesystem change from watchDir: an absolute path, four kinds. */
119
+ /** Filesystem event from watchDir */
159
120
  interface FilesystemEvent {
160
- path: string;
161
- type: "create" | "write" | "remove" | "rename";
121
+ /** Relative path to the changed file/directory */
122
+ name: string;
123
+ /** Type of filesystem operation */
124
+ type: "create" | "remove" | "rename" | "chmod" | "write";
162
125
  }
163
126
  /** Handle to stop watching a directory */
164
127
  interface WatchHandle {
@@ -166,21 +129,9 @@ interface WatchHandle {
166
129
  }
167
130
  /** Options for watching a directory */
168
131
  interface WatchOptions {
169
- /** Also report changes in every subdirectory. Default false. */
170
132
  recursive?: boolean;
171
- }
172
- /** One resource-usage sample (the SDK contract's SandboxMetrics). */
173
- interface SandboxMetrics {
174
- cpuPct: number;
175
- memUsedMb: number;
176
- memTotalMb: number;
177
- diskUsedMb?: number;
178
- sampledAt: string;
179
- source: string;
180
- }
181
- /** Options for an inspect-only attach (the SDK contract's SandboxInspectOptions). */
182
- interface SandboxInspectOptions {
183
- user?: string;
133
+ timeoutMs?: number;
134
+ onExit?: (err?: Error) => void | Promise<void>;
184
135
  }
185
136
  /** Options for blocking sandbox command execution */
186
137
  interface SandboxRunOptions {
@@ -334,10 +285,6 @@ interface SandboxFiles {
334
285
  remove(path: string): Promise<void>;
335
286
  /** Rename or move file/directory */
336
287
  rename(oldPath: string, newPath: string): Promise<void>;
337
- /** The entry at `path` itself; a symlink is never followed */
338
- stat(path: string): Promise<FileInfo>;
339
- /** Exactly the requested bytes, without moving the whole file when the range is small */
340
- readRange(path: string, range: FileRange): Promise<Uint8Array>;
341
288
  /** Watch directory for changes */
342
289
  watchDir(path: string, onEvent: (event: FilesystemEvent) => void | Promise<void>, options?: WatchOptions): Promise<WatchHandle>;
343
290
  }
@@ -352,8 +299,6 @@ interface SandboxInstance {
352
299
  isRunning(): Promise<boolean>;
353
300
  /** Get sandbox metadata and timing */
354
301
  getInfo(): Promise<SandboxInfo>;
355
- /** The newest resource-usage sample, or null while there is none yet */
356
- metrics(): Promise<SandboxMetrics | null>;
357
302
  /** Terminate sandbox */
358
303
  kill(): Promise<void>;
359
304
  /** Pause sandbox (preserves state) */
@@ -371,8 +316,6 @@ interface SandboxProvider {
371
316
  create(options: SandboxCreateOptions): Promise<SandboxInstance>;
372
317
  /** Connect to existing sandbox */
373
318
  connect(sandboxId: string, timeoutMs?: number): Promise<SandboxInstance>;
374
- /** Attach to a RUNNING sandbox for reads; never resumes it, never touches its lifetime */
375
- inspect(sandboxId: string, options?: SandboxInspectOptions): Promise<SandboxInstance>;
376
319
  /** List sandboxes, paginating to exhaustion. `limit` bounds items returned. */
377
320
  list(options?: SandboxListOptions): Promise<SandboxInfo[]>;
378
321
  /** The same enumeration for fleet bookkeeping: never throws, reports completeness. */
@@ -408,10 +351,7 @@ declare class E2BCommands implements SandboxCommands {
408
351
  declare class E2BFiles implements SandboxFiles {
409
352
  private sandbox;
410
353
  private defaultUser?;
411
- private envdVersion?;
412
- /** inspect() passes the record's envd version; a created or connected sandbox reads its record once. */
413
- constructor(sandbox: Sandbox, defaultUser?: string | undefined, envdVersion?: string | undefined);
414
- private assertEntryInfo;
354
+ constructor(sandbox: Sandbox, defaultUser?: string | undefined);
415
355
  read(path: string): Promise<string | Uint8Array>;
416
356
  write(path: string, content: string | Buffer | ArrayBuffer | Uint8Array): Promise<void>;
417
357
  writeBatch(files: Array<{
@@ -423,8 +363,6 @@ declare class E2BFiles implements SandboxFiles {
423
363
  downloadUrl(path: string, expiresInSeconds?: number): Promise<string>;
424
364
  exists(path: string): Promise<boolean>;
425
365
  list(path: string): Promise<FileInfo[]>;
426
- stat(path: string): Promise<FileInfo>;
427
- readRange(path: string, range: FileRange): Promise<Uint8Array>;
428
366
  remove(path: string): Promise<void>;
429
367
  rename(oldPath: string, newPath: string): Promise<void>;
430
368
  readStream(path: string): Promise<ReadableStream<Uint8Array>>;
@@ -460,11 +398,8 @@ declare class E2BSandboxImpl implements SandboxInstance {
460
398
  private apiUrl?;
461
399
  readonly commands: SandboxCommands;
462
400
  readonly files: SandboxFiles;
463
- /** Timestamp of the newest metrics sample seen, so later reads ask only for what is new. */
464
- private lastMetricsAt?;
465
- constructor(sandbox: Sandbox, apiKey: string, apiUrl?: string | undefined, defaultUser?: string, envdVersion?: string);
401
+ constructor(sandbox: Sandbox, apiKey: string, apiUrl?: string | undefined, defaultUser?: string);
466
402
  get sandboxId(): string;
467
- metrics(): Promise<SandboxMetrics | null>;
468
403
  getHost(port: number): Promise<string>;
469
404
  isRunning(): Promise<boolean>;
470
405
  getInfo(): Promise<SandboxInfo>;
@@ -509,8 +444,6 @@ declare class E2BProvider implements SandboxProvider {
509
444
  constructor(config: ResolvedE2BConfig);
510
445
  create(options: SandboxCreateOptions): Promise<SandboxInstance>;
511
446
  connect(sandboxId: string, timeoutMs?: number): Promise<SandboxInstance>;
512
- inspect(sandboxId: string, options?: SandboxInspectOptions): Promise<SandboxInstance>;
513
- protected fetchSandboxDetail(sandboxId: string): Promise<E2BSandboxDetail>;
514
447
  /**
515
448
  * List sandboxes, walking every page.
516
449
  *
@@ -567,15 +500,6 @@ declare function collectSandboxPages(paginator: E2BSandboxPaginator, wanted?: nu
567
500
  stoppedAtLimit: boolean;
568
501
  }>;
569
502
  declare const _testCollectSandboxPages: typeof collectSandboxPages;
570
- /** The fields of E2B's SandboxDetail record that inspect() reads. */
571
- interface E2BSandboxDetail {
572
- sandboxID: string;
573
- state: string;
574
- envdVersion: string;
575
- domain?: string | null;
576
- envdAccessToken?: string;
577
- trafficAccessToken?: string | null;
578
- }
579
503
  /**
580
504
  * Create E2B sandbox provider.
581
505
  *
@@ -591,7 +515,5 @@ declare function createE2BProvider(config?: E2BConfig): SandboxProvider;
591
515
  * the type (never the constructor) gives the seam the real methods to pin.
592
516
  */
593
517
  type _testE2BSandboxImpl = E2BSandboxImpl;
594
- /** The constructor, for the metrics unit test (a vendor sandbox double goes in). */
595
- declare const _testE2BSandboxImplCtor: typeof E2BSandboxImpl;
596
518
 
597
- export { E2BBootCommandError, E2BCommands, type E2BConfig, E2BFiles, E2BIdleTimeoutError, E2BNetworkUpdateUnsupportedError, E2BProvider, E2BResourcesError, type E2BSandboxPaginator, E2B_MAX_LIST_PAGES, E2B_MAX_PAGE_SIZE, E2B_MIN_UPDATE_NETWORK_VERSION, type FileInfo, type FileRange, type FilesystemEvent, type ProcessInfo, type SandboxCommandHandle, type SandboxCommandResult, type SandboxCommands, type SandboxConnectOptions, type SandboxCreateOptions, SandboxFeatureUnsupportedError, type SandboxFiles, type SandboxInfo, type SandboxInspectOptions, type SandboxInstance, type SandboxListOptions, type SandboxListPage, type SandboxMetrics, SandboxNotRunningError, SandboxPathNotFoundError, type SandboxProvider, type SandboxRunOptions, type SandboxSpawnOptions, type WatchHandle, type WatchOptions, _testCollectSandboxPages, type _testE2BSandboxImpl, _testE2BSandboxImplCtor, createE2BProvider, isSandboxFeatureUnsupportedError, isSandboxNotRunningError, isSandboxPathNotFoundError };
519
+ export { E2BBootCommandError, E2BCommands, type E2BConfig, E2BFiles, E2BIdleTimeoutError, E2BNetworkUpdateUnsupportedError, E2BProvider, E2BResourcesError, type E2BSandboxPaginator, E2B_MAX_LIST_PAGES, E2B_MAX_PAGE_SIZE, E2B_MIN_UPDATE_NETWORK_VERSION, type FileInfo, type FilesystemEvent, type ProcessInfo, type SandboxCommandHandle, type SandboxCommandResult, type SandboxCommands, type SandboxConnectOptions, type SandboxCreateOptions, type SandboxFiles, type SandboxInfo, type SandboxInstance, type SandboxListOptions, type SandboxListPage, type SandboxProvider, type SandboxRunOptions, type SandboxSpawnOptions, type WatchHandle, type WatchOptions, _testCollectSandboxPages, type _testE2BSandboxImpl, createE2BProvider };
package/dist/index.js CHANGED
@@ -1,8 +1,8 @@
1
- import {Sandbox,ConnectionConfig,ApiClient}from'@e2b/code-interpreter';import {compareVersions}from'compare-versions';import'fs';var x=class extends Error{feature;provider;reason;constructor(e,t,n){super(`${t} does not support ${e}${n?`: ${n}`:""}`),this.name="SandboxFeatureUnsupportedError",this.feature=e,this.provider=t,this.reason=n;}},m=class extends Error{path;provider;constructor(e,t){super(`${t}: no such file or directory: ${e}`),this.name="SandboxPathNotFoundError",this.path=e,this.provider=t;}},g=class extends Error{sandboxId;provider;state;constructor(e,t,n){super(`${t} sandbox ${e} is not running (${n}); inspect never starts or resumes a sandbox`),this.name="SandboxNotRunningError",this.sandboxId=e,this.provider=t,this.state=n;}};function P(r,e){return !!r&&typeof r=="object"&&r.name===e}function q(r){return P(r,"SandboxFeatureUnsupportedError")}function W(r){return P(r,"SandboxPathNotFoundError")}function j(r){return P(r,"SandboxNotRunningError")}function E(r){if(!Number.isInteger(r.offset)||r.offset<0)throw new RangeError(`offset must be a non-negative integer, got ${r.offset}`);if(!Number.isInteger(r.length)||r.length<0)throw new RangeError(`length must be a non-negative integer, got ${r.length}`)}function z(r){return r.padStart(4,"0")}var X=/^(-|[dalTLDpSugct?]+)([-r][-w][-x]){3}$/;function N(r){if(!X.test(r))throw new RangeError(`not a Go file mode string: ${r}`);let e=r.slice(0,-9),t=r.slice(-9),n=e.includes("d")?"dir":e.includes("L")?"symlink":/[DpSc?]/.test(e)?"other":"file",s=(e.includes("u")?2048:0)|(e.includes("g")?1024:0)|(e.includes("t")?512:0);for(let o=0;o<9;o++)t[o]!=="-"&&(s|=1<<8-o);return {type:n,mode:z(s.toString(8))}}function v(r){let e=r instanceof Date?r:typeof r=="number"?new Date(r*1e3):new Date(r);if(Number.isNaN(e.getTime()))throw new RangeError(`not a timestamp: ${String(r)}`);return e.toISOString()}function D(r,e){return r.endsWith("/")?`${r}${e}`:`${r}/${e}`}async function $(r,e,t){if(E(e),e.length===0)return new Uint8Array(0);let n=e.offset+e.length-1,s=await fetch(r,{headers:{Range:`bytes=${e.offset}-${n}`},signal:AbortSignal.timeout(t.timeoutMs)});if(s.status===206){let o=new Uint8Array(await s.arrayBuffer());return o.length>e.length?o.subarray(0,e.length):o}if(s.status===200)return Y(s,e);if(s.status===416)return await s.body?.cancel().catch(()=>{}),new Uint8Array(0);throw await s.body?.cancel().catch(()=>{}),s.status===404?new m(t.path,t.provider):new Error(`${t.provider}: range read of ${t.path} failed (HTTP ${s.status})`)}async function Y(r,e){if(!r.body)return new Uint8Array(0);let t=r.body.getReader(),n=[],s=0,o=0,a=e.offset+e.length;try{for(;;){let{done:c,value:p}=await t.read();if(c)break;let h=s;if(s+=p.length,s>e.offset){let d=Math.max(0,e.offset-h),u=Math.min(p.length,a-h);u>d&&(n.push(p.subarray(d,u)),o+=u-d);}if(s>=a)break}}finally{await t.cancel().catch(()=>{});}let i=new Uint8Array(o),l=0;for(let c of n)i.set(c,l),l+=c.length;return i}var b=3e5,_="0.2.5",ee=new Date(0);function I(r){if(!r||typeof r!="object")return false;if(r.name==="TimeoutError")return true;let e=r.message;return typeof e=="string"&&/timed?\s*out/i.test(e)}var L=100,K=100;function w(r){return r instanceof Date?r.toISOString():String(r)}function G(r){if(typeof r=="string"||r instanceof ArrayBuffer)return r;if(r instanceof Buffer)return new Uint8Array(r).buffer;if(r instanceof Uint8Array)return new Uint8Array(r).buffer;throw new Error(`Unsupported data type for file upload: ${typeof r}. Expected string, Buffer, ArrayBuffer, or Uint8Array.`)}var S=class extends Error{constructor(e){super(e),this.name="E2BResourcesError";}},te="2.25.0",A=class extends Error{constructor(e){super(e),this.name="E2BNetworkUpdateUnsupportedError";}};function T(r){if(r?.outbound==="open"&&r.allowedDestinations?.length)throw new Error("network.allowedDestinations is only valid when outbound is blocked");let e=r?.allowedDestinations??[],t=r?.outbound==="blocked"&&e.length>0;return {allowInternetAccess:r?.outbound!=="blocked"||t,network:t?{denyOut:["0.0.0.0/0"],allowOut:e}:void 0}}var B=class extends Error{constructor(){super("E2B takes no create-time boot command: the sandbox boots its template's own init, and a start command is a template-BUILD field (Template startCmd) this provider never sets. The boot is already inert \u2014 run the process by exec after create, or bake it into the template the `image` names."),this.name="E2BBootCommandError";}},M=class extends Error{constructor(){super("E2B has no idle timeout: its sandbox timeout is an ABSOLUTE lifetime that in-sandbox activity never extends. Use `timeoutMs` for the lifetime, and call setTimeout() to extend a sandbox you know is still working."),this.name="E2BIdleTimeoutError";}},R=class{constructor(e,t){this.sandbox=e;this.defaultUser=t;}async run(e,t){try{let n=await this.sandbox.commands.run(e,{timeoutMs:t?.timeoutMs,envs:t?.envs,cwd:t?.cwd,user:this.defaultUser,onStdout:t?.onStdout,onStderr:t?.onStderr});return {exitCode:n.exitCode,stdout:n.stdout,stderr:n.stderr}}catch(n){if(n&&typeof n=="object"&&"exitCode"in n){let s=n;return {exitCode:s.exitCode,stdout:s.stdout??"",stderr:s.stderr??""}}if(I(n))return {exitCode:124,stdout:"",stderr:n instanceof Error?n.message:"command timed out"};throw n}}async spawn(e,t){let n=await this.sandbox.commands.run(e,{background:true,stdin:t?.stdin??true,timeoutMs:t?.timeoutMs,envs:t?.envs,cwd:t?.cwd,user:this.defaultUser,onStdout:t?.onStdout,onStderr:t?.onStderr});return {processId:String(n.pid),wait:async()=>{try{let s=await n.wait();return {exitCode:s.exitCode,stdout:s.stdout,stderr:s.stderr}}catch(s){if(s&&typeof s=="object"&&"exitCode"in s){let o=s;return {exitCode:o.exitCode,stdout:o.stdout??"",stderr:o.stderr??""}}if(I(s))return {exitCode:124,stdout:"",stderr:s instanceof Error?s.message:"command timed out"};throw s}},kill:()=>this.sandbox.commands.kill(n.pid)}}async list(){return (await this.sandbox.commands.list()).map(t=>({...t,processId:String(t.pid)}))}async connect(e,t){let n=await this.sandbox.commands.connect(Number(e),{onStdout:t?.onStdout,onStderr:t?.onStderr,timeoutMs:t?.timeoutMs});return {processId:String(n.pid),wait:async()=>{try{let s=await n.wait();return {exitCode:s.exitCode,stdout:s.stdout,stderr:s.stderr}}catch(s){if(s&&typeof s=="object"&&"exitCode"in s){let o=s;return {exitCode:o.exitCode,stdout:o.stdout??"",stderr:o.stderr??""}}if(I(s))return {exitCode:124,stdout:"",stderr:s instanceof Error?s.message:"command timed out"};throw s}},kill:()=>this.sandbox.commands.kill(n.pid)}}async sendStdin(e,t){await this.sandbox.commands.sendStdin(Number(e),t);}async kill(e){return this.sandbox.commands.kill(Number(e))}},C=class{constructor(e,t,n){this.sandbox=e;this.defaultUser=t;this.envdVersion=n;}async assertEntryInfo(e){if(this.envdVersion??=(await this.sandbox.getInfo()).envdVersion,compareVersions(this.envdVersion,_)<0)throw new x(e,"e2b",`the sandbox runs envd ${this.envdVersion}; entry permissions, owner, group and mtime need envd ${_} or later (rebuild the template)`)}async read(e){let t=await this.sandbox.files.read(e,{format:"bytes",requestTimeoutMs:b,user:this.defaultUser});if(!t.includes(0))try{return new TextDecoder("utf-8",{fatal:!0,ignoreBOM:!0}).decode(t)}catch{}return t}async write(e,t){await this.sandbox.files.write(e,G(t),{requestTimeoutMs:b,user:this.defaultUser});}async writeBatch(e){let t=e.map(n=>({path:n.path,data:G(n.data)}));await this.sandbox.files.write(t,{requestTimeoutMs:b,user:this.defaultUser});}async makeDir(e){await this.sandbox.files.makeDir(e,{user:this.defaultUser});}async uploadUrl(e,t){return this.sandbox.uploadUrl(e,{user:this.defaultUser,...t?{useSignatureExpiration:t}:{}})}async downloadUrl(e,t){return this.sandbox.downloadUrl(e,{user:this.defaultUser,...t?{useSignatureExpiration:t}:{}})}async exists(e){return this.sandbox.files.exists(e,{user:this.defaultUser})}async list(e){await this.assertEntryInfo("files.list");try{return (await this.sandbox.files.list(e,{user:this.defaultUser})).map(n=>H(n))}catch(t){throw U(t)?new m(e,"e2b"):t}}async stat(e){await this.assertEntryInfo("files.stat");try{return H(await this.sandbox.files.getInfo(e,{user:this.defaultUser}))}catch(t){throw U(t)?new m(e,"e2b"):t}}async readRange(e,t){if(E(t),t.length===0)return new Uint8Array(0);let n=await this.sandbox.downloadUrl(e,{user:this.defaultUser,useSignatureExpiration:Math.ceil(b/1e3)});return $(n,t,{provider:"e2b",path:e,timeoutMs:b})}async remove(e){await this.sandbox.files.remove(e,{user:this.defaultUser});}async rename(e,t){await this.sandbox.files.rename(e,t,{user:this.defaultUser});}async readStream(e){return this.sandbox.files.read(e,{format:"stream",user:this.defaultUser})}async writeStream(e,t){await this.sandbox.files.write(e,t,{user:this.defaultUser});}async writeFromPath(e,t){let{createReadStream:n,statSync:s}=await import('fs'),{Readable:o}=await import('stream'),{randomBytes:a}=await import('crypto'),i=s(t).size,l=`----evolve${a(16).toString("hex")}`,c=Buffer.from(`--${l}\r
1
+ import {Sandbox}from'@e2b/code-interpreter';function b(s){if(!s||typeof s!="object")return false;if(s.name==="TimeoutError")return true;let e=s.message;return typeof e=="string"&&/timed?\s*out/i.test(e)}var k=100,I=100;function u(s){return s instanceof Date?s.toISOString():String(s)}function U(s){if(typeof s=="string"||s instanceof ArrayBuffer)return s;if(s instanceof Buffer)return new Uint8Array(s).buffer;if(s instanceof Uint8Array)return new Uint8Array(s).buffer;throw new Error(`Unsupported data type for file upload: ${typeof s}. Expected string, Buffer, ArrayBuffer, or Uint8Array.`)}var l=class extends Error{constructor(e){super(e),this.name="E2BResourcesError";}},B="2.25.0",g=class extends Error{constructor(e){super(e),this.name="E2BNetworkUpdateUnsupportedError";}};function x(s){if(s?.outbound==="open"&&s.allowedDestinations?.length)throw new Error("network.allowedDestinations is only valid when outbound is blocked");let e=s?.allowedDestinations??[],t=s?.outbound==="blocked"&&e.length>0;return {allowInternetAccess:s?.outbound!=="blocked"||t,network:t?{denyOut:["0.0.0.0/0"],allowOut:e}:void 0}}var h=class extends Error{constructor(){super("E2B takes no create-time boot command: the sandbox boots its template's own init, and a start command is a template-BUILD field (Template startCmd) this provider never sets. The boot is already inert \u2014 run the process by exec after create, or bake it into the template the `image` names."),this.name="E2BBootCommandError";}},y=class extends Error{constructor(){super("E2B has no idle timeout: its sandbox timeout is an ABSOLUTE lifetime that in-sandbox activity never extends. Use `timeoutMs` for the lifetime, and call setTimeout() to extend a sandbox you know is still working."),this.name="E2BIdleTimeoutError";}},w=class{constructor(e,t){this.sandbox=e;this.defaultUser=t;}async run(e,t){try{let r=await this.sandbox.commands.run(e,{timeoutMs:t?.timeoutMs,envs:t?.envs,cwd:t?.cwd,user:this.defaultUser,onStdout:t?.onStdout,onStderr:t?.onStderr});return {exitCode:r.exitCode,stdout:r.stdout,stderr:r.stderr}}catch(r){if(r&&typeof r=="object"&&"exitCode"in r){let n=r;return {exitCode:n.exitCode,stdout:n.stdout??"",stderr:n.stderr??""}}if(b(r))return {exitCode:124,stdout:"",stderr:r instanceof Error?r.message:"command timed out"};throw r}}async spawn(e,t){let r=await this.sandbox.commands.run(e,{background:true,stdin:t?.stdin??true,timeoutMs:t?.timeoutMs,envs:t?.envs,cwd:t?.cwd,user:this.defaultUser,onStdout:t?.onStdout,onStderr:t?.onStderr});return {processId:String(r.pid),wait:async()=>{try{let n=await r.wait();return {exitCode:n.exitCode,stdout:n.stdout,stderr:n.stderr}}catch(n){if(n&&typeof n=="object"&&"exitCode"in n){let i=n;return {exitCode:i.exitCode,stdout:i.stdout??"",stderr:i.stderr??""}}if(b(n))return {exitCode:124,stdout:"",stderr:n instanceof Error?n.message:"command timed out"};throw n}},kill:()=>this.sandbox.commands.kill(r.pid)}}async list(){return (await this.sandbox.commands.list()).map(t=>({...t,processId:String(t.pid)}))}async connect(e,t){let r=await this.sandbox.commands.connect(Number(e),{onStdout:t?.onStdout,onStderr:t?.onStderr,timeoutMs:t?.timeoutMs});return {processId:String(r.pid),wait:async()=>{try{let n=await r.wait();return {exitCode:n.exitCode,stdout:n.stdout,stderr:n.stderr}}catch(n){if(n&&typeof n=="object"&&"exitCode"in n){let i=n;return {exitCode:i.exitCode,stdout:i.stdout??"",stderr:i.stderr??""}}if(b(n))return {exitCode:124,stdout:"",stderr:n instanceof Error?n.message:"command timed out"};throw n}},kill:()=>this.sandbox.commands.kill(r.pid)}}async sendStdin(e,t){await this.sandbox.commands.sendStdin(Number(e),t);}async kill(e){return this.sandbox.commands.kill(Number(e))}},S=class{constructor(e,t){this.sandbox=e;this.defaultUser=t;}async read(e){let t=await this.sandbox.files.read(e,{format:"bytes",requestTimeoutMs:3e5,user:this.defaultUser});if(!t.includes(0))try{return new TextDecoder("utf-8",{fatal:!0,ignoreBOM:!0}).decode(t)}catch{}return t}async write(e,t){await this.sandbox.files.write(e,U(t),{requestTimeoutMs:3e5,user:this.defaultUser});}async writeBatch(e){let t=e.map(r=>({path:r.path,data:U(r.data)}));await this.sandbox.files.write(t,{requestTimeoutMs:3e5,user:this.defaultUser});}async makeDir(e){await this.sandbox.files.makeDir(e,{user:this.defaultUser});}async uploadUrl(e,t){return this.sandbox.uploadUrl(e,{user:this.defaultUser,...t?{useSignatureExpiration:t}:{}})}async downloadUrl(e,t){return this.sandbox.downloadUrl(e,{user:this.defaultUser,...t?{useSignatureExpiration:t}:{}})}async exists(e){return this.sandbox.files.exists(e,{user:this.defaultUser})}async list(e){return (await this.sandbox.files.list(e,{user:this.defaultUser})).map(r=>({name:r.name,path:r.path,type:r.type==="dir"?"dir":"file"}))}async remove(e){await this.sandbox.files.remove(e,{user:this.defaultUser});}async rename(e,t){await this.sandbox.files.rename(e,t,{user:this.defaultUser});}async readStream(e){return this.sandbox.files.read(e,{format:"stream",user:this.defaultUser})}async writeStream(e,t){await this.sandbox.files.write(e,t,{user:this.defaultUser});}async writeFromPath(e,t){let{createReadStream:r,statSync:n}=await import('fs'),{Readable:i}=await import('stream'),{randomBytes:d}=await import('crypto'),a=n(t).size,p=`----evolve${d(16).toString("hex")}`,v=Buffer.from(`--${p}\r
2
2
  Content-Disposition: form-data; name="file"; filename="blob"\r
3
3
  Content-Type: application/octet-stream\r
4
4
  \r
5
- `),p=Buffer.from(`\r
6
- --${l}--\r
7
- `);async function*h(){yield c;for await(let d of n(t))yield d;yield p;}try{let d=await this.uploadUrl(e),u=await fetch(d,{method:"POST",body:o.toWeb(o.from(h())),headers:{"Content-Type":`multipart/form-data; boundary=${l}`,"Content-Length":String(c.length+i+p.length)},duplex:"half"});if(!u.ok)throw new Error(`streamed upload to ${e} failed (HTTP ${u.status})`)}catch(d){console.warn(`[e2b] streamed upload of ${t} failed, falling back to a buffered write:`,d instanceof Error?d.message:d);let u=o.toWeb(n(t));await this.writeStream(e,u);}}async watchDir(e,t,n){let s;try{s=await this.sandbox.files.watchDir(e,o=>{let a=o.type==="chmod"?"write":o.type;return t({path:D(e,o.name),type:a})},{recursive:n?.recursive??!1,timeoutMs:0,user:this.defaultUser});}catch(o){throw U(o)?new m(e,"e2b"):o}return {stop:()=>s.stop()}}};function U(r){let e=r&&typeof r=="object"?r.name:void 0;return e==="FileNotFoundError"||e==="NotFoundError"}function H(r){let{type:e,mode:t}=N(r.permissions),n={name:r.name,path:r.path,type:e,size:r.size,mtime:v(r.modifiedTime??ee),mode:t,owner:r.owner,group:r.group};return e==="symlink"&&r.symlinkTarget!==void 0&&r.symlinkTarget!==r.path&&(n.target=r.symlinkTarget),n}var f=class{constructor(e,t,n,s,o){this.sandbox=e;this.apiKey=t;this.apiUrl=n;this.commands=new R(e,s),this.files=new C(e,s,o);}commands;files;lastMetricsAt;get sandboxId(){return this.sandbox.sandboxId}async metrics(){let e=await this.sandbox.getMetrics(this.lastMetricsAt?{start:this.lastMetricsAt}:{}),t;for(let n of e)(!t||n.timestamp.getTime()>t.timestamp.getTime())&&(t=n);return t?(this.lastMetricsAt=t.timestamp,{cpuPct:t.cpuUsedPct,memUsedMb:t.memUsed/k,memTotalMb:t.memTotal/k,diskUsedMb:t.diskUsed/k,sampledAt:v(t.timestamp),source:"e2b:getMetrics"}):null}getHost(e){return Promise.resolve(this.sandbox.getHost(e))}async isRunning(){return this.sandbox.isRunning()}async getInfo(){let e=await this.sandbox.getInfo();return {sandboxId:e.sandboxId,image:e.templateId,name:e.name,metadata:e.metadata??{},startedAt:w(e.startedAt),endAt:e.endAt?w(e.endAt):void 0}}async updateNetwork(e){let t=T(e),n=this.sandbox;if(typeof n.updateNetwork!="function")throw new A(`The installed e2b client cannot change a running sandbox's network policy: Sandbox.updateNetwork requires e2b >= ${te}. Upgrade the e2b dependency (it is pulled in by @e2b/code-interpreter), or create the sandbox with the policy it needs for its whole lifetime.`);await n.updateNetwork({allowInternetAccess:t.allowInternetAccess,...t.network??{}});}async kill(){try{await this.sandbox.kill();}catch{await new Promise(e=>setTimeout(e,500)),await this.sandbox.kill();}}async pause(){await this.sandbox.betaPause({apiKey:this.apiKey,apiUrl:this.apiUrl});}},O=class{providerType="e2b";name="E2B";apiKey;apiUrl;defaultTimeoutMs;templateId;sandboxUsers=new Map;constructor(e){this.apiKey=e.apiKey,this.apiUrl=e.apiUrl,this.defaultTimeoutMs=e.defaultTimeoutMs??36e5,this.templateId=e.templateId;}async create(e){if(e.bootCommand!==void 0)throw new B;if(e.idleTimeoutMs!==void 0)throw new M;if(e.resources?.gpu!==void 0||e.resources?.gpuTypes!==void 0)throw new S("E2B offers no GPU allocation at any tier \u2014 a `resources.gpu` request cannot be enforced. Run GPU workloads on a provider that reserves GPUs (modal).");if(e.resources&&(e.resources.cpu!==void 0||e.resources.memory!==void 0||e.resources.disk!==void 0))throw new S("E2B cannot size a sandbox at create time: sizing is fixed by the template (Template.build cpuCount/memoryMB; disk is plan-fixed). Build a template with the desired resources and pass it as `image` instead of `resources`.");let t=e.timeoutMs??this.defaultTimeoutMs,n=e.image??this.templateId??"evolve-all";for(let a of e.phaseNetworkPolicies??[])T(a);let s=T(e.network),o=await Sandbox.create(n,{apiKey:this.apiKey,apiUrl:this.apiUrl,envs:e.envs,metadata:e.metadata,timeoutMs:t,...s});return e.workingDirectory&&await o.files.makeDir(e.workingDirectory,{user:e.user}),e.user&&this.sandboxUsers.set(o.sandboxId,e.user),new f(o,this.apiKey,this.apiUrl,e.user)}async connect(e,t){let n=await Sandbox.connect(e,{apiKey:this.apiKey,apiUrl:this.apiUrl,timeoutMs:t??this.defaultTimeoutMs});return new f(n,this.apiKey,this.apiUrl,this.sandboxUsers.get(e))}async inspect(e,t){let n=await this.fetchSandboxDetail(e);if(n.state!=="running")throw new g(e,"e2b",n.state);let s=F.attach({sandboxId:n.sandboxID,sandboxDomain:n.domain??void 0,envdVersion:n.envdVersion,envdAccessToken:n.envdAccessToken,trafficAccessToken:n.trafficAccessToken??void 0,apiKey:this.apiKey,apiUrl:this.apiUrl});return new f(s,this.apiKey,this.apiUrl,t?.user??this.sandboxUsers.get(e),n.envdVersion)}async fetchSandboxDetail(e){let t=new ConnectionConfig({apiKey:this.apiKey,apiUrl:this.apiUrl}),n=await new ApiClient(t).api.GET("/sandboxes/{sandboxID}",{params:{path:{sandboxID:e}}});if(n.error?.code===404||!n.data&&!n.error)throw new g(e,"e2b","not found");if(n.error)throw new Error(`E2B refused the sandbox record for ${e}: ${n.error.message??n.error.code}`);return n.data}async list(e){let t=await this.paginate(e);if(t.error&&!t.stoppedAtLimit)throw new Error(t.error);return t.sandboxes}async listAll(e){let{stoppedAtLimit:t,...n}=await this.paginate(e);return n}async paginate(e){let t=e?.limit;return V(Sandbox.list({apiKey:this.apiKey,apiUrl:this.apiUrl,query:{state:e?.state,metadata:e?.metadata},limit:t===void 0?L:Math.min(t,L)}),t)}};async function V(r,e){let t=[],n=0,s=new Set;for(;r.hasNext;){if(n>=K)return {sandboxes:t,complete:false,pagesFetched:n,stoppedAtLimit:false,error:`sandbox list exceeded ${K} pages`};let o=r.nextToken;if(o!==void 0){if(s.has(o))return {sandboxes:t,complete:false,pagesFetched:n,stoppedAtLimit:false,error:"pagination token repeated"};s.add(o);}let a;try{a=await r.nextItems();}catch(i){return {sandboxes:t,complete:false,pagesFetched:n,stoppedAtLimit:false,error:`sandbox list failed: ${i instanceof Error?i.message:String(i)}`}}n+=1;for(let i of a){if(e!==void 0&&t.length>=e)return {sandboxes:t,complete:false,pagesFetched:n,stoppedAtLimit:true,error:`stopped at the requested limit of ${e} with more sandboxes available`};t.push({sandboxId:i.sandboxId,image:i.templateId,name:i.name,metadata:i.metadata??{},startedAt:w(i.startedAt),endAt:i.endAt?w(i.endAt):void 0});}if(e!==void 0&&t.length>=e&&r.hasNext)return {sandboxes:t,complete:false,pagesFetched:n,stoppedAtLimit:true,error:`stopped at the requested limit of ${e} with more sandboxes available`};if(e!==void 0&&t.length>=e)break}return {sandboxes:t,complete:true,pagesFetched:n,stoppedAtLimit:false}}var ce=V,k=1024*1024,F=class r extends Sandbox{static attach(e){return new r(e)}};function le(r={}){let e=r.apiKey??process.env.E2B_API_KEY;if(!e)throw new Error("E2B API key required. Set E2B_API_KEY environment variable or pass apiKey in config. Get your key at https://e2b.dev/sign-in");return new O({...r,apiKey:e})}var pe=f;
8
- export{B as E2BBootCommandError,R as E2BCommands,C as E2BFiles,M as E2BIdleTimeoutError,A as E2BNetworkUpdateUnsupportedError,O as E2BProvider,S as E2BResourcesError,K as E2B_MAX_LIST_PAGES,L as E2B_MAX_PAGE_SIZE,te as E2B_MIN_UPDATE_NETWORK_VERSION,x as SandboxFeatureUnsupportedError,g as SandboxNotRunningError,m as SandboxPathNotFoundError,ce as _testCollectSandboxPages,pe as _testE2BSandboxImplCtor,le as createE2BProvider,q as isSandboxFeatureUnsupportedError,j as isSandboxNotRunningError,W as isSandboxPathNotFoundError};
5
+ `),A=Buffer.from(`\r
6
+ --${p}--\r
7
+ `);async function*C(){yield v;for await(let o of r(t))yield o;yield A;}try{let o=await this.uploadUrl(e),m=await fetch(o,{method:"POST",body:i.toWeb(i.from(C())),headers:{"Content-Type":`multipart/form-data; boundary=${p}`,"Content-Length":String(v.length+a+A.length)},duplex:"half"});if(!m.ok)throw new Error(`streamed upload to ${e} failed (HTTP ${m.status})`)}catch(o){console.warn(`[e2b] streamed upload of ${t} failed, falling back to a buffered write:`,o instanceof Error?o.message:o);let m=i.toWeb(r(t));await this.writeStream(e,m);}}async watchDir(e,t,r){let n=await this.sandbox.files.watchDir(e,t,{recursive:r?.recursive,timeoutMs:r?.timeoutMs,user:this.defaultUser,onExit:r?.onExit});return {stop:()=>n.stop()}}},c=class{constructor(e,t,r,n){this.sandbox=e;this.apiKey=t;this.apiUrl=r;this.commands=new w(e,n),this.files=new S(e,n);}commands;files;get sandboxId(){return this.sandbox.sandboxId}getHost(e){return Promise.resolve(this.sandbox.getHost(e))}async isRunning(){return this.sandbox.isRunning()}async getInfo(){let e=await this.sandbox.getInfo();return {sandboxId:e.sandboxId,image:e.templateId,name:e.name,metadata:e.metadata??{},startedAt:u(e.startedAt),endAt:e.endAt?u(e.endAt):void 0}}async updateNetwork(e){let t=x(e),r=this.sandbox;if(typeof r.updateNetwork!="function")throw new g(`The installed e2b client cannot change a running sandbox's network policy: Sandbox.updateNetwork requires e2b >= ${B}. Upgrade the e2b dependency (it is pulled in by @e2b/code-interpreter), or create the sandbox with the policy it needs for its whole lifetime.`);await r.updateNetwork({allowInternetAccess:t.allowInternetAccess,...t.network??{}});}async kill(){try{await this.sandbox.kill();}catch{await new Promise(e=>setTimeout(e,500)),await this.sandbox.kill();}}async pause(){await this.sandbox.betaPause({apiKey:this.apiKey,apiUrl:this.apiUrl});}},P=class{providerType="e2b";name="E2B";apiKey;apiUrl;defaultTimeoutMs;templateId;sandboxUsers=new Map;constructor(e){this.apiKey=e.apiKey,this.apiUrl=e.apiUrl,this.defaultTimeoutMs=e.defaultTimeoutMs??36e5,this.templateId=e.templateId;}async create(e){if(e.bootCommand!==void 0)throw new h;if(e.idleTimeoutMs!==void 0)throw new y;if(e.resources?.gpu!==void 0||e.resources?.gpuTypes!==void 0)throw new l("E2B offers no GPU allocation at any tier \u2014 a `resources.gpu` request cannot be enforced. Run GPU workloads on a provider that reserves GPUs (modal).");if(e.resources&&(e.resources.cpu!==void 0||e.resources.memory!==void 0||e.resources.disk!==void 0))throw new l("E2B cannot size a sandbox at create time: sizing is fixed by the template (Template.build cpuCount/memoryMB; disk is plan-fixed). Build a template with the desired resources and pass it as `image` instead of `resources`.");let t=e.timeoutMs??this.defaultTimeoutMs,r=e.image??this.templateId??"evolve-all";for(let d of e.phaseNetworkPolicies??[])x(d);let n=x(e.network),i=await Sandbox.create(r,{apiKey:this.apiKey,apiUrl:this.apiUrl,envs:e.envs,metadata:e.metadata,timeoutMs:t,...n});return e.workingDirectory&&await i.files.makeDir(e.workingDirectory,{user:e.user}),e.user&&this.sandboxUsers.set(i.sandboxId,e.user),new c(i,this.apiKey,this.apiUrl,e.user)}async connect(e,t){let r=await Sandbox.connect(e,{apiKey:this.apiKey,apiUrl:this.apiUrl,timeoutMs:t??this.defaultTimeoutMs});return new c(r,this.apiKey,this.apiUrl,this.sandboxUsers.get(e))}async list(e){let t=await this.paginate(e);if(t.error&&!t.stoppedAtLimit)throw new Error(t.error);return t.sandboxes}async listAll(e){let{stoppedAtLimit:t,...r}=await this.paginate(e);return r}async paginate(e){let t=e?.limit;return E(Sandbox.list({apiKey:this.apiKey,apiUrl:this.apiUrl,query:{state:e?.state,metadata:e?.metadata},limit:t===void 0?k:Math.min(t,k)}),t)}};async function E(s,e){let t=[],r=0,n=new Set;for(;s.hasNext;){if(r>=I)return {sandboxes:t,complete:false,pagesFetched:r,stoppedAtLimit:false,error:`sandbox list exceeded ${I} pages`};let i=s.nextToken;if(i!==void 0){if(n.has(i))return {sandboxes:t,complete:false,pagesFetched:r,stoppedAtLimit:false,error:"pagination token repeated"};n.add(i);}let d;try{d=await s.nextItems();}catch(a){return {sandboxes:t,complete:false,pagesFetched:r,stoppedAtLimit:false,error:`sandbox list failed: ${a instanceof Error?a.message:String(a)}`}}r+=1;for(let a of d){if(e!==void 0&&t.length>=e)return {sandboxes:t,complete:false,pagesFetched:r,stoppedAtLimit:true,error:`stopped at the requested limit of ${e} with more sandboxes available`};t.push({sandboxId:a.sandboxId,image:a.templateId,name:a.name,metadata:a.metadata??{},startedAt:u(a.startedAt),endAt:a.endAt?u(a.endAt):void 0});}if(e!==void 0&&t.length>=e&&s.hasNext)return {sandboxes:t,complete:false,pagesFetched:r,stoppedAtLimit:true,error:`stopped at the requested limit of ${e} with more sandboxes available`};if(e!==void 0&&t.length>=e)break}return {sandboxes:t,complete:true,pagesFetched:r,stoppedAtLimit:false}}var T=E;function M(s={}){let e=s.apiKey??process.env.E2B_API_KEY;if(!e)throw new Error("E2B API key required. Set E2B_API_KEY environment variable or pass apiKey in config. Get your key at https://e2b.dev/sign-in");return new P({...s,apiKey:e})}
8
+ export{h as E2BBootCommandError,w as E2BCommands,S as E2BFiles,y as E2BIdleTimeoutError,g as E2BNetworkUpdateUnsupportedError,P as E2BProvider,l as E2BResourcesError,I as E2B_MAX_LIST_PAGES,k as E2B_MAX_PAGE_SIZE,B as E2B_MIN_UPDATE_NETWORK_VERSION,T as _testCollectSandboxPages,M as createE2BProvider};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@evolvingmachines/e2b",
3
- "version": "0.0.59-train-2026-09-16-fs.20260917.41a409fa",
3
+ "version": "0.0.60",
4
4
  "keywords": [
5
5
  "ai",
6
6
  "agents",
@@ -33,11 +33,10 @@
33
33
  "build": "tsup --minify",
34
34
  "dev": "tsup --watch",
35
35
  "type-check": "tsc --noEmit",
36
- "test:unit": "tsx tests/unit/e2b-list-pagination.test.ts && tsx tests/unit/e2b-files-read.test.ts && tsx tests/unit/e2b-gpu-rejection.test.ts && tsx tests/unit/e2b-boot-command-rejection.test.ts && tsx tests/unit/e2b-template-refresh.test.ts && tsx tests/unit/e2b-files-observe.test.ts"
36
+ "test:unit": "tsx tests/unit/e2b-list-pagination.test.ts && tsx tests/unit/e2b-files-read.test.ts && tsx tests/unit/e2b-gpu-rejection.test.ts && tsx tests/unit/e2b-boot-command-rejection.test.ts && tsx tests/unit/e2b-template-refresh.test.ts"
37
37
  },
38
38
  "dependencies": {
39
- "@e2b/code-interpreter": "^2.7.1",
40
- "compare-versions": "^6.1.0"
39
+ "@e2b/code-interpreter": "^2.7.1"
41
40
  },
42
41
  "devDependencies": {
43
42
  "@types/node": "^22.15.18",