@evolvingmachines/e2b 0.0.60 → 0.0.61
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 +5 -5
- package/dist/index.d.cts +91 -13
- package/dist/index.d.ts +91 -13
- package/dist/index.js +5 -5
- package/package.json +4 -3
package/dist/index.cjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
'use strict';var codeInterpreter=require('@e2b/code-interpreter');function
|
|
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
|
|
2
2
|
Content-Disposition: form-data; name="file"; filename="blob"\r
|
|
3
3
|
Content-Type: application/octet-stream\r
|
|
4
4
|
\r
|
|
5
|
-
`),
|
|
6
|
-
--${
|
|
7
|
-
`);async function*
|
|
8
|
-
exports.E2BBootCommandError=
|
|
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;
|
package/dist/index.d.cts
CHANGED
|
@@ -1,9 +1,37 @@
|
|
|
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
|
+
|
|
3
30
|
/**
|
|
4
31
|
* E2B Sandbox Provider - Clean Architecture
|
|
5
32
|
*
|
|
6
|
-
* @requires @e2b/code-interpreter >=
|
|
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)
|
|
7
35
|
* @requires Node.js >= 18 (for ReadableStream support)
|
|
8
36
|
*
|
|
9
37
|
* Design principles:
|
|
@@ -110,18 +138,27 @@ interface SandboxInfo {
|
|
|
110
138
|
/** End time (undefined for running sandboxes) */
|
|
111
139
|
endAt?: string;
|
|
112
140
|
}
|
|
113
|
-
/**
|
|
141
|
+
/** The SDK contract's FileInfo (sdk-ts types.ts), the same entry on every provider. */
|
|
114
142
|
interface FileInfo {
|
|
115
143
|
name: string;
|
|
116
144
|
path: string;
|
|
117
|
-
type: "file" | "dir";
|
|
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;
|
|
118
157
|
}
|
|
119
|
-
/**
|
|
158
|
+
/** One filesystem change from watchDir: an absolute path, four kinds. */
|
|
120
159
|
interface FilesystemEvent {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
/** Type of filesystem operation */
|
|
124
|
-
type: "create" | "remove" | "rename" | "chmod" | "write";
|
|
160
|
+
path: string;
|
|
161
|
+
type: "create" | "write" | "remove" | "rename";
|
|
125
162
|
}
|
|
126
163
|
/** Handle to stop watching a directory */
|
|
127
164
|
interface WatchHandle {
|
|
@@ -129,9 +166,21 @@ interface WatchHandle {
|
|
|
129
166
|
}
|
|
130
167
|
/** Options for watching a directory */
|
|
131
168
|
interface WatchOptions {
|
|
169
|
+
/** Also report changes in every subdirectory. Default false. */
|
|
132
170
|
recursive?: boolean;
|
|
133
|
-
|
|
134
|
-
|
|
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;
|
|
135
184
|
}
|
|
136
185
|
/** Options for blocking sandbox command execution */
|
|
137
186
|
interface SandboxRunOptions {
|
|
@@ -285,6 +334,10 @@ interface SandboxFiles {
|
|
|
285
334
|
remove(path: string): Promise<void>;
|
|
286
335
|
/** Rename or move file/directory */
|
|
287
336
|
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>;
|
|
288
341
|
/** Watch directory for changes */
|
|
289
342
|
watchDir(path: string, onEvent: (event: FilesystemEvent) => void | Promise<void>, options?: WatchOptions): Promise<WatchHandle>;
|
|
290
343
|
}
|
|
@@ -299,6 +352,8 @@ interface SandboxInstance {
|
|
|
299
352
|
isRunning(): Promise<boolean>;
|
|
300
353
|
/** Get sandbox metadata and timing */
|
|
301
354
|
getInfo(): Promise<SandboxInfo>;
|
|
355
|
+
/** The newest resource-usage sample, or null while there is none yet */
|
|
356
|
+
metrics(): Promise<SandboxMetrics | null>;
|
|
302
357
|
/** Terminate sandbox */
|
|
303
358
|
kill(): Promise<void>;
|
|
304
359
|
/** Pause sandbox (preserves state) */
|
|
@@ -316,6 +371,8 @@ interface SandboxProvider {
|
|
|
316
371
|
create(options: SandboxCreateOptions): Promise<SandboxInstance>;
|
|
317
372
|
/** Connect to existing sandbox */
|
|
318
373
|
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>;
|
|
319
376
|
/** List sandboxes, paginating to exhaustion. `limit` bounds items returned. */
|
|
320
377
|
list(options?: SandboxListOptions): Promise<SandboxInfo[]>;
|
|
321
378
|
/** The same enumeration for fleet bookkeeping: never throws, reports completeness. */
|
|
@@ -351,7 +408,10 @@ declare class E2BCommands implements SandboxCommands {
|
|
|
351
408
|
declare class E2BFiles implements SandboxFiles {
|
|
352
409
|
private sandbox;
|
|
353
410
|
private defaultUser?;
|
|
354
|
-
|
|
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;
|
|
355
415
|
read(path: string): Promise<string | Uint8Array>;
|
|
356
416
|
write(path: string, content: string | Buffer | ArrayBuffer | Uint8Array): Promise<void>;
|
|
357
417
|
writeBatch(files: Array<{
|
|
@@ -363,6 +423,8 @@ declare class E2BFiles implements SandboxFiles {
|
|
|
363
423
|
downloadUrl(path: string, expiresInSeconds?: number): Promise<string>;
|
|
364
424
|
exists(path: string): Promise<boolean>;
|
|
365
425
|
list(path: string): Promise<FileInfo[]>;
|
|
426
|
+
stat(path: string): Promise<FileInfo>;
|
|
427
|
+
readRange(path: string, range: FileRange): Promise<Uint8Array>;
|
|
366
428
|
remove(path: string): Promise<void>;
|
|
367
429
|
rename(oldPath: string, newPath: string): Promise<void>;
|
|
368
430
|
readStream(path: string): Promise<ReadableStream<Uint8Array>>;
|
|
@@ -398,8 +460,11 @@ declare class E2BSandboxImpl implements SandboxInstance {
|
|
|
398
460
|
private apiUrl?;
|
|
399
461
|
readonly commands: SandboxCommands;
|
|
400
462
|
readonly files: SandboxFiles;
|
|
401
|
-
|
|
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);
|
|
402
466
|
get sandboxId(): string;
|
|
467
|
+
metrics(): Promise<SandboxMetrics | null>;
|
|
403
468
|
getHost(port: number): Promise<string>;
|
|
404
469
|
isRunning(): Promise<boolean>;
|
|
405
470
|
getInfo(): Promise<SandboxInfo>;
|
|
@@ -444,6 +509,8 @@ declare class E2BProvider implements SandboxProvider {
|
|
|
444
509
|
constructor(config: ResolvedE2BConfig);
|
|
445
510
|
create(options: SandboxCreateOptions): Promise<SandboxInstance>;
|
|
446
511
|
connect(sandboxId: string, timeoutMs?: number): Promise<SandboxInstance>;
|
|
512
|
+
inspect(sandboxId: string, options?: SandboxInspectOptions): Promise<SandboxInstance>;
|
|
513
|
+
protected fetchSandboxDetail(sandboxId: string): Promise<E2BSandboxDetail>;
|
|
447
514
|
/**
|
|
448
515
|
* List sandboxes, walking every page.
|
|
449
516
|
*
|
|
@@ -500,6 +567,15 @@ declare function collectSandboxPages(paginator: E2BSandboxPaginator, wanted?: nu
|
|
|
500
567
|
stoppedAtLimit: boolean;
|
|
501
568
|
}>;
|
|
502
569
|
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
|
+
}
|
|
503
579
|
/**
|
|
504
580
|
* Create E2B sandbox provider.
|
|
505
581
|
*
|
|
@@ -515,5 +591,7 @@ declare function createE2BProvider(config?: E2BConfig): SandboxProvider;
|
|
|
515
591
|
* the type (never the constructor) gives the seam the real methods to pin.
|
|
516
592
|
*/
|
|
517
593
|
type _testE2BSandboxImpl = E2BSandboxImpl;
|
|
594
|
+
/** The constructor, for the metrics unit test (a vendor sandbox double goes in). */
|
|
595
|
+
declare const _testE2BSandboxImplCtor: typeof E2BSandboxImpl;
|
|
518
596
|
|
|
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 };
|
|
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 };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,37 @@
|
|
|
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
|
+
|
|
3
30
|
/**
|
|
4
31
|
* E2B Sandbox Provider - Clean Architecture
|
|
5
32
|
*
|
|
6
|
-
* @requires @e2b/code-interpreter >=
|
|
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)
|
|
7
35
|
* @requires Node.js >= 18 (for ReadableStream support)
|
|
8
36
|
*
|
|
9
37
|
* Design principles:
|
|
@@ -110,18 +138,27 @@ interface SandboxInfo {
|
|
|
110
138
|
/** End time (undefined for running sandboxes) */
|
|
111
139
|
endAt?: string;
|
|
112
140
|
}
|
|
113
|
-
/**
|
|
141
|
+
/** The SDK contract's FileInfo (sdk-ts types.ts), the same entry on every provider. */
|
|
114
142
|
interface FileInfo {
|
|
115
143
|
name: string;
|
|
116
144
|
path: string;
|
|
117
|
-
type: "file" | "dir";
|
|
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;
|
|
118
157
|
}
|
|
119
|
-
/**
|
|
158
|
+
/** One filesystem change from watchDir: an absolute path, four kinds. */
|
|
120
159
|
interface FilesystemEvent {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
/** Type of filesystem operation */
|
|
124
|
-
type: "create" | "remove" | "rename" | "chmod" | "write";
|
|
160
|
+
path: string;
|
|
161
|
+
type: "create" | "write" | "remove" | "rename";
|
|
125
162
|
}
|
|
126
163
|
/** Handle to stop watching a directory */
|
|
127
164
|
interface WatchHandle {
|
|
@@ -129,9 +166,21 @@ interface WatchHandle {
|
|
|
129
166
|
}
|
|
130
167
|
/** Options for watching a directory */
|
|
131
168
|
interface WatchOptions {
|
|
169
|
+
/** Also report changes in every subdirectory. Default false. */
|
|
132
170
|
recursive?: boolean;
|
|
133
|
-
|
|
134
|
-
|
|
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;
|
|
135
184
|
}
|
|
136
185
|
/** Options for blocking sandbox command execution */
|
|
137
186
|
interface SandboxRunOptions {
|
|
@@ -285,6 +334,10 @@ interface SandboxFiles {
|
|
|
285
334
|
remove(path: string): Promise<void>;
|
|
286
335
|
/** Rename or move file/directory */
|
|
287
336
|
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>;
|
|
288
341
|
/** Watch directory for changes */
|
|
289
342
|
watchDir(path: string, onEvent: (event: FilesystemEvent) => void | Promise<void>, options?: WatchOptions): Promise<WatchHandle>;
|
|
290
343
|
}
|
|
@@ -299,6 +352,8 @@ interface SandboxInstance {
|
|
|
299
352
|
isRunning(): Promise<boolean>;
|
|
300
353
|
/** Get sandbox metadata and timing */
|
|
301
354
|
getInfo(): Promise<SandboxInfo>;
|
|
355
|
+
/** The newest resource-usage sample, or null while there is none yet */
|
|
356
|
+
metrics(): Promise<SandboxMetrics | null>;
|
|
302
357
|
/** Terminate sandbox */
|
|
303
358
|
kill(): Promise<void>;
|
|
304
359
|
/** Pause sandbox (preserves state) */
|
|
@@ -316,6 +371,8 @@ interface SandboxProvider {
|
|
|
316
371
|
create(options: SandboxCreateOptions): Promise<SandboxInstance>;
|
|
317
372
|
/** Connect to existing sandbox */
|
|
318
373
|
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>;
|
|
319
376
|
/** List sandboxes, paginating to exhaustion. `limit` bounds items returned. */
|
|
320
377
|
list(options?: SandboxListOptions): Promise<SandboxInfo[]>;
|
|
321
378
|
/** The same enumeration for fleet bookkeeping: never throws, reports completeness. */
|
|
@@ -351,7 +408,10 @@ declare class E2BCommands implements SandboxCommands {
|
|
|
351
408
|
declare class E2BFiles implements SandboxFiles {
|
|
352
409
|
private sandbox;
|
|
353
410
|
private defaultUser?;
|
|
354
|
-
|
|
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;
|
|
355
415
|
read(path: string): Promise<string | Uint8Array>;
|
|
356
416
|
write(path: string, content: string | Buffer | ArrayBuffer | Uint8Array): Promise<void>;
|
|
357
417
|
writeBatch(files: Array<{
|
|
@@ -363,6 +423,8 @@ declare class E2BFiles implements SandboxFiles {
|
|
|
363
423
|
downloadUrl(path: string, expiresInSeconds?: number): Promise<string>;
|
|
364
424
|
exists(path: string): Promise<boolean>;
|
|
365
425
|
list(path: string): Promise<FileInfo[]>;
|
|
426
|
+
stat(path: string): Promise<FileInfo>;
|
|
427
|
+
readRange(path: string, range: FileRange): Promise<Uint8Array>;
|
|
366
428
|
remove(path: string): Promise<void>;
|
|
367
429
|
rename(oldPath: string, newPath: string): Promise<void>;
|
|
368
430
|
readStream(path: string): Promise<ReadableStream<Uint8Array>>;
|
|
@@ -398,8 +460,11 @@ declare class E2BSandboxImpl implements SandboxInstance {
|
|
|
398
460
|
private apiUrl?;
|
|
399
461
|
readonly commands: SandboxCommands;
|
|
400
462
|
readonly files: SandboxFiles;
|
|
401
|
-
|
|
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);
|
|
402
466
|
get sandboxId(): string;
|
|
467
|
+
metrics(): Promise<SandboxMetrics | null>;
|
|
403
468
|
getHost(port: number): Promise<string>;
|
|
404
469
|
isRunning(): Promise<boolean>;
|
|
405
470
|
getInfo(): Promise<SandboxInfo>;
|
|
@@ -444,6 +509,8 @@ declare class E2BProvider implements SandboxProvider {
|
|
|
444
509
|
constructor(config: ResolvedE2BConfig);
|
|
445
510
|
create(options: SandboxCreateOptions): Promise<SandboxInstance>;
|
|
446
511
|
connect(sandboxId: string, timeoutMs?: number): Promise<SandboxInstance>;
|
|
512
|
+
inspect(sandboxId: string, options?: SandboxInspectOptions): Promise<SandboxInstance>;
|
|
513
|
+
protected fetchSandboxDetail(sandboxId: string): Promise<E2BSandboxDetail>;
|
|
447
514
|
/**
|
|
448
515
|
* List sandboxes, walking every page.
|
|
449
516
|
*
|
|
@@ -500,6 +567,15 @@ declare function collectSandboxPages(paginator: E2BSandboxPaginator, wanted?: nu
|
|
|
500
567
|
stoppedAtLimit: boolean;
|
|
501
568
|
}>;
|
|
502
569
|
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
|
+
}
|
|
503
579
|
/**
|
|
504
580
|
* Create E2B sandbox provider.
|
|
505
581
|
*
|
|
@@ -515,5 +591,7 @@ declare function createE2BProvider(config?: E2BConfig): SandboxProvider;
|
|
|
515
591
|
* the type (never the constructor) gives the seam the real methods to pin.
|
|
516
592
|
*/
|
|
517
593
|
type _testE2BSandboxImpl = E2BSandboxImpl;
|
|
594
|
+
/** The constructor, for the metrics unit test (a vendor sandbox double goes in). */
|
|
595
|
+
declare const _testE2BSandboxImplCtor: typeof E2BSandboxImpl;
|
|
518
596
|
|
|
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 };
|
|
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 };
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {Sandbox}from'@e2b/code-interpreter';function
|
|
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
|
|
2
2
|
Content-Disposition: form-data; name="file"; filename="blob"\r
|
|
3
3
|
Content-Type: application/octet-stream\r
|
|
4
4
|
\r
|
|
5
|
-
`),
|
|
6
|
-
--${
|
|
7
|
-
`);async function*
|
|
8
|
-
export{
|
|
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};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@evolvingmachines/e2b",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.61",
|
|
4
4
|
"keywords": [
|
|
5
5
|
"ai",
|
|
6
6
|
"agents",
|
|
@@ -33,10 +33,11 @@
|
|
|
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"
|
|
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"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@e2b/code-interpreter": "^2.7.1"
|
|
39
|
+
"@e2b/code-interpreter": "^2.7.1",
|
|
40
|
+
"compare-versions": "^6.1.0"
|
|
40
41
|
},
|
|
41
42
|
"devDependencies": {
|
|
42
43
|
"@types/node": "^22.15.18",
|