zeitlich 0.2.27 → 0.2.29

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.
Files changed (109) hide show
  1. package/README.md +121 -13
  2. package/dist/{activities-DE3_q9yq.d.ts → activities-1xrWRrGJ.d.cts} +2 -3
  3. package/dist/{activities-p8PDlRIK.d.cts → activities-DOViDCTE.d.ts} +2 -3
  4. package/dist/adapters/sandbox/e2b/index.cjs +230 -0
  5. package/dist/adapters/sandbox/e2b/index.cjs.map +1 -0
  6. package/dist/adapters/sandbox/e2b/index.d.cts +77 -0
  7. package/dist/adapters/sandbox/e2b/index.d.ts +77 -0
  8. package/dist/adapters/sandbox/e2b/index.js +227 -0
  9. package/dist/adapters/sandbox/e2b/index.js.map +1 -0
  10. package/dist/adapters/sandbox/{virtual → e2b}/workflow.cjs +8 -8
  11. package/dist/adapters/sandbox/e2b/workflow.cjs.map +1 -0
  12. package/dist/adapters/sandbox/e2b/workflow.d.cts +27 -0
  13. package/dist/adapters/sandbox/e2b/workflow.d.ts +27 -0
  14. package/dist/adapters/sandbox/{virtual → e2b}/workflow.js +8 -8
  15. package/dist/adapters/sandbox/e2b/workflow.js.map +1 -0
  16. package/dist/adapters/thread/anthropic/index.d.cts +5 -6
  17. package/dist/adapters/thread/anthropic/index.d.ts +5 -6
  18. package/dist/adapters/thread/anthropic/workflow.d.cts +4 -5
  19. package/dist/adapters/thread/anthropic/workflow.d.ts +4 -5
  20. package/dist/adapters/thread/google-genai/index.d.cts +5 -6
  21. package/dist/adapters/thread/google-genai/index.d.ts +5 -6
  22. package/dist/adapters/thread/google-genai/workflow.d.cts +4 -5
  23. package/dist/adapters/thread/google-genai/workflow.d.ts +4 -5
  24. package/dist/adapters/thread/langchain/index.cjs +22 -10
  25. package/dist/adapters/thread/langchain/index.cjs.map +1 -1
  26. package/dist/adapters/thread/langchain/index.d.cts +12 -10
  27. package/dist/adapters/thread/langchain/index.d.ts +12 -10
  28. package/dist/adapters/thread/langchain/index.js +22 -10
  29. package/dist/adapters/thread/langchain/index.js.map +1 -1
  30. package/dist/adapters/thread/langchain/workflow.d.cts +4 -5
  31. package/dist/adapters/thread/langchain/workflow.d.ts +4 -5
  32. package/dist/index.cjs +526 -24
  33. package/dist/index.cjs.map +1 -1
  34. package/dist/index.d.cts +66 -15
  35. package/dist/index.d.ts +66 -15
  36. package/dist/index.js +522 -26
  37. package/dist/index.js.map +1 -1
  38. package/dist/{proxy-BK1ydQt0.d.ts → proxy-78nc985d.d.ts} +1 -1
  39. package/dist/{proxy-BMAsMHdp.d.cts → proxy-Bm2UTiO_.d.cts} +1 -1
  40. package/dist/{thread-manager-dzaJHQEA.d.ts → thread-manager-07BaYu_z.d.ts} +1 -1
  41. package/dist/{thread-manager-Bz8txKKj.d.cts → thread-manager-BRE5KkHB.d.cts} +1 -1
  42. package/dist/{thread-manager-BlHua5_v.d.cts → thread-manager-CatBkarc.d.cts} +1 -1
  43. package/dist/{thread-manager-Bh9x847n.d.ts → thread-manager-CxbWo7q_.d.ts} +1 -1
  44. package/dist/types-BkVoEyiH.d.ts +1211 -0
  45. package/dist/{types-CIkYBoF8.d.ts → types-DAv_SLN8.d.ts} +1 -1
  46. package/dist/{types-BfIQABzu.d.cts → types-Dpz2gXLk.d.cts} +1 -1
  47. package/dist/types-seDYom4M.d.cts +1211 -0
  48. package/dist/workflow-B4T3la0p.d.cts +750 -0
  49. package/dist/workflow-DCmaXLZ_.d.ts +750 -0
  50. package/dist/workflow.cjs +198 -21
  51. package/dist/workflow.cjs.map +1 -1
  52. package/dist/workflow.d.cts +5 -579
  53. package/dist/workflow.d.ts +5 -579
  54. package/dist/workflow.js +197 -23
  55. package/dist/workflow.js.map +1 -1
  56. package/package.json +23 -23
  57. package/src/adapters/sandbox/{virtual → e2b}/proxy.ts +16 -13
  58. package/src/adapters/thread/langchain/hooks.test.ts +195 -0
  59. package/src/adapters/thread/langchain/hooks.ts +29 -12
  60. package/src/index.ts +7 -0
  61. package/src/lib/observability/hooks.ts +117 -0
  62. package/src/lib/observability/index.ts +13 -0
  63. package/src/lib/observability/sinks.ts +88 -0
  64. package/src/lib/sandbox/manager.ts +3 -3
  65. package/src/lib/session/session-edge-cases.integration.test.ts +1 -0
  66. package/src/lib/session/session.integration.test.ts +1 -0
  67. package/src/lib/session/session.ts +79 -5
  68. package/src/lib/session/types.ts +21 -0
  69. package/src/lib/state/manager.integration.test.ts +1 -0
  70. package/src/lib/subagent/handler.ts +22 -2
  71. package/src/lib/subagent/register.ts +7 -2
  72. package/src/lib/subagent/subagent.integration.test.ts +1 -0
  73. package/src/lib/tool-router/router-edge-cases.integration.test.ts +2 -0
  74. package/src/lib/tool-router/router.integration.test.ts +2 -0
  75. package/src/lib/tool-router/router.ts +26 -7
  76. package/src/lib/tool-router/types.ts +0 -4
  77. package/src/{adapters/sandbox/virtual → lib/virtual-fs}/filesystem.ts +4 -4
  78. package/src/lib/virtual-fs/index.ts +18 -0
  79. package/src/lib/virtual-fs/manager.ts +48 -0
  80. package/src/lib/virtual-fs/proxy.ts +45 -0
  81. package/src/{adapters/sandbox/virtual → lib/virtual-fs}/types.ts +43 -33
  82. package/src/{adapters/sandbox/virtual/virtual-sandbox.test.ts → lib/virtual-fs/virtual-fs.test.ts} +15 -130
  83. package/src/lib/virtual-fs/with-virtual-fs.ts +94 -0
  84. package/src/workflow.ts +25 -8
  85. package/tsup.config.ts +3 -2
  86. package/dist/adapters/sandbox/virtual/index.cjs +0 -487
  87. package/dist/adapters/sandbox/virtual/index.cjs.map +0 -1
  88. package/dist/adapters/sandbox/virtual/index.d.cts +0 -90
  89. package/dist/adapters/sandbox/virtual/index.d.ts +0 -90
  90. package/dist/adapters/sandbox/virtual/index.js +0 -479
  91. package/dist/adapters/sandbox/virtual/index.js.map +0 -1
  92. package/dist/adapters/sandbox/virtual/workflow.cjs.map +0 -1
  93. package/dist/adapters/sandbox/virtual/workflow.d.cts +0 -28
  94. package/dist/adapters/sandbox/virtual/workflow.d.ts +0 -28
  95. package/dist/adapters/sandbox/virtual/workflow.js.map +0 -1
  96. package/dist/queries-BCgJ9Sr5.d.ts +0 -44
  97. package/dist/queries-DwnE2bu3.d.cts +0 -44
  98. package/dist/types-CvJyXDYt.d.ts +0 -490
  99. package/dist/types-DFUNSYbj.d.ts +0 -125
  100. package/dist/types-DRnz-OZp.d.cts +0 -125
  101. package/dist/types-DSOefLpY.d.cts +0 -490
  102. package/dist/types-mCVxKIZb.d.cts +0 -585
  103. package/dist/types-mCVxKIZb.d.ts +0 -585
  104. package/src/adapters/sandbox/virtual/index.ts +0 -92
  105. package/src/adapters/sandbox/virtual/provider.ts +0 -121
  106. package/src/adapters/sandbox/virtual/with-virtual-sandbox.ts +0 -97
  107. /package/src/{adapters/sandbox/virtual → lib/virtual-fs}/mutations.ts +0 -0
  108. /package/src/{adapters/sandbox/virtual → lib/virtual-fs}/queries.ts +0 -0
  109. /package/src/{adapters/sandbox/virtual → lib/virtual-fs}/tree.ts +0 -0
