@langchain/deno 0.0.1
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/README.md +289 -0
- package/dist/index.cjs +727 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +576 -0
- package/dist/index.d.ts +576 -0
- package/dist/index.js +721 -0
- package/dist/index.js.map +1 -0
- package/package.json +71 -0
package/README.md
ADDED
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
# @langchain/deno
|
|
2
|
+
|
|
3
|
+
Deno Sandbox backend for [deepagents](https://www.npmjs.com/package/deepagents). This package provides a `DenoSandbox` implementation of the `SandboxBackendProtocol`, enabling agents to execute commands, read/write files, and manage isolated Linux microVM environments using Deno Deploy's Sandbox infrastructure.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@langchain/deno)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
|
|
8
|
+
## Features
|
|
9
|
+
|
|
10
|
+
- **Isolated Execution**: Run commands in secure, isolated Linux microVMs
|
|
11
|
+
- **File Operations**: Upload and download files with full filesystem access
|
|
12
|
+
- **BaseSandbox Integration**: All inherited methods (`read`, `write`, `edit`, `ls`, `grep`, `glob`) work out of the box
|
|
13
|
+
- **Factory Pattern**: Compatible with deepagents' middleware architecture
|
|
14
|
+
- **Full SDK Access**: Access the underlying Deno SDK via the `sandbox` property for advanced features
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
# npm
|
|
20
|
+
npm install @langchain/deno
|
|
21
|
+
|
|
22
|
+
# yarn
|
|
23
|
+
yarn add @langchain/deno
|
|
24
|
+
|
|
25
|
+
# pnpm
|
|
26
|
+
pnpm add @langchain/deno
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Authentication Setup
|
|
30
|
+
|
|
31
|
+
The package requires Deno Deploy authentication:
|
|
32
|
+
|
|
33
|
+
### Environment Variable (Recommended)
|
|
34
|
+
|
|
35
|
+
1. Go to [https://app.deno.com](https://app.deno.com)
|
|
36
|
+
2. Navigate to Settings → Organization Tokens
|
|
37
|
+
3. Create a new token and set it as an environment variable:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
export DENO_DEPLOY_TOKEN=your_token_here
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Explicit Token in Code
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
const sandbox = await DenoSandbox.create({
|
|
47
|
+
auth: { token: "your-token-here" },
|
|
48
|
+
});
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Basic Usage
|
|
52
|
+
|
|
53
|
+
```typescript
|
|
54
|
+
import { createDeepAgent } from "deepagents";
|
|
55
|
+
import { ChatAnthropic } from "@langchain/anthropic";
|
|
56
|
+
import { DenoSandbox } from "@langchain/deno";
|
|
57
|
+
|
|
58
|
+
// Create and initialize the sandbox
|
|
59
|
+
const sandbox = await DenoSandbox.create({
|
|
60
|
+
memoryMb: 1024,
|
|
61
|
+
lifetime: "10m",
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
try {
|
|
65
|
+
const agent = createDeepAgent({
|
|
66
|
+
model: new ChatAnthropic({ model: "claude-sonnet-4-20250514" }),
|
|
67
|
+
systemPrompt: "You are a coding assistant with access to a sandbox.",
|
|
68
|
+
backend: sandbox,
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
const result = await agent.invoke({
|
|
72
|
+
messages: [
|
|
73
|
+
{ role: "user", content: "Create a hello world Deno app and run it" },
|
|
74
|
+
],
|
|
75
|
+
});
|
|
76
|
+
} finally {
|
|
77
|
+
await sandbox.close();
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Configuration Options
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
interface DenoSandboxOptions {
|
|
85
|
+
/**
|
|
86
|
+
* Memory allocation in megabytes.
|
|
87
|
+
* Min: 768MB, Max: 4096MB
|
|
88
|
+
* @default 768
|
|
89
|
+
*/
|
|
90
|
+
memoryMb?: number;
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Sandbox lifetime.
|
|
94
|
+
* - "session": Shuts down when you close the client (default)
|
|
95
|
+
* - Duration: e.g., "5m", "30s"
|
|
96
|
+
*/
|
|
97
|
+
lifetime?: "session" | `${number}s` | `${number}m`;
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Region where the sandbox will be created.
|
|
101
|
+
* If not specified, uses the default region.
|
|
102
|
+
*/
|
|
103
|
+
region?: DenoSandboxRegion;
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Authentication configuration.
|
|
107
|
+
*/
|
|
108
|
+
auth?: {
|
|
109
|
+
token?: string;
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## Available Regions
|
|
115
|
+
|
|
116
|
+
The sandbox can be deployed in the following regions:
|
|
117
|
+
|
|
118
|
+
| Region Code | Location |
|
|
119
|
+
| ----------- | --------- |
|
|
120
|
+
| `ams` | Amsterdam |
|
|
121
|
+
| `ord` | Chicago |
|
|
122
|
+
|
|
123
|
+
## Accessing the Deno SDK
|
|
124
|
+
|
|
125
|
+
For advanced features not exposed by `BaseSandbox`, you can access the underlying Deno SDK directly via the `sandbox` property:
|
|
126
|
+
|
|
127
|
+
```typescript
|
|
128
|
+
const denoSandbox = await DenoSandbox.create();
|
|
129
|
+
|
|
130
|
+
// Access the raw Deno SDK
|
|
131
|
+
const sdk = denoSandbox.sandbox;
|
|
132
|
+
|
|
133
|
+
// Use any Deno SDK feature directly
|
|
134
|
+
const url = await sdk.exposeHttp({ port: 3000 });
|
|
135
|
+
const ssh = await sdk.exposeSsh();
|
|
136
|
+
const result = await sdk.eval("1 + 2");
|
|
137
|
+
await sdk.env.set("API_KEY", "secret");
|
|
138
|
+
|
|
139
|
+
// Use shell template literals
|
|
140
|
+
const output = await sdk.sh`echo "Hello from Deno!"`.text();
|
|
141
|
+
|
|
142
|
+
// Start a JavaScript runtime
|
|
143
|
+
const runtime = await sdk.createJsRuntime({ entrypoint: "server.ts" });
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
See the [@deno/sandbox documentation](https://www.npmjs.com/package/@deno/sandbox) for all available SDK methods.
|
|
147
|
+
|
|
148
|
+
## Factory Functions
|
|
149
|
+
|
|
150
|
+
### Creating New Sandboxes Per Invocation
|
|
151
|
+
|
|
152
|
+
```typescript
|
|
153
|
+
import { createDenoSandboxFactory } from "@langchain/deno";
|
|
154
|
+
|
|
155
|
+
// Each call creates a new sandbox
|
|
156
|
+
const factory = createDenoSandboxFactory({ memoryMb: 1024 });
|
|
157
|
+
|
|
158
|
+
const sandbox1 = await factory();
|
|
159
|
+
const sandbox2 = await factory();
|
|
160
|
+
|
|
161
|
+
try {
|
|
162
|
+
// Use sandboxes...
|
|
163
|
+
} finally {
|
|
164
|
+
await sandbox1.close();
|
|
165
|
+
await sandbox2.close();
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### Reusing an Existing Sandbox
|
|
170
|
+
|
|
171
|
+
```typescript
|
|
172
|
+
import { createDeepAgent, createFilesystemMiddleware } from "deepagents";
|
|
173
|
+
import {
|
|
174
|
+
DenoSandbox,
|
|
175
|
+
createDenoSandboxFactoryFromSandbox,
|
|
176
|
+
} from "@langchain/deno";
|
|
177
|
+
|
|
178
|
+
// Create and initialize a sandbox
|
|
179
|
+
const sandbox = await DenoSandbox.create({ memoryMb: 1024 });
|
|
180
|
+
|
|
181
|
+
try {
|
|
182
|
+
const agent = createDeepAgent({
|
|
183
|
+
model: new ChatAnthropic({ model: "claude-sonnet-4-20250514" }),
|
|
184
|
+
systemPrompt: "You are a coding assistant.",
|
|
185
|
+
middlewares: [
|
|
186
|
+
createFilesystemMiddleware({
|
|
187
|
+
backend: createDenoSandboxFactoryFromSandbox(sandbox),
|
|
188
|
+
}),
|
|
189
|
+
],
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
await agent.invoke({ messages: [...] });
|
|
193
|
+
} finally {
|
|
194
|
+
await sandbox.close();
|
|
195
|
+
}
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
## Reconnecting to Existing Sandboxes
|
|
199
|
+
|
|
200
|
+
Resume working with a sandbox that has a duration-based lifetime:
|
|
201
|
+
|
|
202
|
+
```typescript
|
|
203
|
+
// First session: create with duration lifetime
|
|
204
|
+
const sandbox = await DenoSandbox.create({
|
|
205
|
+
memoryMb: 1024,
|
|
206
|
+
lifetime: "30m",
|
|
207
|
+
});
|
|
208
|
+
const sandboxId = sandbox.id;
|
|
209
|
+
await sandbox.close(); // Close connection, but sandbox keeps running
|
|
210
|
+
|
|
211
|
+
// Later: reconnect to the same sandbox
|
|
212
|
+
const reconnected = await DenoSandbox.connect(sandboxId);
|
|
213
|
+
const result = await reconnected.execute("ls -la");
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
## Error Handling
|
|
217
|
+
|
|
218
|
+
```typescript
|
|
219
|
+
import { DenoSandboxError } from "@langchain/deno";
|
|
220
|
+
|
|
221
|
+
try {
|
|
222
|
+
await sandbox.execute("some command");
|
|
223
|
+
} catch (error) {
|
|
224
|
+
if (error instanceof DenoSandboxError) {
|
|
225
|
+
switch (error.code) {
|
|
226
|
+
case "NOT_INITIALIZED":
|
|
227
|
+
await sandbox.initialize();
|
|
228
|
+
break;
|
|
229
|
+
case "COMMAND_TIMEOUT":
|
|
230
|
+
console.error("Command took too long");
|
|
231
|
+
break;
|
|
232
|
+
case "AUTHENTICATION_FAILED":
|
|
233
|
+
console.error("Check your Deno Deploy token");
|
|
234
|
+
break;
|
|
235
|
+
default:
|
|
236
|
+
throw error;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
### Error Codes
|
|
243
|
+
|
|
244
|
+
| Code | Description |
|
|
245
|
+
| ------------------------- | ------------------------------------------- |
|
|
246
|
+
| `NOT_INITIALIZED` | Sandbox not initialized - call initialize() |
|
|
247
|
+
| `ALREADY_INITIALIZED` | Cannot initialize twice |
|
|
248
|
+
| `AUTHENTICATION_FAILED` | Invalid or missing Deno Deploy token |
|
|
249
|
+
| `SANDBOX_CREATION_FAILED` | Failed to create sandbox |
|
|
250
|
+
| `SANDBOX_NOT_FOUND` | Sandbox ID not found or expired |
|
|
251
|
+
| `COMMAND_TIMEOUT` | Command execution timed out |
|
|
252
|
+
| `COMMAND_FAILED` | Command execution failed |
|
|
253
|
+
| `FILE_OPERATION_FAILED` | File read/write failed |
|
|
254
|
+
| `RESOURCE_LIMIT_EXCEEDED` | CPU, memory, or storage limits exceeded |
|
|
255
|
+
|
|
256
|
+
## Inherited BaseSandbox Methods
|
|
257
|
+
|
|
258
|
+
`DenoSandbox` extends `BaseSandbox` and inherits these convenience methods:
|
|
259
|
+
|
|
260
|
+
| Method | Description |
|
|
261
|
+
| ------------ | ----------------------------- |
|
|
262
|
+
| `read()` | Read a file's contents |
|
|
263
|
+
| `write()` | Write content to a file |
|
|
264
|
+
| `edit()` | Replace text in a file |
|
|
265
|
+
| `lsInfo()` | List directory contents |
|
|
266
|
+
| `grepRaw()` | Search for patterns in files |
|
|
267
|
+
| `globInfo()` | Find files matching a pattern |
|
|
268
|
+
|
|
269
|
+
## Limits and Constraints
|
|
270
|
+
|
|
271
|
+
| Constraint | Value |
|
|
272
|
+
| -------------------- | ----------------- |
|
|
273
|
+
| Minimum memory | 768 MB |
|
|
274
|
+
| Maximum memory | 4096 MB (4 GB) |
|
|
275
|
+
| Disk space | 10 GB |
|
|
276
|
+
| vCPUs | 2 |
|
|
277
|
+
| Working directory | `/home/app` |
|
|
278
|
+
| Network access | Full (by default) |
|
|
279
|
+
| Interactive commands | Not supported |
|
|
280
|
+
|
|
281
|
+
## Environment Variables
|
|
282
|
+
|
|
283
|
+
| Variable | Description |
|
|
284
|
+
| ------------------- | ------------------------------------- |
|
|
285
|
+
| `DENO_DEPLOY_TOKEN` | Deno Deploy organization access token |
|
|
286
|
+
|
|
287
|
+
## License
|
|
288
|
+
|
|
289
|
+
MIT
|