@evolvingmachines/e2b 0.0.52-project-sable.20260815.143c2cd → 0.0.52-project-sable.20260824.3dfecab

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');function g(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 P=100,v=100;function u(s){return s instanceof Date?s.toISOString():String(s)}function A(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=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";}},x=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(g(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(g(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(g(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))}},h=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,A(t),{requestTimeoutMs:3e5,user:this.defaultUser});}async writeBatch(e){let t=e.map(r=>({path:r.path,data:A(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:o}=await import('crypto'),a=n(t).size,f=`----evolve${o(16).toString("hex")}`,w=Buffer.from(`--${f}\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
- `),S=Buffer.from(`\r
6
- --${f}--\r
7
- `);async function*I(){yield w;for await(let d of r(t))yield d;yield S;}try{let d=await this.uploadUrl(e),m=await fetch(d,{method:"POST",body:i.toWeb(i.from(I())),headers:{"Content-Type":`multipart/form-data; boundary=${f}`,"Content-Length":String(w.length+a+S.length)},duplex:"half"});if(!m.ok)throw new Error(`streamed upload to ${e} failed (HTTP ${m.status})`)}catch(d){console.warn(`[e2b] streamed upload of ${t} failed, falling back to a buffered write:`,d instanceof Error?d.message:d);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 x(e,n),this.files=new h(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 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});}},y=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.idleTimeoutMs!==void 0)throw new b;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";if(e.network?.outbound==="open"&&e.network.allowedDestinations?.length)throw new Error("network.allowedDestinations is only valid when outbound is blocked");let n=e.network?.allowedDestinations??[],i=e.network?.outbound==="blocked"&&n.length>0,o=await codeInterpreter.Sandbox.create(r,{apiKey:this.apiKey,apiUrl:this.apiUrl,envs:e.envs,metadata:e.metadata,timeoutMs:t,allowInternetAccess:e.network?.outbound!=="blocked"||i,network:i?{denyOut:["0.0.0.0/0"],allowOut:n}:void 0});return e.workingDirectory&&await o.files.makeDir(e.workingDirectory,{user:e.user}),e.user&&this.sandboxUsers.set(o.sandboxId,e.user),new c(o,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 U(codeInterpreter.Sandbox.list({apiKey:this.apiKey,apiUrl:this.apiUrl,query:{state:e?.state,metadata:e?.metadata},limit:t===void 0?P:Math.min(t,P)}),t)}};async function U(s,e){let t=[],r=0,n=new Set;for(;s.hasNext;){if(r>=v)return {sandboxes:t,complete:false,pagesFetched:r,stoppedAtLimit:false,error:`sandbox list exceeded ${v} 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 o;try{o=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 o){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 E=U;function C(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 y({...s,apiKey:e})}
8
- exports.E2BCommands=x;exports.E2BFiles=h;exports.E2BIdleTimeoutError=b;exports.E2BProvider=y;exports.E2BResourcesError=l;exports.E2B_MAX_LIST_PAGES=v;exports.E2B_MAX_PAGE_SIZE=P;exports._testCollectSandboxPages=E;exports.createE2BProvider=C;
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
@@ -37,6 +37,35 @@ declare const E2B_MAX_LIST_PAGES = 100;
37
37
  declare class E2BResourcesError extends Error {
38
38
  constructor(message: string);
39
39
  }
40
+ /**
41
+ * Minimum `e2b` client that can switch a running sandbox's egress.
42
+ *
43
+ * 2.25.0, per e2b's own release notes: "Add `Sandbox.updateNetwork` /
44
+ * `update_network` to replace a running sandbox's egress configuration"
45
+ * (e2b@2.25.0). Confirmed against the published type declarations — absent in
46
+ * 2.24.0, present in 2.25.0.
47
+ *
48
+ * IT SAID 2.26.0 UNTIL THE RELEASE NOTES WERE READ. That number came from a
49
+ * binary search over published tarballs that happened to sample only even
50
+ * minors, so 2.25.0 was never tested and the first "present" result looked
51
+ * like the boundary. The search was sound and the conclusion was still wrong
52
+ * by one release — which is the argument for reading the vendor's own record
53
+ * rather than inferring version history from artifacts.
54
+ */
55
+ declare const E2B_MIN_UPDATE_NETWORK_VERSION = "2.25.0";
56
+ /**
57
+ * Typed error for a runtime egress switch the INSTALLED client cannot make.
58
+ *
59
+ * E2B the service supports it; an older `e2b` package simply has no method to
60
+ * call. That distinction matters to whoever reads this: the fix is a
61
+ * dependency bump, not a plan change or a different provider. Refused loudly
62
+ * rather than skipped, because a policy switch that quietly does nothing
63
+ * leaves the sandbox running under the previous policy — which, when the
64
+ * switch was meant to TIGHTEN egress, is the failure nobody notices.
65
+ */
66
+ declare class E2BNetworkUpdateUnsupportedError extends Error {
67
+ constructor(message: string);
68
+ }
40
69
  /**
41
70
  * Typed error for an idle timeout E2B cannot enforce. E2B has exactly one
42
71
  * clock and it is absolute: the sandbox is killed when its timeout expires,
@@ -44,6 +73,9 @@ declare class E2BResourcesError extends Error {
44
73
  * deadline — never what the sandbox is or is not doing. An `idleTimeoutMs`
45
74
  * would therefore be silently ignored, so it is refused instead.
46
75
  */
76
+ declare class E2BBootCommandError extends Error {
77
+ constructor();
78
+ }
47
79
  declare class E2BIdleTimeoutError extends Error {
48
80
  constructor();
49
81
  }
@@ -138,6 +170,13 @@ interface SandboxCreateOptions {
138
170
  * map this onto and honouring it would be a lie.
139
171
  */
140
172
  idleTimeoutMs?: number;
173
+ /**
174
+ * REJECTED with E2BBootCommandError. The sandbox boots the template's own
175
+ * init — a start command is a template-BUILD field (startCmd) this provider
176
+ * never sets, so a create-time argv cannot be honored. The boot is already
177
+ * inert; exec the process after create instead.
178
+ */
179
+ bootCommand?: string[];
141
180
  workingDirectory?: string;
142
181
  /**
143
182
  * Per-sandbox compute sizing (cpu cores, memory GiB, disk GiB). E2B sizes
@@ -158,6 +197,23 @@ interface SandboxCreateOptions {
158
197
  outbound: "open" | "blocked";
159
198
  allowedDestinations?: string[];
160
199
  };
200
+ /**
201
+ * Every policy `updateNetwork()` may later be asked for on this box.
202
+ *
203
+ * ACCEPTED AND IGNORED HERE, deliberately. It exists because on modal the
204
+ * create call decides whether switching is possible at all, and a box built
205
+ * the blunt way can never be widened. E2B has no such constraint — it
206
+ * switches freely at any time — so this changes nothing about the sandbox
207
+ * it creates.
208
+ *
209
+ * Declared anyway so the option means the SAME thing in every provider
210
+ * package: a caller reading these types must not conclude that E2B
211
+ * cannot do phase switching because the option is missing here.
212
+ */
213
+ phaseNetworkPolicies?: Array<{
214
+ outbound: "open" | "blocked";
215
+ allowedDestinations?: string[];
216
+ }>;
161
217
  /** Run all commands and file operations as this user (passed on every E2B operation that supports it). */
162
218
  user?: string;
163
219
  /** Home directory used by the SDK for agent config paths; not consumed by the provider. */
@@ -247,6 +303,8 @@ interface SandboxInstance {
247
303
  kill(): Promise<void>;
248
304
  /** Pause sandbox (preserves state) */
249
305
  pause(): Promise<void>;
306
+ /** Replace the outbound network policy of the running sandbox. */
307
+ updateNetwork(network: SandboxCreateOptions["network"]): Promise<void>;
250
308
  }
251
309
  /** Sandbox lifecycle management */
252
310
  interface SandboxProvider {
@@ -334,6 +392,41 @@ declare class E2BFiles implements SandboxFiles {
334
392
  writeFromPath(sandboxPath: string, localPath: string): Promise<void>;
335
393
  watchDir(path: string, onEvent: (event: FilesystemEvent) => void | Promise<void>, options?: WatchOptions): Promise<WatchHandle>;
336
394
  }
395
+ declare class E2BSandboxImpl implements SandboxInstance {
396
+ private sandbox;
397
+ private apiKey;
398
+ private apiUrl?;
399
+ readonly commands: SandboxCommands;
400
+ readonly files: SandboxFiles;
401
+ constructor(sandbox: Sandbox, apiKey: string, apiUrl?: string | undefined, defaultUser?: string);
402
+ get sandboxId(): string;
403
+ getHost(port: number): Promise<string>;
404
+ isRunning(): Promise<boolean>;
405
+ getInfo(): Promise<SandboxInfo>;
406
+ /**
407
+ * Replace the running sandbox's outbound policy — E2B's
408
+ * `Sandbox.updateNetwork`: "Update the network configuration of the sandbox.
409
+ * Replaces the current egress configuration atomically — fields that are
410
+ * omitted are cleared on the server." (from the published e2b 2.25.0+ type
411
+ * declarations for Sandbox.updateNetwork).
412
+ *
413
+ * That "omitted fields are cleared" rule is why the whole policy is sent
414
+ * every time and never a delta: mapNetworkPolicy always states
415
+ * allowInternetAccess, and states `network` only when an allowlist is in
416
+ * force — so switching from an allowlist to a sealed box clears the
417
+ * allowlist by the server's own rule rather than by a second call that could
418
+ * fail in between and leave the box half-switched.
419
+ *
420
+ * VERSION GATE. `updateNetwork` landed in e2b 2.25.0; the client resolved in
421
+ * this workspace today is older and has no such method. Feature-detected
422
+ * rather than assumed, and refused loudly when absent — a `catch` around a
423
+ * missing method, or an early return, would leave the sandbox on its
424
+ * previous policy while the caller believes the switch happened.
425
+ */
426
+ updateNetwork(network: SandboxCreateOptions["network"]): Promise<void>;
427
+ kill(): Promise<void>;
428
+ pause(): Promise<void>;
429
+ }
337
430
  declare class E2BProvider implements SandboxProvider {
338
431
  readonly providerType: "e2b";
339
432
  readonly name = "E2B";
@@ -414,5 +507,13 @@ declare const _testCollectSandboxPages: typeof collectSandboxPages;
414
507
  * @throws Error if apiKey cannot be resolved
415
508
  */
416
509
  declare function createE2BProvider(config?: E2BConfig): SandboxProvider;
510
+ /**
511
+ * TYPE-ONLY handle on the concrete sandbox class, for the contract-conformance
512
+ * seam. create() is declared to return the local SandboxInstance INTERFACE, so
513
+ * a seam reading create()'s return type checks the interface and never the
514
+ * class — which let a narrowed method on the class pass unnoticed. Exporting
515
+ * the type (never the constructor) gives the seam the real methods to pin.
516
+ */
517
+ type _testE2BSandboxImpl = E2BSandboxImpl;
417
518
 
418
- export { E2BCommands, type E2BConfig, E2BFiles, E2BIdleTimeoutError, E2BProvider, E2BResourcesError, type E2BSandboxPaginator, E2B_MAX_LIST_PAGES, E2B_MAX_PAGE_SIZE, 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, createE2BProvider };
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
@@ -37,6 +37,35 @@ declare const E2B_MAX_LIST_PAGES = 100;
37
37
  declare class E2BResourcesError extends Error {
38
38
  constructor(message: string);
39
39
  }
40
+ /**
41
+ * Minimum `e2b` client that can switch a running sandbox's egress.
42
+ *
43
+ * 2.25.0, per e2b's own release notes: "Add `Sandbox.updateNetwork` /
44
+ * `update_network` to replace a running sandbox's egress configuration"
45
+ * (e2b@2.25.0). Confirmed against the published type declarations — absent in
46
+ * 2.24.0, present in 2.25.0.
47
+ *
48
+ * IT SAID 2.26.0 UNTIL THE RELEASE NOTES WERE READ. That number came from a
49
+ * binary search over published tarballs that happened to sample only even
50
+ * minors, so 2.25.0 was never tested and the first "present" result looked
51
+ * like the boundary. The search was sound and the conclusion was still wrong
52
+ * by one release — which is the argument for reading the vendor's own record
53
+ * rather than inferring version history from artifacts.
54
+ */
55
+ declare const E2B_MIN_UPDATE_NETWORK_VERSION = "2.25.0";
56
+ /**
57
+ * Typed error for a runtime egress switch the INSTALLED client cannot make.
58
+ *
59
+ * E2B the service supports it; an older `e2b` package simply has no method to
60
+ * call. That distinction matters to whoever reads this: the fix is a
61
+ * dependency bump, not a plan change or a different provider. Refused loudly
62
+ * rather than skipped, because a policy switch that quietly does nothing
63
+ * leaves the sandbox running under the previous policy — which, when the
64
+ * switch was meant to TIGHTEN egress, is the failure nobody notices.
65
+ */
66
+ declare class E2BNetworkUpdateUnsupportedError extends Error {
67
+ constructor(message: string);
68
+ }
40
69
  /**
41
70
  * Typed error for an idle timeout E2B cannot enforce. E2B has exactly one
42
71
  * clock and it is absolute: the sandbox is killed when its timeout expires,
@@ -44,6 +73,9 @@ declare class E2BResourcesError extends Error {
44
73
  * deadline — never what the sandbox is or is not doing. An `idleTimeoutMs`
45
74
  * would therefore be silently ignored, so it is refused instead.
46
75
  */
76
+ declare class E2BBootCommandError extends Error {
77
+ constructor();
78
+ }
47
79
  declare class E2BIdleTimeoutError extends Error {
48
80
  constructor();
49
81
  }
@@ -138,6 +170,13 @@ interface SandboxCreateOptions {
138
170
  * map this onto and honouring it would be a lie.
139
171
  */
140
172
  idleTimeoutMs?: number;
173
+ /**
174
+ * REJECTED with E2BBootCommandError. The sandbox boots the template's own
175
+ * init — a start command is a template-BUILD field (startCmd) this provider
176
+ * never sets, so a create-time argv cannot be honored. The boot is already
177
+ * inert; exec the process after create instead.
178
+ */
179
+ bootCommand?: string[];
141
180
  workingDirectory?: string;
142
181
  /**
143
182
  * Per-sandbox compute sizing (cpu cores, memory GiB, disk GiB). E2B sizes
@@ -158,6 +197,23 @@ interface SandboxCreateOptions {
158
197
  outbound: "open" | "blocked";
159
198
  allowedDestinations?: string[];
160
199
  };
200
+ /**
201
+ * Every policy `updateNetwork()` may later be asked for on this box.
202
+ *
203
+ * ACCEPTED AND IGNORED HERE, deliberately. It exists because on modal the
204
+ * create call decides whether switching is possible at all, and a box built
205
+ * the blunt way can never be widened. E2B has no such constraint — it
206
+ * switches freely at any time — so this changes nothing about the sandbox
207
+ * it creates.
208
+ *
209
+ * Declared anyway so the option means the SAME thing in every provider
210
+ * package: a caller reading these types must not conclude that E2B
211
+ * cannot do phase switching because the option is missing here.
212
+ */
213
+ phaseNetworkPolicies?: Array<{
214
+ outbound: "open" | "blocked";
215
+ allowedDestinations?: string[];
216
+ }>;
161
217
  /** Run all commands and file operations as this user (passed on every E2B operation that supports it). */
162
218
  user?: string;
163
219
  /** Home directory used by the SDK for agent config paths; not consumed by the provider. */
@@ -247,6 +303,8 @@ interface SandboxInstance {
247
303
  kill(): Promise<void>;
248
304
  /** Pause sandbox (preserves state) */
249
305
  pause(): Promise<void>;
306
+ /** Replace the outbound network policy of the running sandbox. */
307
+ updateNetwork(network: SandboxCreateOptions["network"]): Promise<void>;
250
308
  }
251
309
  /** Sandbox lifecycle management */
252
310
  interface SandboxProvider {
@@ -334,6 +392,41 @@ declare class E2BFiles implements SandboxFiles {
334
392
  writeFromPath(sandboxPath: string, localPath: string): Promise<void>;
335
393
  watchDir(path: string, onEvent: (event: FilesystemEvent) => void | Promise<void>, options?: WatchOptions): Promise<WatchHandle>;
336
394
  }
395
+ declare class E2BSandboxImpl implements SandboxInstance {
396
+ private sandbox;
397
+ private apiKey;
398
+ private apiUrl?;
399
+ readonly commands: SandboxCommands;
400
+ readonly files: SandboxFiles;
401
+ constructor(sandbox: Sandbox, apiKey: string, apiUrl?: string | undefined, defaultUser?: string);
402
+ get sandboxId(): string;
403
+ getHost(port: number): Promise<string>;
404
+ isRunning(): Promise<boolean>;
405
+ getInfo(): Promise<SandboxInfo>;
406
+ /**
407
+ * Replace the running sandbox's outbound policy — E2B's
408
+ * `Sandbox.updateNetwork`: "Update the network configuration of the sandbox.
409
+ * Replaces the current egress configuration atomically — fields that are
410
+ * omitted are cleared on the server." (from the published e2b 2.25.0+ type
411
+ * declarations for Sandbox.updateNetwork).
412
+ *
413
+ * That "omitted fields are cleared" rule is why the whole policy is sent
414
+ * every time and never a delta: mapNetworkPolicy always states
415
+ * allowInternetAccess, and states `network` only when an allowlist is in
416
+ * force — so switching from an allowlist to a sealed box clears the
417
+ * allowlist by the server's own rule rather than by a second call that could
418
+ * fail in between and leave the box half-switched.
419
+ *
420
+ * VERSION GATE. `updateNetwork` landed in e2b 2.25.0; the client resolved in
421
+ * this workspace today is older and has no such method. Feature-detected
422
+ * rather than assumed, and refused loudly when absent — a `catch` around a
423
+ * missing method, or an early return, would leave the sandbox on its
424
+ * previous policy while the caller believes the switch happened.
425
+ */
426
+ updateNetwork(network: SandboxCreateOptions["network"]): Promise<void>;
427
+ kill(): Promise<void>;
428
+ pause(): Promise<void>;
429
+ }
337
430
  declare class E2BProvider implements SandboxProvider {
338
431
  readonly providerType: "e2b";
339
432
  readonly name = "E2B";
@@ -414,5 +507,13 @@ declare const _testCollectSandboxPages: typeof collectSandboxPages;
414
507
  * @throws Error if apiKey cannot be resolved
415
508
  */
416
509
  declare function createE2BProvider(config?: E2BConfig): SandboxProvider;
510
+ /**
511
+ * TYPE-ONLY handle on the concrete sandbox class, for the contract-conformance
512
+ * seam. create() is declared to return the local SandboxInstance INTERFACE, so
513
+ * a seam reading create()'s return type checks the interface and never the
514
+ * class — which let a narrowed method on the class pass unnoticed. Exporting
515
+ * the type (never the constructor) gives the seam the real methods to pin.
516
+ */
517
+ type _testE2BSandboxImpl = E2BSandboxImpl;
417
518
 
418
- export { E2BCommands, type E2BConfig, E2BFiles, E2BIdleTimeoutError, E2BProvider, E2BResourcesError, type E2BSandboxPaginator, E2B_MAX_LIST_PAGES, E2B_MAX_PAGE_SIZE, 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, createE2BProvider };
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}from'@e2b/code-interpreter';function g(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 P=100,v=100;function u(s){return s instanceof Date?s.toISOString():String(s)}function A(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=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";}},x=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(g(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(g(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(g(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))}},h=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,A(t),{requestTimeoutMs:3e5,user:this.defaultUser});}async writeBatch(e){let t=e.map(r=>({path:r.path,data:A(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:o}=await import('crypto'),a=n(t).size,f=`----evolve${o(16).toString("hex")}`,w=Buffer.from(`--${f}\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
- `),S=Buffer.from(`\r
6
- --${f}--\r
7
- `);async function*I(){yield w;for await(let d of r(t))yield d;yield S;}try{let d=await this.uploadUrl(e),m=await fetch(d,{method:"POST",body:i.toWeb(i.from(I())),headers:{"Content-Type":`multipart/form-data; boundary=${f}`,"Content-Length":String(w.length+a+S.length)},duplex:"half"});if(!m.ok)throw new Error(`streamed upload to ${e} failed (HTTP ${m.status})`)}catch(d){console.warn(`[e2b] streamed upload of ${t} failed, falling back to a buffered write:`,d instanceof Error?d.message:d);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 x(e,n),this.files=new h(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 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});}},y=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.idleTimeoutMs!==void 0)throw new b;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";if(e.network?.outbound==="open"&&e.network.allowedDestinations?.length)throw new Error("network.allowedDestinations is only valid when outbound is blocked");let n=e.network?.allowedDestinations??[],i=e.network?.outbound==="blocked"&&n.length>0,o=await Sandbox.create(r,{apiKey:this.apiKey,apiUrl:this.apiUrl,envs:e.envs,metadata:e.metadata,timeoutMs:t,allowInternetAccess:e.network?.outbound!=="blocked"||i,network:i?{denyOut:["0.0.0.0/0"],allowOut:n}:void 0});return e.workingDirectory&&await o.files.makeDir(e.workingDirectory,{user:e.user}),e.user&&this.sandboxUsers.set(o.sandboxId,e.user),new c(o,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 U(Sandbox.list({apiKey:this.apiKey,apiUrl:this.apiUrl,query:{state:e?.state,metadata:e?.metadata},limit:t===void 0?P:Math.min(t,P)}),t)}};async function U(s,e){let t=[],r=0,n=new Set;for(;s.hasNext;){if(r>=v)return {sandboxes:t,complete:false,pagesFetched:r,stoppedAtLimit:false,error:`sandbox list exceeded ${v} 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 o;try{o=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 o){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 E=U;function C(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 y({...s,apiKey:e})}
8
- export{x as E2BCommands,h as E2BFiles,b as E2BIdleTimeoutError,y as E2BProvider,l as E2BResourcesError,v as E2B_MAX_LIST_PAGES,P as E2B_MAX_PAGE_SIZE,E as _testCollectSandboxPages,C as createE2BProvider};
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.52-project-sable.20260815.143c2cd",
3
+ "version": "0.0.52-project-sable.20260824.3dfecab",
4
4
  "keywords": [
5
5
  "ai",
6
6
  "agents",
@@ -33,10 +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"
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.0.1"
39
+ "@e2b/code-interpreter": "^2.7.1"
40
40
  },
41
41
  "devDependencies": {
42
42
  "@types/node": "^22.15.18",