package/README.md CHANGED
@@ -58,7 +58,7 @@ A sandbox adapter provides filesystem access for tools like `Bash`, `Read`, `Wri
58
58
  | Adapter | Import | Use case |
59
59
  |---------|--------|----------|
60
60
  | In-memory | `zeitlich/adapters/sandbox/inmemory` | Tests and lightweight agents |
61
- | Virtual | `zeitlich/adapters/sandbox/virtual` | Custom resolvers with path-only ops |
61
+ | Virtual FS | `zeitlich` / `zeitlich/workflow` | Built-in virtual filesystem with custom resolvers |
62
62
  | Daytona | `zeitlich/adapters/sandbox/daytona` | Remote Daytona workspaces |
63
63
  | E2B | `zeitlich/adapters/sandbox/e2b` | E2B cloud sandboxes |
64
64
  | Bedrock | `zeitlich/adapters/sandbox/bedrock` | AWS Bedrock AgentCore Code Interpreter |
@@ -774,22 +774,16 @@ This means `readFile("a/b.txt")` is treated as `/a/b.txt` across adapters.
774
774
 
775
775
  Each `fs` instance also exposes `workspaceBase`, which is the base used for relative paths.
776
776
 
777
- **Virtual sandbox example (path-only calls):**
777
+ **Virtual filesystem example (path-only calls):**
778
778
 
779
779
  ```typescript
780
- import { createVirtualSandbox, VirtualSandboxProvider } from "zeitlich";
780
+ import { VirtualFileSystem } from "zeitlich";
781
781
 
782
- const provider = new VirtualSandboxProvider(resolver);
783
- const { sandbox } = await provider.create({
784
- resolverContext: { projectId: "p1" },
785
- workspaceBase: "/repo",
786
- });
787
-
788
- const fs = sandbox.fs;
789
- console.log(fs.workspaceBase); // "/repo"
782
+ const virtualFs = new VirtualFileSystem(fileTree, resolver, { projectId: "p1" }, "/repo");
783
+ console.log(virtualFs.workspaceBase); // "/repo"
790
784
 
791
- await fs.writeFile("src/index.ts", 'export const ok = true;\n');
792
- const content = await fs.readFile("src/index.ts"); // reads /repo/src/index.ts
785
+ await virtualFs.writeFile("src/index.ts", 'export const ok = true;\n');
786
+ const content = await virtualFs.readFile("src/index.ts"); // reads /repo/src/index.ts
793
787
  ```
794
788
 
795
789
  **Daytona sandbox example (base `/home/daytona`):**
@@ -991,6 +985,120 @@ Framework-agnostic utilities for activities, worker setup, and Node.js code:
991
985
  └─────────────────┘
992
986
  ```
993
987
 
988
+ ## Observability
989
+
990
+ Zeitlich emits structured, replay-safe logs at key lifecycle points (session start/end, each turn, tool execution, subagent spawn/completion). These flow through Temporal's built-in workflow logger with zero configuration.
991
+
992
+ ### Logging
993
+
994
+ All log messages are emitted via `@temporalio/workflow`'s `log` and automatically routed to whatever logger you configure on the Temporal Runtime. By default they go to `STDERR` via `console.error`.
995
+
996
+ **Custom logger (e.g. winston):**
997
+
998
+ ```typescript
999
+ import { Runtime, makeTelemetryFilterString } from "@temporalio/worker";
1000
+ import winston from "winston";
1001
+
1002
+ const logger = winston.createLogger({
1003
+ level: "info",
1004
+ format: winston.format.json(),
1005
+ transports: [new winston.transports.File({ filename: "worker.log" })],
1006
+ });
1007
+
1008
+ Runtime.install({
1009
+ logger,
1010
+ telemetryOptions: {
1011
+ logging: {
1012
+ filter: makeTelemetryFilterString({ core: "INFO", other: "INFO" }),
1013
+ forward: {},
1014
+ },
1015
+ },
1016
+ });
1017
+ ```
1018
+
1019
+ ### Metrics via Sinks
1020
+
1021
+ For custom metrics (Prometheus, Datadog, OpenTelemetry, etc.), zeitlich provides `ZeitlichObservabilitySinks` — a typed Temporal Sinks interface that bridges agent events from the workflow sandbox to your Node.js metrics backend.
1022
+
1023
+ **1. Register sinks on the Worker:**
1024
+
1025
+ ```typescript
1026
+ import { Worker, InjectedSinks } from "@temporalio/worker";
1027
+ import type { ZeitlichObservabilitySinks } from "zeitlich/workflow";
1028
+
1029
+ const sinks: InjectedSinks<ZeitlichObservabilitySinks> = {
1030
+ zeitlichMetrics: {
1031
+ sessionStarted: {
1032
+ fn(_workflowInfo, event) {
1033
+ sessionCounter.inc({ agent: event.agentName });
1034
+ },
1035
+ callDuringReplay: false,
1036
+ },
1037
+ sessionEnded: {
1038
+ fn(_workflowInfo, event) {
1039
+ sessionDuration.observe(event.durationMs);
1040
+ tokenCounter.inc({ type: "input" }, event.usage.inputTokens ?? 0);
1041
+ },
1042
+ callDuringReplay: false,
1043
+ },
1044
+ turnCompleted: {
1045
+ fn(_workflowInfo, event) {
1046
+ turnGauge.set({ agent: event.agentName }, event.turn);
1047
+ },
1048
+ callDuringReplay: false,
1049
+ },
1050
+ toolExecuted: {
1051
+ fn(_workflowInfo, event) {
1052
+ toolDuration.observe({ tool: event.toolName }, event.durationMs);
1053
+ if (!event.success) toolErrors.inc({ tool: event.toolName });
1054
+ },
1055
+ callDuringReplay: false,
1056
+ },
1057
+ },
1058
+ };
1059
+
1060
+ const worker = await Worker.create({ sinks, /* ... */ });
1061
+ ```
1062
+
1063
+ **2. Wire hooks in your workflow:**
1064
+
1065
+ ```typescript
1066
+ import { createSession, createObservabilityHooks } from "zeitlich/workflow";
1067
+
1068
+ const session = await createSession({
1069
+ agentName: "myAgent",
1070
+ hooks: createObservabilityHooks("myAgent"),
1071
+ // ...
1072
+ });
1073
+ ```
1074
+
1075
+ Use `composeHooks()` to combine observability hooks with your own:
1076
+
1077
+ ```typescript
1078
+ import { createObservabilityHooks, composeHooks } from "zeitlich/workflow";
1079
+
1080
+ const obs = createObservabilityHooks("myAgent");
1081
+
1082
+ const session = await createSession({
1083
+ hooks: {
1084
+ ...obs,
1085
+ onSessionEnd: composeHooks(obs.onSessionEnd, (ctx) => {
1086
+ // your custom session-end logic
1087
+ }),
1088
+ },
1089
+ });
1090
+ ```
1091
+
1092
+ ### Tracing with OpenTelemetry
1093
+
1094
+ For distributed tracing across client, workflow, and activities, use Temporal's OpenTelemetry interceptor package:
1095
+
1096
+ ```bash
1097
+ npm install @temporalio/interceptors-opentelemetry @opentelemetry/sdk-node
1098
+ ```
1099
+
1100
+ See [Temporal's tracing docs](https://docs.temporal.io/develop/typescript/observability#set-up-tracing) and the [`interceptors-opentelemetry` sample](https://github.com/temporalio/samples-typescript/tree/main/interceptors-opentelemetry) for setup.
1101
+
994
1102
  ## Requirements
995
1103
 
996
1104
  - Node.js >= 18
@@ -1,8 +1,7 @@
1
1
  import Redis from 'ioredis';
2
2
  import { Part, Content, GoogleGenAI } from '@google/genai';
3
- import { R as RouterContext, T as ToolHandlerResponse, A as ActivityToolHandler } from './types-mCVxKIZb.js';
4
- import { a as ModelInvoker, P as PrefixedThreadOps, S as ScopedPrefix } from './types-CvJyXDYt.js';
5
- import { T as ThreadManagerHooks, P as ProviderThreadManager } from './types-CIkYBoF8.js';
3
+ import { a as ModelInvoker, P as PrefixedThreadOps, S as ScopedPrefix, R as RouterContext, b as ToolHandlerResponse, c as ActivityToolHandler } from './types-seDYom4M.cjs';
4
+ import { T as ThreadManagerHooks, P as ProviderThreadManager } from './types-Dpz2gXLk.cjs';
6
5
 
7
6
  /** SDK-native content type for Google GenAI human messages */
8
7
  type GoogleGenAIContent = string | Part[];
@@ -1,8 +1,7 @@
1
1
  import Redis from 'ioredis';
2
2
  import { Part, Content, GoogleGenAI } from '@google/genai';
3
- import { R as RouterContext, T as ToolHandlerResponse, A as ActivityToolHandler } from './types-mCVxKIZb.cjs';
4
- import { a as ModelInvoker, P as PrefixedThreadOps, S as ScopedPrefix } from './types-DSOefLpY.cjs';
5
- import { T as ThreadManagerHooks, P as ProviderThreadManager } from './types-BfIQABzu.cjs';
3
+ import { a as ModelInvoker, P as PrefixedThreadOps, S as ScopedPrefix, R as RouterContext, b as ToolHandlerResponse, c as ActivityToolHandler } from './types-BkVoEyiH.js';
4
+ import { T as ThreadManagerHooks, P as ProviderThreadManager } from './types-DAv_SLN8.js';
6
5
 
7
6
  /** SDK-native content type for Google GenAI human messages */
8
7
  type GoogleGenAIContent = string | Part[];
@@ -0,0 +1,230 @@
1
+ 'use strict';
2
+
3
+ var codeInterpreter = require('@e2b/code-interpreter');
4
+ var common = require('@temporalio/common');
5
+ var path = require('path');
6
+
7
+ // src/adapters/sandbox/e2b/index.ts
8
+ var SandboxNotSupportedError = class extends common.ApplicationFailure {
9
+ constructor(operation) {
10
+ super(
11
+ `Sandbox does not support: ${operation}`,
12
+ "SandboxNotSupportedError",
13
+ true
14
+ );
15
+ }
16
+ };
17
+ var SandboxNotFoundError = class extends common.ApplicationFailure {
18
+ constructor(sandboxId) {
19
+ super(`Sandbox not found: ${sandboxId}`, "SandboxNotFoundError", true);
20
+ }
21
+ };
22
+ function toArrayBuffer(u8) {
23
+ return u8.buffer.slice(u8.byteOffset, u8.byteOffset + u8.byteLength);
24
+ }
25
+ var E2bSandboxFileSystem = class {
26
+ constructor(sandbox, workspaceBase = "/home/user") {
27
+ this.sandbox = sandbox;
28
+ this.workspaceBase = path.posix.resolve("/", workspaceBase);
29
+ }
30
+ workspaceBase;
31
+ normalisePath(path$1) {
32
+ return path.posix.resolve(this.workspaceBase, path$1);
33
+ }
34
+ async readFile(path) {
35
+ return this.sandbox.files.read(this.normalisePath(path));
36
+ }
37
+ async readFileBuffer(path) {
38
+ return this.sandbox.files.read(this.normalisePath(path), {
39
+ format: "bytes"
40
+ });
41
+ }
42
+ async writeFile(path, content) {
43
+ const norm = this.normalisePath(path);
44
+ if (typeof content === "string") {
45
+ await this.sandbox.files.write(norm, content);
46
+ } else {
47
+ await this.sandbox.files.write(norm, toArrayBuffer(content));
48
+ }
49
+ }
50
+ async appendFile(path, content) {
51
+ const norm = this.normalisePath(path);
52
+ let existing = "";
53
+ try {
54
+ existing = await this.sandbox.files.read(norm);
55
+ } catch {
56
+ }
57
+ const addition = typeof content === "string" ? content : new TextDecoder().decode(content);
58
+ await this.sandbox.files.write(norm, existing + addition);
59
+ }
60
+ async exists(path) {
61
+ return this.sandbox.files.exists(this.normalisePath(path));
62
+ }
63
+ async stat(path) {
64
+ const norm = this.normalisePath(path);
65
+ const info = await this.sandbox.files.getInfo(norm);
66
+ const isSymlink = !!info.symlinkTarget;
67
+ return {
68
+ isFile: isSymlink ? false : info.type === codeInterpreter.FileType.FILE,
69
+ isDirectory: isSymlink ? false : info.type === codeInterpreter.FileType.DIR,
70
+ isSymbolicLink: isSymlink,
71
+ size: info.size,
72
+ mtime: info.modifiedTime ?? /* @__PURE__ */ new Date(0)
73
+ };
74
+ }
75
+ async mkdir(path, _options) {
76
+ await this.sandbox.files.makeDir(this.normalisePath(path));
77
+ }
78
+ async readdir(path$1) {
79
+ const entries = await this.sandbox.files.list(this.normalisePath(path$1));
80
+ return entries.map((e) => path.posix.basename(e.path));
81
+ }
82
+ async readdirWithFileTypes(path$1) {
83
+ const entries = await this.sandbox.files.list(this.normalisePath(path$1));
84
+ return entries.map((e) => {
85
+ const isSymlink = !!e.symlinkTarget;
86
+ return {
87
+ name: path.posix.basename(e.path),
88
+ isFile: isSymlink ? false : e.type === codeInterpreter.FileType.FILE,
89
+ isDirectory: isSymlink ? false : e.type === codeInterpreter.FileType.DIR,
90
+ isSymbolicLink: isSymlink
91
+ };
92
+ });
93
+ }
94
+ async rm(path, options) {
95
+ const norm = this.normalisePath(path);
96
+ try {
97
+ await this.sandbox.files.remove(norm);
98
+ } catch (err) {
99
+ if (!options?.force) throw err;
100
+ }
101
+ }
102
+ async cp(src, dest, _options) {
103
+ const normSrc = this.normalisePath(src);
104
+ const normDest = this.normalisePath(dest);
105
+ await this.sandbox.commands.run(`cp -r "${normSrc}" "${normDest}"`);
106
+ }
107
+ async mv(src, dest) {
108
+ const normSrc = this.normalisePath(src);
109
+ const normDest = this.normalisePath(dest);
110
+ await this.sandbox.files.rename(normSrc, normDest);
111
+ }
112
+ async readlink(path) {
113
+ const norm = this.normalisePath(path);
114
+ const info = await this.sandbox.files.getInfo(norm);
115
+ if (!info.symlinkTarget) {
116
+ throw new Error(`EINVAL: invalid argument, readlink '${path}'`);
117
+ }
118
+ return info.symlinkTarget;
119
+ }
120
+ resolvePath(base, path$1) {
121
+ return path.posix.resolve(this.normalisePath(base), path$1);
122
+ }
123
+ };
124
+
125
+ // src/adapters/sandbox/e2b/index.ts
126
+ var E2bSandboxImpl = class {
127
+ constructor(id, sdkSandbox, workspaceBase = "/home/user") {
128
+ this.id = id;
129
+ this.sdkSandbox = sdkSandbox;
130
+ this.fs = new E2bSandboxFileSystem(sdkSandbox, workspaceBase);
131
+ }
132
+ capabilities = {
133
+ filesystem: true,
134
+ execution: true,
135
+ persistence: true
136
+ };
137
+ fs;
138
+ async exec(command, options) {
139
+ const result = await this.sdkSandbox.commands.run(command, {
140
+ cwd: options?.cwd,
141
+ envs: options?.env,
142
+ timeoutMs: options?.timeout
143
+ });
144
+ return {
145
+ exitCode: result.exitCode,
146
+ stdout: result.stdout,
147
+ stderr: result.stderr
148
+ };
149
+ }
150
+ async destroy() {
151
+ await this.sdkSandbox.kill();
152
+ }
153
+ };
154
+ var E2bSandboxProvider = class {
155
+ id = "e2b";
156
+ capabilities = {
157
+ filesystem: true,
158
+ execution: true,
159
+ persistence: true
160
+ };
161
+ defaultTemplate;
162
+ defaultWorkspaceBase;
163
+ defaultTimeoutMs;
164
+ constructor(config) {
165
+ this.defaultTemplate = config?.template;
166
+ this.defaultWorkspaceBase = config?.workspaceBase ?? "/home/user";
167
+ this.defaultTimeoutMs = config?.timeoutMs;
168
+ }
169
+ async create(options) {
170
+ const template = options?.template ?? this.defaultTemplate;
171
+ const workspaceBase = this.defaultWorkspaceBase;
172
+ const createOpts = {
173
+ envs: options?.env,
174
+ timeoutMs: options?.timeoutMs ?? this.defaultTimeoutMs
175
+ };
176
+ const sdkSandbox = template ? await codeInterpreter.Sandbox.create(template, createOpts) : await codeInterpreter.Sandbox.create(createOpts);
177
+ const sandbox = new E2bSandboxImpl(
178
+ sdkSandbox.sandboxId,
179
+ sdkSandbox,
180
+ workspaceBase
181
+ );
182
+ if (options?.initialFiles) {
183
+ await Promise.all(
184
+ Object.entries(options.initialFiles).map(
185
+ ([path, content]) => sandbox.fs.writeFile(path, content)
186
+ )
187
+ );
188
+ }
189
+ return { sandbox };
190
+ }
191
+ async get(sandboxId) {
192
+ try {
193
+ const sdkSandbox = await codeInterpreter.Sandbox.connect(sandboxId);
194
+ return new E2bSandboxImpl(sandboxId, sdkSandbox, this.defaultWorkspaceBase);
195
+ } catch {
196
+ throw new SandboxNotFoundError(sandboxId);
197
+ }
198
+ }
199
+ async destroy(sandboxId) {
200
+ try {
201
+ const sdkSandbox = await codeInterpreter.Sandbox.connect(sandboxId);
202
+ await sdkSandbox.kill();
203
+ } catch {
204
+ }
205
+ }
206
+ async pause(sandboxId, _ttlSeconds) {
207
+ const sdkSandbox = await codeInterpreter.Sandbox.connect(sandboxId);
208
+ await sdkSandbox.pause();
209
+ }
210
+ async snapshot(_sandboxId) {
211
+ throw new SandboxNotSupportedError("snapshot");
212
+ }
213
+ async restore(_snapshot) {
214
+ throw new SandboxNotSupportedError("restore");
215
+ }
216
+ async fork(sandboxId) {
217
+ const { snapshotId } = await codeInterpreter.Sandbox.createSnapshot(sandboxId);
218
+ const sdkSandbox = await codeInterpreter.Sandbox.create(snapshotId);
219
+ return new E2bSandboxImpl(
220
+ sdkSandbox.sandboxId,
221
+ sdkSandbox,
222
+ this.defaultWorkspaceBase
223
+ );
224
+ }
225
+ };
226
+
227
+ exports.E2bSandboxFileSystem = E2bSandboxFileSystem;
228
+ exports.E2bSandboxProvider = E2bSandboxProvider;
229
+ //# sourceMappingURL=index.cjs.map
230
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/lib/sandbox/types.ts","../../../../src/adapters/sandbox/e2b/filesystem.ts","../../../../src/adapters/sandbox/e2b/index.ts"],"names":["ApplicationFailure","posix","path","FileType","E2bSdkSandbox"],"mappings":"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","file":"index.cjs","sourcesContent":["// ============================================================================\n// Sandbox Filesystem\n// ============================================================================\n\nexport interface DirentEntry {\n name: string;\n isFile: boolean;\n isDirectory: boolean;\n isSymbolicLink: boolean;\n}\n\nexport interface FileStat {\n isFile: boolean;\n isDirectory: boolean;\n isSymbolicLink: boolean;\n size: number;\n mtime: Date;\n}\n\n/**\n * Provider-agnostic filesystem interface.\n *\n * Implementations that don't support a method should throw\n * {@link SandboxNotSupportedError}.\n */\nexport interface SandboxFileSystem {\n /** Base directory used when resolving relative paths. */\n readonly workspaceBase: string;\n readFile(path: string): Promise<string>;\n readFileBuffer(path: string): Promise<Uint8Array>;\n writeFile(path: string, content: string | Uint8Array): Promise<void>;\n appendFile(path: string, content: string | Uint8Array): Promise<void>;\n exists(path: string): Promise<boolean>;\n stat(path: string): Promise<FileStat>;\n mkdir(path: string, options?: { recursive?: boolean }): Promise<void>;\n readdir(path: string): Promise<string[]>;\n readdirWithFileTypes(path: string): Promise<DirentEntry[]>;\n rm(\n path: string,\n options?: { recursive?: boolean; force?: boolean }\n ): Promise<void>;\n cp(\n src: string,\n dest: string,\n options?: { recursive?: boolean }\n ): Promise<void>;\n mv(src: string, dest: string): Promise<void>;\n readlink(path: string): Promise<string>;\n resolvePath(base: string, path: string): string;\n}\n\n// ============================================================================\n// Execution\n// ============================================================================\n\nexport interface ExecOptions {\n timeout?: number;\n cwd?: string;\n env?: Record<string, string>;\n}\n\nexport interface ExecResult {\n exitCode: number;\n stdout: string;\n stderr: string;\n}\n\n// ============================================================================\n// Capabilities\n// ============================================================================\n\nexport interface SandboxCapabilities {\n /** Sandbox supports filesystem operations */\n filesystem: boolean;\n /** Sandbox supports shell/command execution */\n execution: boolean;\n /** Sandbox state can be persisted and restored */\n persistence: boolean;\n}\n\n// ============================================================================\n// Sandbox\n// ============================================================================\n\nexport interface Sandbox {\n readonly id: string;\n readonly capabilities: SandboxCapabilities;\n readonly fs: SandboxFileSystem;\n\n exec(command: string, options?: ExecOptions): Promise<ExecResult>;\n destroy(): Promise<void>;\n}\n\n// ============================================================================\n// Snapshots\n// ============================================================================\n\nexport interface SandboxSnapshot {\n sandboxId: string;\n providerId: string;\n /** Provider-specific serialised state */\n data: unknown;\n createdAt: string;\n}\n\n// ============================================================================\n// Provider\n// ============================================================================\n\nexport interface SandboxCreateOptions {\n /** Preferred sandbox ID (provider may ignore) */\n id?: string;\n /** Seed the filesystem with these files */\n initialFiles?: Record<string, string | Uint8Array>;\n /** Environment variables available inside the sandbox */\n env?: Record<string, string>;\n}\n\nexport interface SandboxCreateResult {\n sandbox: Sandbox;\n /** Optional state to merge into the workflow's `AgentState` via the session. */\n stateUpdate?: Record<string, unknown>;\n}\n\nexport interface SandboxProvider<\n TOptions extends SandboxCreateOptions = SandboxCreateOptions,\n TSandbox extends Sandbox = Sandbox,\n> {\n readonly id: string;\n readonly capabilities: SandboxCapabilities;\n\n create(options?: TOptions): Promise<SandboxCreateResult>;\n get(sandboxId: string): Promise<TSandbox>;\n destroy(sandboxId: string): Promise<void>;\n pause(sandboxId: string, ttlSeconds?: number): Promise<void>;\n snapshot(sandboxId: string): Promise<SandboxSnapshot>;\n restore(snapshot: SandboxSnapshot): Promise<Sandbox>;\n fork(sandboxId: string): Promise<Sandbox>;\n}\n\n// ============================================================================\n// SandboxOps — workflow-side activity interface (like ThreadOps)\n// ============================================================================\n\nexport interface SandboxOps<\n TOptions extends SandboxCreateOptions = SandboxCreateOptions,\n> {\n createSandbox(\n options?: TOptions\n ): Promise<{ sandboxId: string; stateUpdate?: Record<string, unknown> }>;\n destroySandbox(sandboxId: string): Promise<void>;\n pauseSandbox(sandboxId: string): Promise<void>;\n snapshotSandbox(sandboxId: string): Promise<SandboxSnapshot>;\n forkSandbox(sandboxId: string): Promise<string>;\n}\n\n/**\n * Maps generic {@link SandboxOps} method names to adapter-prefixed names.\n *\n * @example\n * ```typescript\n * type InMemOps = PrefixedSandboxOps<\"inMemory\">;\n * // → { inMemoryCreateSandbox, inMemoryDestroySandbox, inMemorySnapshotSandbox }\n * ```\n */\nexport type PrefixedSandboxOps<\n TPrefix extends string,\n TOptions extends SandboxCreateOptions = SandboxCreateOptions,\n> = {\n [K in keyof SandboxOps<TOptions> as `${TPrefix}${Capitalize<K & string>}`]: SandboxOps<TOptions>[K];\n};\n\n// ============================================================================\n// Errors\n// ============================================================================\n\nimport { ApplicationFailure } from \"@temporalio/common\";\n\nexport class SandboxNotSupportedError extends ApplicationFailure {\n constructor(operation: string) {\n super(\n `Sandbox does not support: ${operation}`,\n \"SandboxNotSupportedError\",\n true\n );\n }\n}\n\nexport class SandboxNotFoundError extends ApplicationFailure {\n constructor(sandboxId: string) {\n super(`Sandbox not found: ${sandboxId}`, \"SandboxNotFoundError\", true);\n }\n}\n","import { FileType, type Sandbox as E2bSdkSandbox } from \"@e2b/code-interpreter\";\nimport type {\n SandboxFileSystem,\n DirentEntry,\n FileStat,\n} from \"../../../lib/sandbox/types\";\nimport { posix } from \"node:path\";\n\nfunction toArrayBuffer(u8: Uint8Array): ArrayBuffer {\n return u8.buffer.slice(u8.byteOffset, u8.byteOffset + u8.byteLength) as ArrayBuffer;\n}\n\n/**\n * {@link SandboxFileSystem} backed by an E2B SDK sandbox.\n *\n * Maps zeitlich's filesystem interface to E2B's `sandbox.files` and\n * `sandbox.commands` APIs. Operations that have no direct E2B equivalent\n * (e.g. `appendFile`, `cp`) are composed from primitives.\n */\nexport class E2bSandboxFileSystem implements SandboxFileSystem {\n readonly workspaceBase: string;\n\n constructor(\n private sandbox: E2bSdkSandbox,\n workspaceBase = \"/home/user\"\n ) {\n this.workspaceBase = posix.resolve(\"/\", workspaceBase);\n }\n\n private normalisePath(path: string): string {\n return posix.resolve(this.workspaceBase, path);\n }\n\n async readFile(path: string): Promise<string> {\n return this.sandbox.files.read(this.normalisePath(path));\n }\n\n async readFileBuffer(path: string): Promise<Uint8Array> {\n return this.sandbox.files.read(this.normalisePath(path), {\n format: \"bytes\",\n });\n }\n\n async writeFile(path: string, content: string | Uint8Array): Promise<void> {\n const norm = this.normalisePath(path);\n if (typeof content === \"string\") {\n await this.sandbox.files.write(norm, content);\n } else {\n await this.sandbox.files.write(norm, toArrayBuffer(content));\n }\n }\n\n async appendFile(path: string, content: string | Uint8Array): Promise<void> {\n const norm = this.normalisePath(path);\n let existing = \"\";\n try {\n existing = await this.sandbox.files.read(norm);\n } catch {\n // file doesn't exist yet — write from scratch\n }\n const addition =\n typeof content === \"string\"\n ? content\n : new TextDecoder().decode(content);\n await this.sandbox.files.write(norm, existing + addition);\n }\n\n async exists(path: string): Promise<boolean> {\n return this.sandbox.files.exists(this.normalisePath(path));\n }\n\n async stat(path: string): Promise<FileStat> {\n const norm = this.normalisePath(path);\n const info = await this.sandbox.files.getInfo(norm);\n const isSymlink = !!info.symlinkTarget;\n return {\n isFile: isSymlink ? false : info.type === FileType.FILE,\n isDirectory: isSymlink ? false : info.type === FileType.DIR,\n isSymbolicLink: isSymlink,\n size: info.size,\n mtime: info.modifiedTime ?? new Date(0),\n };\n }\n\n async mkdir(path: string, _options?: { recursive?: boolean }): Promise<void> {\n await this.sandbox.files.makeDir(this.normalisePath(path));\n }\n\n async readdir(path: string): Promise<string[]> {\n const entries = await this.sandbox.files.list(this.normalisePath(path));\n return entries.map((e) => posix.basename(e.path));\n }\n\n async readdirWithFileTypes(path: string): Promise<DirentEntry[]> {\n const entries = await this.sandbox.files.list(this.normalisePath(path));\n return entries.map((e) => {\n const isSymlink = !!e.symlinkTarget;\n return {\n name: posix.basename(e.path),\n isFile: isSymlink ? false : e.type === FileType.FILE,\n isDirectory: isSymlink ? false : e.type === FileType.DIR,\n isSymbolicLink: isSymlink,\n };\n });\n }\n\n async rm(\n path: string,\n options?: { recursive?: boolean; force?: boolean }\n ): Promise<void> {\n const norm = this.normalisePath(path);\n try {\n await this.sandbox.files.remove(norm);\n } catch (err) {\n if (!options?.force) throw err;\n }\n }\n\n async cp(\n src: string,\n dest: string,\n _options?: { recursive?: boolean }\n ): Promise<void> {\n const normSrc = this.normalisePath(src);\n const normDest = this.normalisePath(dest);\n await this.sandbox.commands.run(`cp -r \"${normSrc}\" \"${normDest}\"`);\n }\n\n async mv(src: string, dest: string): Promise<void> {\n const normSrc = this.normalisePath(src);\n const normDest = this.normalisePath(dest);\n await this.sandbox.files.rename(normSrc, normDest);\n }\n\n async readlink(path: string): Promise<string> {\n const norm = this.normalisePath(path);\n const info = await this.sandbox.files.getInfo(norm);\n if (!info.symlinkTarget) {\n throw new Error(`EINVAL: invalid argument, readlink '${path}'`);\n }\n return info.symlinkTarget;\n }\n\n resolvePath(base: string, path: string): string {\n return posix.resolve(this.normalisePath(base), path);\n }\n}\n","import { Sandbox as E2bSdkSandbox } from \"@e2b/code-interpreter\";\nimport type {\n Sandbox,\n SandboxCapabilities,\n SandboxCreateResult,\n SandboxProvider,\n SandboxSnapshot,\n ExecOptions,\n ExecResult,\n} from \"../../../lib/sandbox/types\";\nimport {\n SandboxNotFoundError,\n SandboxNotSupportedError,\n} from \"../../../lib/sandbox/types\";\nimport { E2bSandboxFileSystem } from \"./filesystem\";\nimport type {\n E2bSandbox,\n E2bSandboxConfig,\n E2bSandboxCreateOptions,\n} from \"./types\";\n\n// ============================================================================\n// E2bSandbox\n// ============================================================================\n\nclass E2bSandboxImpl implements Sandbox {\n readonly capabilities: SandboxCapabilities = {\n filesystem: true,\n execution: true,\n persistence: true,\n };\n\n readonly fs: E2bSandboxFileSystem;\n\n constructor(\n readonly id: string,\n private sdkSandbox: E2bSdkSandbox,\n workspaceBase = \"/home/user\"\n ) {\n this.fs = new E2bSandboxFileSystem(sdkSandbox, workspaceBase);\n }\n\n async exec(command: string, options?: ExecOptions): Promise<ExecResult> {\n const result = await this.sdkSandbox.commands.run(command, {\n cwd: options?.cwd,\n envs: options?.env,\n timeoutMs: options?.timeout,\n });\n return {\n exitCode: result.exitCode,\n stdout: result.stdout,\n stderr: result.stderr,\n };\n }\n\n async destroy(): Promise<void> {\n await this.sdkSandbox.kill();\n }\n}\n\n// ============================================================================\n// E2bSandboxProvider\n// ============================================================================\n\nexport class E2bSandboxProvider\n implements SandboxProvider<E2bSandboxCreateOptions, E2bSandbox>\n{\n readonly id = \"e2b\";\n readonly capabilities: SandboxCapabilities = {\n filesystem: true,\n execution: true,\n persistence: true,\n };\n\n private readonly defaultTemplate?: string;\n private readonly defaultWorkspaceBase: string;\n private readonly defaultTimeoutMs?: number;\n\n constructor(config?: E2bSandboxConfig) {\n this.defaultTemplate = config?.template;\n this.defaultWorkspaceBase = config?.workspaceBase ?? \"/home/user\";\n this.defaultTimeoutMs = config?.timeoutMs;\n }\n\n async create(\n options?: E2bSandboxCreateOptions\n ): Promise<SandboxCreateResult> {\n const template = options?.template ?? this.defaultTemplate;\n const workspaceBase = this.defaultWorkspaceBase;\n const createOpts = {\n envs: options?.env,\n timeoutMs: options?.timeoutMs ?? this.defaultTimeoutMs,\n };\n\n const sdkSandbox = template\n ? await E2bSdkSandbox.create(template, createOpts)\n : await E2bSdkSandbox.create(createOpts);\n\n const sandbox = new E2bSandboxImpl(\n sdkSandbox.sandboxId,\n sdkSandbox,\n workspaceBase\n );\n\n if (options?.initialFiles) {\n await Promise.all(\n Object.entries(options.initialFiles).map(([path, content]) =>\n sandbox.fs.writeFile(path, content)\n )\n );\n }\n\n return { sandbox };\n }\n\n async get(sandboxId: string): Promise<E2bSandbox> {\n try {\n const sdkSandbox = await E2bSdkSandbox.connect(sandboxId);\n return new E2bSandboxImpl(sandboxId, sdkSandbox, this.defaultWorkspaceBase);\n } catch {\n throw new SandboxNotFoundError(sandboxId);\n }\n }\n\n async destroy(sandboxId: string): Promise<void> {\n try {\n const sdkSandbox = await E2bSdkSandbox.connect(sandboxId);\n await sdkSandbox.kill();\n } catch {\n // Already gone or not found\n }\n }\n\n async pause(sandboxId: string, _ttlSeconds?: number): Promise<void> {\n const sdkSandbox = await E2bSdkSandbox.connect(sandboxId);\n await sdkSandbox.pause();\n }\n\n async snapshot(_sandboxId: string): Promise<SandboxSnapshot> {\n throw new SandboxNotSupportedError(\"snapshot\");\n }\n\n async restore(_snapshot: SandboxSnapshot): Promise<Sandbox> {\n throw new SandboxNotSupportedError(\"restore\");\n }\n\n async fork(sandboxId: string): Promise<Sandbox> {\n const { snapshotId } = await E2bSdkSandbox.createSnapshot(sandboxId);\n const sdkSandbox = await E2bSdkSandbox.create(snapshotId);\n return new E2bSandboxImpl(\n sdkSandbox.sandboxId,\n sdkSandbox,\n this.defaultWorkspaceBase\n );\n }\n}\n\n// Re-exports\nexport { E2bSandboxFileSystem } from \"./filesystem\";\nexport type {\n E2bSandbox,\n E2bSandboxConfig,\n E2bSandboxCreateOptions,\n} from \"./types\";\n"]}
@@ -0,0 +1,77 @@
1
+ import { a as SandboxFileSystem, F as FileStat, D as DirentEntry, S as Sandbox$1, d as SandboxCreateOptions, b as SandboxProvider, c as SandboxCapabilities, e as SandboxCreateResult, f as SandboxSnapshot } from '../../../types-ChAMwU3q.cjs';
2
+ import { Sandbox } from '@e2b/code-interpreter';
3
+ import '@temporalio/common';
4
+
5
+ /**
6
+ * {@link SandboxFileSystem} backed by an E2B SDK sandbox.
7
+ *
8
+ * Maps zeitlich's filesystem interface to E2B's `sandbox.files` and
9
+ * `sandbox.commands` APIs. Operations that have no direct E2B equivalent
10
+ * (e.g. `appendFile`, `cp`) are composed from primitives.
11
+ */
12
+ declare class E2bSandboxFileSystem implements SandboxFileSystem {
13
+ private sandbox;
14
+ readonly workspaceBase: string;
15
+ constructor(sandbox: Sandbox, workspaceBase?: string);
16
+ private normalisePath;
17
+ readFile(path: string): Promise<string>;
18
+ readFileBuffer(path: string): Promise<Uint8Array>;
19
+ writeFile(path: string, content: string | Uint8Array): Promise<void>;
20
+ appendFile(path: string, content: string | Uint8Array): Promise<void>;
21
+ exists(path: string): Promise<boolean>;
22
+ stat(path: string): Promise<FileStat>;
23
+ mkdir(path: string, _options?: {
24
+ recursive?: boolean;
25
+ }): Promise<void>;
26
+ readdir(path: string): Promise<string[]>;
27
+ readdirWithFileTypes(path: string): Promise<DirentEntry[]>;
28
+ rm(path: string, options?: {
29
+ recursive?: boolean;
30
+ force?: boolean;
31
+ }): Promise<void>;
32
+ cp(src: string, dest: string, _options?: {
33
+ recursive?: boolean;
34
+ }): Promise<void>;
35
+ mv(src: string, dest: string): Promise<void>;
36
+ readlink(path: string): Promise<string>;
37
+ resolvePath(base: string, path: string): string;
38
+ }
39
+
40
+ /**
41
+ * An E2B-backed {@link Sandbox} with its typed filesystem.
42
+ */
43
+ type E2bSandbox = Sandbox$1 & {
44
+ fs: E2bSandboxFileSystem;
45
+ };
46
+ interface E2bSandboxConfig {
47
+ /** Sandbox template name or ID */
48
+ template?: string;
49
+ /** Default working directory inside the sandbox */
50
+ workspaceBase?: string;
51
+ /** Sandbox idle timeout in milliseconds */
52
+ timeoutMs?: number;
53
+ }
54
+ interface E2bSandboxCreateOptions extends SandboxCreateOptions {
55
+ /** Sandbox template name or ID — overrides the provider default */
56
+ template?: string;
57
+ /** Sandbox idle timeout in milliseconds — overrides the provider default */
58
+ timeoutMs?: number;
59
+ }
60
+
61
+ declare class E2bSandboxProvider implements SandboxProvider<E2bSandboxCreateOptions, E2bSandbox> {
62
+ readonly id = "e2b";
63
+ readonly capabilities: SandboxCapabilities;
64
+ private readonly defaultTemplate?;
65
+ private readonly defaultWorkspaceBase;
66
+ private readonly defaultTimeoutMs?;
67
+ constructor(config?: E2bSandboxConfig);
68
+ create(options?: E2bSandboxCreateOptions): Promise<SandboxCreateResult>;
69
+ get(sandboxId: string): Promise<E2bSandbox>;
70
+ destroy(sandboxId: string): Promise<void>;
71
+ pause(sandboxId: string, _ttlSeconds?: number): Promise<void>;
72
+ snapshot(_sandboxId: string): Promise<SandboxSnapshot>;
73
+ restore(_snapshot: SandboxSnapshot): Promise<Sandbox$1>;
74
+ fork(sandboxId: string): Promise<Sandbox$1>;
75
+ }
76
+
77
+ export { type E2bSandbox, type E2bSandboxConfig, type E2bSandboxCreateOptions, E2bSandboxFileSystem, E2bSandboxProvider };
@@ -0,0 +1,77 @@
1
+ import { a as SandboxFileSystem, F as FileStat, D as DirentEntry, S as Sandbox$1, d as SandboxCreateOptions, b as SandboxProvider, c as SandboxCapabilities, e as SandboxCreateResult, f as SandboxSnapshot } from '../../../types-ChAMwU3q.js';
2
+ import { Sandbox } from '@e2b/code-interpreter';
3
+ import '@temporalio/common';
4
+
5
+ /**
6
+ * {@link SandboxFileSystem} backed by an E2B SDK sandbox.
7
+ *
8
+ * Maps zeitlich's filesystem interface to E2B's `sandbox.files` and
9
+ * `sandbox.commands` APIs. Operations that have no direct E2B equivalent
10
+ * (e.g. `appendFile`, `cp`) are composed from primitives.
11
+ */
12
+ declare class E2bSandboxFileSystem implements SandboxFileSystem {
13
+ private sandbox;
14
+ readonly workspaceBase: string;
15
+ constructor(sandbox: Sandbox, workspaceBase?: string);
16
+ private normalisePath;
17
+ readFile(path: string): Promise<string>;
18
+ readFileBuffer(path: string): Promise<Uint8Array>;
19
+ writeFile(path: string, content: string | Uint8Array): Promise<void>;
20
+ appendFile(path: string, content: string | Uint8Array): Promise<void>;
21
+ exists(path: string): Promise<boolean>;
22
+ stat(path: string): Promise<FileStat>;
23
+ mkdir(path: string, _options?: {
24
+ recursive?: boolean;
25
+ }): Promise<void>;
26
+ readdir(path: string): Promise<string[]>;
27
+ readdirWithFileTypes(path: string): Promise<DirentEntry[]>;
28
+ rm(path: string, options?: {
29
+ recursive?: boolean;
30
+ force?: boolean;
31
+ }): Promise<void>;
32
+ cp(src: string, dest: string, _options?: {
33
+ recursive?: boolean;
34
+ }): Promise<void>;
35
+ mv(src: string, dest: string): Promise<void>;
36
+ readlink(path: string): Promise<string>;
37
+ resolvePath(base: string, path: string): string;
38
+ }
39
+
40
+ /**
41
+ * An E2B-backed {@link Sandbox} with its typed filesystem.
42
+ */
43
+ type E2bSandbox = Sandbox$1 & {
44
+ fs: E2bSandboxFileSystem;
45
+ };
46
+ interface E2bSandboxConfig {
47
+ /** Sandbox template name or ID */
48
+ template?: string;
49
+ /** Default working directory inside the sandbox */
50
+ workspaceBase?: string;
51
+ /** Sandbox idle timeout in milliseconds */
52
+ timeoutMs?: number;
53
+ }
54
+ interface E2bSandboxCreateOptions extends SandboxCreateOptions {
55
+ /** Sandbox template name or ID — overrides the provider default */
56
+ template?: string;
57
+ /** Sandbox idle timeout in milliseconds — overrides the provider default */
58
+ timeoutMs?: number;
59
+ }
60
+
61
+ declare class E2bSandboxProvider implements SandboxProvider<E2bSandboxCreateOptions, E2bSandbox> {
62
+ readonly id = "e2b";
63
+ readonly capabilities: SandboxCapabilities;
64
+ private readonly defaultTemplate?;
65
+ private readonly defaultWorkspaceBase;
66
+ private readonly defaultTimeoutMs?;
67
+ constructor(config?: E2bSandboxConfig);
68
+ create(options?: E2bSandboxCreateOptions): Promise<SandboxCreateResult>;
69
+ get(sandboxId: string): Promise<E2bSandbox>;
70
+ destroy(sandboxId: string): Promise<void>;
71
+ pause(sandboxId: string, _ttlSeconds?: number): Promise<void>;
72
+ snapshot(_sandboxId: string): Promise<SandboxSnapshot>;
73
+ restore(_snapshot: SandboxSnapshot): Promise<Sandbox$1>;
74
+ fork(sandboxId: string): Promise<Sandbox$1>;
75
+ }
76
+
77
+ export { type E2bSandbox, type E2bSandboxConfig, type E2bSandboxCreateOptions, E2bSandboxFileSystem, E2bSandboxProvider };