bashkit 0.2.1 → 0.2.3
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/AGENTS.md +55 -12
- package/README.md +25 -1
- package/dist/index.js +149 -54
- package/dist/sandbox/e2b.d.ts +2 -0
- package/dist/sandbox/interface.d.ts +7 -0
- package/dist/sandbox/vercel.d.ts +2 -0
- package/dist/tools/index.d.ts +1 -1
- package/dist/tools/web-fetch.d.ts +8 -0
- package/dist/types.d.ts +16 -0
- package/package.json +1 -1
package/AGENTS.md
CHANGED
|
@@ -21,9 +21,9 @@ bun add bashkit ai @ai-sdk/anthropic
|
|
|
21
21
|
Runs commands directly on the local machine. Use for development/testing only.
|
|
22
22
|
|
|
23
23
|
```typescript
|
|
24
|
-
import { createAgentTools,
|
|
24
|
+
import { createAgentTools, createLocalSandbox } from "bashkit";
|
|
25
25
|
|
|
26
|
-
const sandbox =
|
|
26
|
+
const sandbox = createLocalSandbox({ cwd: "/tmp/workspace" });
|
|
27
27
|
const { tools } = createAgentTools(sandbox);
|
|
28
28
|
```
|
|
29
29
|
|
|
@@ -32,9 +32,9 @@ const { tools } = createAgentTools(sandbox);
|
|
|
32
32
|
Runs in isolated Firecracker microVMs on Vercel's infrastructure.
|
|
33
33
|
|
|
34
34
|
```typescript
|
|
35
|
-
import { createAgentTools,
|
|
35
|
+
import { createAgentTools, createVercelSandbox } from "bashkit";
|
|
36
36
|
|
|
37
|
-
const sandbox =
|
|
37
|
+
const sandbox = createVercelSandbox({
|
|
38
38
|
runtime: "node22",
|
|
39
39
|
resources: { vcpus: 2 },
|
|
40
40
|
});
|
|
@@ -44,6 +44,49 @@ const { tools } = createAgentTools(sandbox);
|
|
|
44
44
|
await sandbox.destroy();
|
|
45
45
|
```
|
|
46
46
|
|
|
47
|
+
### E2BSandbox (Production)
|
|
48
|
+
|
|
49
|
+
Runs in E2B's cloud sandboxes. Requires `@e2b/code-interpreter` peer dependency.
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
import { createAgentTools, createE2BSandbox } from "bashkit";
|
|
53
|
+
|
|
54
|
+
const sandbox = createE2BSandbox({
|
|
55
|
+
apiKey: process.env.E2B_API_KEY,
|
|
56
|
+
});
|
|
57
|
+
const { tools } = createAgentTools(sandbox);
|
|
58
|
+
|
|
59
|
+
await sandbox.destroy();
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Sandbox Reconnection (Cloud Sandboxes)
|
|
63
|
+
|
|
64
|
+
Cloud sandboxes (E2B, Vercel) support reconnection via the `id` property and `sandboxId` config:
|
|
65
|
+
|
|
66
|
+
```typescript
|
|
67
|
+
// Create a new sandbox
|
|
68
|
+
const sandbox = createE2BSandbox({ apiKey: process.env.E2B_API_KEY });
|
|
69
|
+
|
|
70
|
+
// After first operation, the sandbox ID is available
|
|
71
|
+
await sandbox.exec("echo hello");
|
|
72
|
+
const sandboxId = sandbox.id; // "sbx_abc123..."
|
|
73
|
+
|
|
74
|
+
// Store sandboxId in your database (e.g., chat metadata)
|
|
75
|
+
await db.chat.update({ where: { id: chatId }, data: { sandboxId } });
|
|
76
|
+
|
|
77
|
+
// Later: reconnect to the same sandbox
|
|
78
|
+
const savedId = chat.sandboxId;
|
|
79
|
+
const reconnected = createE2BSandbox({
|
|
80
|
+
apiKey: process.env.E2B_API_KEY,
|
|
81
|
+
sandboxId: savedId, // Reconnects instead of creating new
|
|
82
|
+
});
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
This is useful for:
|
|
86
|
+
- Reusing sandboxes across multiple requests in the same conversation
|
|
87
|
+
- Persisting sandbox state between server restarts
|
|
88
|
+
- Reducing sandbox creation overhead
|
|
89
|
+
|
|
47
90
|
## Available Tools
|
|
48
91
|
|
|
49
92
|
### Default Tools (always included)
|
|
@@ -89,11 +132,11 @@ import { generateText, wrapLanguageModel, stepCountIs } from "ai";
|
|
|
89
132
|
import { anthropic } from "@ai-sdk/anthropic";
|
|
90
133
|
import {
|
|
91
134
|
createAgentTools,
|
|
92
|
-
|
|
135
|
+
createLocalSandbox,
|
|
93
136
|
anthropicPromptCacheMiddleware,
|
|
94
137
|
} from "bashkit";
|
|
95
138
|
|
|
96
|
-
const sandbox =
|
|
139
|
+
const sandbox = createLocalSandbox({ cwd: "/tmp/workspace" });
|
|
97
140
|
const { tools } = createAgentTools(sandbox);
|
|
98
141
|
|
|
99
142
|
// Wrap model with prompt caching (recommended)
|
|
@@ -311,12 +354,12 @@ const skills = await discoverSkills();
|
|
|
311
354
|
### Using Skills with Agents
|
|
312
355
|
|
|
313
356
|
```typescript
|
|
314
|
-
import { discoverSkills, skillsToXml, createAgentTools,
|
|
357
|
+
import { discoverSkills, skillsToXml, createAgentTools, createLocalSandbox } from "bashkit";
|
|
315
358
|
import { generateText, stepCountIs } from "ai";
|
|
316
359
|
import { anthropic } from "@ai-sdk/anthropic";
|
|
317
360
|
|
|
318
361
|
const skills = await discoverSkills();
|
|
319
|
-
const sandbox =
|
|
362
|
+
const sandbox = createLocalSandbox({ cwd: "/tmp/workspace" });
|
|
320
363
|
const { tools } = createAgentTools(sandbox);
|
|
321
364
|
|
|
322
365
|
const result = await generateText({
|
|
@@ -421,13 +464,13 @@ import {
|
|
|
421
464
|
createAgentTools,
|
|
422
465
|
createTaskTool,
|
|
423
466
|
createTodoWriteTool,
|
|
424
|
-
|
|
467
|
+
createLocalSandbox,
|
|
425
468
|
anthropicPromptCacheMiddleware,
|
|
426
469
|
type TodoState,
|
|
427
470
|
} from "bashkit";
|
|
428
471
|
|
|
429
472
|
// 1. Create sandbox
|
|
430
|
-
const sandbox =
|
|
473
|
+
const sandbox = createLocalSandbox({ cwd: "/tmp/workspace" });
|
|
431
474
|
|
|
432
475
|
// 2. Create sandbox tools
|
|
433
476
|
const { tools: sandboxTools } = createAgentTools(sandbox);
|
|
@@ -489,9 +532,9 @@ const { tools } = createAgentTools(sandbox, {
|
|
|
489
532
|
Cache tool execution results to avoid redundant operations:
|
|
490
533
|
|
|
491
534
|
```typescript
|
|
492
|
-
import { createAgentTools,
|
|
535
|
+
import { createAgentTools, createLocalSandbox } from "bashkit";
|
|
493
536
|
|
|
494
|
-
const sandbox =
|
|
537
|
+
const sandbox = createLocalSandbox({ cwd: "/tmp/workspace" });
|
|
495
538
|
|
|
496
539
|
// Enable caching with defaults (LRU, 5min TTL)
|
|
497
540
|
const { tools } = createAgentTools(sandbox, { cache: true });
|
package/README.md
CHANGED
|
@@ -148,6 +148,15 @@ const sandbox = createVercelSandbox({
|
|
|
148
148
|
runtime: 'node22',
|
|
149
149
|
resources: { vcpus: 2 },
|
|
150
150
|
});
|
|
151
|
+
|
|
152
|
+
// After first operation, get the sandbox ID for persistence
|
|
153
|
+
await sandbox.exec('echo hello');
|
|
154
|
+
console.log(sandbox.id); // Sandbox ID for reconnection
|
|
155
|
+
|
|
156
|
+
// Later: reconnect to the same sandbox
|
|
157
|
+
const reconnected = createVercelSandbox({
|
|
158
|
+
sandboxId: 'existing-sandbox-id',
|
|
159
|
+
});
|
|
151
160
|
```
|
|
152
161
|
|
|
153
162
|
### E2BSandbox
|
|
@@ -158,7 +167,17 @@ Runs in E2B's cloud sandboxes. Requires `@e2b/code-interpreter` peer dependency.
|
|
|
158
167
|
import { createE2BSandbox } from 'bashkit';
|
|
159
168
|
|
|
160
169
|
const sandbox = createE2BSandbox({
|
|
161
|
-
|
|
170
|
+
apiKey: process.env.E2B_API_KEY,
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
// After first operation, get the sandbox ID for persistence
|
|
174
|
+
await sandbox.exec('echo hello');
|
|
175
|
+
console.log(sandbox.id); // "sbx_abc123..."
|
|
176
|
+
|
|
177
|
+
// Later: reconnect to the same sandbox
|
|
178
|
+
const reconnected = createE2BSandbox({
|
|
179
|
+
apiKey: process.env.E2B_API_KEY,
|
|
180
|
+
sandboxId: 'sbx_abc123...', // Reconnect to existing sandbox
|
|
162
181
|
});
|
|
163
182
|
```
|
|
164
183
|
|
|
@@ -764,9 +783,14 @@ interface Sandbox {
|
|
|
764
783
|
readDir(path: string): Promise<string[]>;
|
|
765
784
|
fileExists(path: string): Promise<boolean>;
|
|
766
785
|
destroy(): Promise<void>;
|
|
786
|
+
|
|
787
|
+
// Optional: Sandbox ID for reconnection (cloud providers only)
|
|
788
|
+
readonly id?: string;
|
|
767
789
|
}
|
|
768
790
|
```
|
|
769
791
|
|
|
792
|
+
The `id` property is available on cloud sandboxes (E2B, Vercel) after the first operation. Use it to persist the sandbox ID and reconnect later.
|
|
793
|
+
|
|
770
794
|
### Custom Sandbox Example
|
|
771
795
|
|
|
772
796
|
```typescript
|
package/dist/index.js
CHANGED
|
@@ -50,19 +50,31 @@ var anthropicPromptCacheMiddleware = {
|
|
|
50
50
|
transformParams: async ({ params }) => applyCacheMarkers(params)
|
|
51
51
|
};
|
|
52
52
|
// src/sandbox/e2b.ts
|
|
53
|
-
import { Sandbox as E2BSandboxSDK } from "@e2b/code-interpreter";
|
|
54
53
|
function createE2BSandbox(config = {}) {
|
|
55
54
|
let sandbox = null;
|
|
55
|
+
let sandboxId = config.sandboxId;
|
|
56
56
|
const workingDirectory = config.cwd || "/home/user";
|
|
57
57
|
const timeout = config.timeout ?? 300000;
|
|
58
58
|
const ensureSandbox = async () => {
|
|
59
59
|
if (sandbox)
|
|
60
60
|
return sandbox;
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
}
|
|
61
|
+
let E2BSandboxSDK;
|
|
62
|
+
try {
|
|
63
|
+
const module = await import("@e2b/code-interpreter");
|
|
64
|
+
E2BSandboxSDK = module.Sandbox;
|
|
65
|
+
} catch {
|
|
66
|
+
throw new Error("E2BSandbox requires @e2b/code-interpreter. Install with: npm install @e2b/code-interpreter");
|
|
67
|
+
}
|
|
68
|
+
if (config.sandboxId) {
|
|
69
|
+
sandbox = await E2BSandboxSDK.connect(config.sandboxId);
|
|
70
|
+
} else {
|
|
71
|
+
sandbox = await E2BSandboxSDK.create({
|
|
72
|
+
apiKey: config.apiKey,
|
|
73
|
+
timeoutMs: timeout,
|
|
74
|
+
metadata: config.metadata
|
|
75
|
+
});
|
|
76
|
+
sandboxId = sandbox.sandboxId;
|
|
77
|
+
}
|
|
66
78
|
return sandbox;
|
|
67
79
|
};
|
|
68
80
|
const exec = async (command, options) => {
|
|
@@ -108,6 +120,9 @@ function createE2BSandbox(config = {}) {
|
|
|
108
120
|
};
|
|
109
121
|
return {
|
|
110
122
|
exec,
|
|
123
|
+
get id() {
|
|
124
|
+
return sandboxId;
|
|
125
|
+
},
|
|
111
126
|
async readFile(path) {
|
|
112
127
|
const result = await exec(`cat "${path}"`);
|
|
113
128
|
if (result.exitCode !== 0) {
|
|
@@ -224,9 +239,9 @@ function createLocalSandbox(config = {}) {
|
|
|
224
239
|
};
|
|
225
240
|
}
|
|
226
241
|
// src/sandbox/vercel.ts
|
|
227
|
-
import { Sandbox as VercelSandboxSDK } from "@vercel/sandbox";
|
|
228
242
|
function createVercelSandbox(config = {}) {
|
|
229
243
|
let sandbox = null;
|
|
244
|
+
let sandboxId = config.sandboxId;
|
|
230
245
|
const workingDirectory = config.cwd || "/vercel/sandbox";
|
|
231
246
|
const resolvedConfig = {
|
|
232
247
|
runtime: config.runtime ?? "node22",
|
|
@@ -236,6 +251,13 @@ function createVercelSandbox(config = {}) {
|
|
|
236
251
|
const ensureSandbox = async () => {
|
|
237
252
|
if (sandbox)
|
|
238
253
|
return sandbox;
|
|
254
|
+
let VercelSandboxSDK;
|
|
255
|
+
try {
|
|
256
|
+
const module = await import("@vercel/sandbox");
|
|
257
|
+
VercelSandboxSDK = module.Sandbox;
|
|
258
|
+
} catch {
|
|
259
|
+
throw new Error("VercelSandbox requires @vercel/sandbox. Install with: npm install @vercel/sandbox");
|
|
260
|
+
}
|
|
239
261
|
const createOptions = {
|
|
240
262
|
runtime: resolvedConfig.runtime,
|
|
241
263
|
resources: resolvedConfig.resources,
|
|
@@ -247,7 +269,12 @@ function createVercelSandbox(config = {}) {
|
|
|
247
269
|
token: config.token
|
|
248
270
|
});
|
|
249
271
|
}
|
|
250
|
-
|
|
272
|
+
if (config.sandboxId) {
|
|
273
|
+
sandbox = await VercelSandboxSDK.get({ sandboxId: config.sandboxId });
|
|
274
|
+
} else {
|
|
275
|
+
sandbox = await VercelSandboxSDK.create(createOptions);
|
|
276
|
+
}
|
|
277
|
+
sandboxId = sandbox.sandboxId;
|
|
251
278
|
return sandbox;
|
|
252
279
|
};
|
|
253
280
|
const exec = async (command, options) => {
|
|
@@ -301,6 +328,9 @@ function createVercelSandbox(config = {}) {
|
|
|
301
328
|
};
|
|
302
329
|
return {
|
|
303
330
|
exec,
|
|
331
|
+
get id() {
|
|
332
|
+
return sandboxId;
|
|
333
|
+
},
|
|
304
334
|
async readFile(path) {
|
|
305
335
|
const sbx = await ensureSandbox();
|
|
306
336
|
const stream = await sbx.readFile({ path });
|
|
@@ -1372,13 +1402,56 @@ function createSkillTool(config) {
|
|
|
1372
1402
|
|
|
1373
1403
|
// src/tools/web-fetch.ts
|
|
1374
1404
|
import { generateText, tool as tool10, zodSchema as zodSchema10 } from "ai";
|
|
1375
|
-
import Parallel from "parallel-web";
|
|
1376
1405
|
import { z as z10 } from "zod";
|
|
1377
1406
|
|
|
1378
1407
|
// src/utils/http-constants.ts
|
|
1379
1408
|
var RETRYABLE_STATUS_CODES = [408, 429, 500, 502, 503];
|
|
1380
1409
|
|
|
1381
1410
|
// src/tools/web-fetch.ts
|
|
1411
|
+
var parallelModule = null;
|
|
1412
|
+
async function getParallelModule() {
|
|
1413
|
+
if (!parallelModule) {
|
|
1414
|
+
try {
|
|
1415
|
+
parallelModule = await import("parallel-web");
|
|
1416
|
+
} catch {
|
|
1417
|
+
throw new Error("WebFetch requires parallel-web. Install with: npm install parallel-web");
|
|
1418
|
+
}
|
|
1419
|
+
}
|
|
1420
|
+
return parallelModule;
|
|
1421
|
+
}
|
|
1422
|
+
async function fetchWithParallel(url, apiKey) {
|
|
1423
|
+
const { default: Parallel } = await getParallelModule();
|
|
1424
|
+
const client = new Parallel({ apiKey });
|
|
1425
|
+
const extract = await client.beta.extract({
|
|
1426
|
+
urls: [url],
|
|
1427
|
+
excerpts: true,
|
|
1428
|
+
full_content: true
|
|
1429
|
+
});
|
|
1430
|
+
if (!extract.results || extract.results.length === 0) {
|
|
1431
|
+
throw new Error("No content extracted from URL");
|
|
1432
|
+
}
|
|
1433
|
+
const result = extract.results[0];
|
|
1434
|
+
const content = result.full_content || result.excerpts?.join(`
|
|
1435
|
+
|
|
1436
|
+
`) || "";
|
|
1437
|
+
if (!content) {
|
|
1438
|
+
throw new Error("No content available from URL");
|
|
1439
|
+
}
|
|
1440
|
+
return {
|
|
1441
|
+
content,
|
|
1442
|
+
finalUrl: result.url
|
|
1443
|
+
};
|
|
1444
|
+
}
|
|
1445
|
+
async function fetchContent(url, apiKey, provider) {
|
|
1446
|
+
switch (provider) {
|
|
1447
|
+
case "parallel":
|
|
1448
|
+
return fetchWithParallel(url, apiKey);
|
|
1449
|
+
default: {
|
|
1450
|
+
const _exhaustive = provider;
|
|
1451
|
+
throw new Error(`Unknown provider: ${_exhaustive}`);
|
|
1452
|
+
}
|
|
1453
|
+
}
|
|
1454
|
+
}
|
|
1382
1455
|
var webFetchInputSchema = z10.object({
|
|
1383
1456
|
url: z10.string().describe("The URL to fetch content from"),
|
|
1384
1457
|
prompt: z10.string().describe("The prompt to run on the fetched content")
|
|
@@ -1400,7 +1473,14 @@ Usage notes:
|
|
|
1400
1473
|
- When a URL redirects to a different host, the tool will inform you and provide the redirect URL. You should then make a new WebFetch request with the redirect URL to fetch the content.
|
|
1401
1474
|
`;
|
|
1402
1475
|
function createWebFetchTool(config) {
|
|
1403
|
-
const {
|
|
1476
|
+
const {
|
|
1477
|
+
provider = "parallel",
|
|
1478
|
+
apiKey,
|
|
1479
|
+
model,
|
|
1480
|
+
strict,
|
|
1481
|
+
needsApproval,
|
|
1482
|
+
providerOptions
|
|
1483
|
+
} = config;
|
|
1404
1484
|
return tool10({
|
|
1405
1485
|
description: WEB_FETCH_DESCRIPTION,
|
|
1406
1486
|
inputSchema: zodSchema10(webFetchInputSchema),
|
|
@@ -1410,30 +1490,7 @@ function createWebFetchTool(config) {
|
|
|
1410
1490
|
execute: async (input) => {
|
|
1411
1491
|
const { url, prompt } = input;
|
|
1412
1492
|
try {
|
|
1413
|
-
const
|
|
1414
|
-
const extract = await client.beta.extract({
|
|
1415
|
-
urls: [url],
|
|
1416
|
-
excerpts: true,
|
|
1417
|
-
full_content: true
|
|
1418
|
-
});
|
|
1419
|
-
if (!extract.results || extract.results.length === 0) {
|
|
1420
|
-
return {
|
|
1421
|
-
error: "No content extracted from URL",
|
|
1422
|
-
status_code: 404,
|
|
1423
|
-
retryable: false
|
|
1424
|
-
};
|
|
1425
|
-
}
|
|
1426
|
-
const extractedResult = extract.results[0];
|
|
1427
|
-
const content = extractedResult.full_content || extractedResult.excerpts?.join(`
|
|
1428
|
-
|
|
1429
|
-
`) || "";
|
|
1430
|
-
if (!content) {
|
|
1431
|
-
return {
|
|
1432
|
-
error: "No content available from URL",
|
|
1433
|
-
status_code: 404,
|
|
1434
|
-
retryable: false
|
|
1435
|
-
};
|
|
1436
|
-
}
|
|
1493
|
+
const { content, finalUrl } = await fetchContent(url, apiKey, provider);
|
|
1437
1494
|
const result = await generateText({
|
|
1438
1495
|
model,
|
|
1439
1496
|
prompt: `${prompt}
|
|
@@ -1445,7 +1502,7 @@ ${content}`
|
|
|
1445
1502
|
return {
|
|
1446
1503
|
response: result.text,
|
|
1447
1504
|
url,
|
|
1448
|
-
final_url:
|
|
1505
|
+
final_url: finalUrl || url
|
|
1449
1506
|
};
|
|
1450
1507
|
} catch (error) {
|
|
1451
1508
|
if (error && typeof error === "object" && "status" in error) {
|
|
@@ -1467,8 +1524,53 @@ ${content}`
|
|
|
1467
1524
|
|
|
1468
1525
|
// src/tools/web-search.ts
|
|
1469
1526
|
import { tool as tool11, zodSchema as zodSchema11 } from "ai";
|
|
1470
|
-
import Parallel2 from "parallel-web";
|
|
1471
1527
|
import { z as z11 } from "zod";
|
|
1528
|
+
var parallelModule2 = null;
|
|
1529
|
+
async function getParallelModule2() {
|
|
1530
|
+
if (!parallelModule2) {
|
|
1531
|
+
try {
|
|
1532
|
+
parallelModule2 = await import("parallel-web");
|
|
1533
|
+
} catch {
|
|
1534
|
+
throw new Error("WebSearch requires parallel-web. Install with: npm install parallel-web");
|
|
1535
|
+
}
|
|
1536
|
+
}
|
|
1537
|
+
return parallelModule2;
|
|
1538
|
+
}
|
|
1539
|
+
async function searchWithParallel(apiKey, options) {
|
|
1540
|
+
const { default: Parallel } = await getParallelModule2();
|
|
1541
|
+
const client = new Parallel({ apiKey });
|
|
1542
|
+
const sourcePolicy = options.allowedDomains || options.blockedDomains ? {
|
|
1543
|
+
...options.allowedDomains && {
|
|
1544
|
+
include_domains: options.allowedDomains
|
|
1545
|
+
},
|
|
1546
|
+
...options.blockedDomains && {
|
|
1547
|
+
exclude_domains: options.blockedDomains
|
|
1548
|
+
}
|
|
1549
|
+
} : undefined;
|
|
1550
|
+
const search = await client.beta.search({
|
|
1551
|
+
mode: "agentic",
|
|
1552
|
+
objective: options.query,
|
|
1553
|
+
max_results: 10,
|
|
1554
|
+
...sourcePolicy && { source_policy: sourcePolicy }
|
|
1555
|
+
});
|
|
1556
|
+
return (search.results || []).map((result) => ({
|
|
1557
|
+
title: result.title ?? "",
|
|
1558
|
+
url: result.url ?? "",
|
|
1559
|
+
snippet: result.excerpts?.join(`
|
|
1560
|
+
`) ?? "",
|
|
1561
|
+
metadata: result.publish_date ? { publish_date: result.publish_date } : undefined
|
|
1562
|
+
}));
|
|
1563
|
+
}
|
|
1564
|
+
async function searchContent(apiKey, provider, options) {
|
|
1565
|
+
switch (provider) {
|
|
1566
|
+
case "parallel":
|
|
1567
|
+
return searchWithParallel(apiKey, options);
|
|
1568
|
+
default: {
|
|
1569
|
+
const _exhaustive = provider;
|
|
1570
|
+
throw new Error(`Unknown provider: ${_exhaustive}`);
|
|
1571
|
+
}
|
|
1572
|
+
}
|
|
1573
|
+
}
|
|
1472
1574
|
var webSearchInputSchema = z11.object({
|
|
1473
1575
|
query: z11.string().describe("The search query to use"),
|
|
1474
1576
|
allowed_domains: z11.array(z11.string()).optional().describe("Only include results from these domains"),
|
|
@@ -1495,7 +1597,13 @@ When searching for recent information, documentation, or current events, use the
|
|
|
1495
1597
|
- allowed_domains: Only include results from these domains
|
|
1496
1598
|
- blocked_domains: Never include results from these domains`;
|
|
1497
1599
|
function createWebSearchTool(config) {
|
|
1498
|
-
const {
|
|
1600
|
+
const {
|
|
1601
|
+
provider = "parallel",
|
|
1602
|
+
apiKey,
|
|
1603
|
+
strict,
|
|
1604
|
+
needsApproval,
|
|
1605
|
+
providerOptions
|
|
1606
|
+
} = config;
|
|
1499
1607
|
return tool11({
|
|
1500
1608
|
description: WEB_SEARCH_DESCRIPTION,
|
|
1501
1609
|
inputSchema: zodSchema11(webSearchInputSchema),
|
|
@@ -1505,24 +1613,11 @@ function createWebSearchTool(config) {
|
|
|
1505
1613
|
execute: async (input) => {
|
|
1506
1614
|
const { query, allowed_domains, blocked_domains } = input;
|
|
1507
1615
|
try {
|
|
1508
|
-
const
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
} : undefined;
|
|
1513
|
-
const search = await client.beta.search({
|
|
1514
|
-
mode: "agentic",
|
|
1515
|
-
objective: query,
|
|
1516
|
-
max_results: 10,
|
|
1517
|
-
...sourcePolicy && { source_policy: sourcePolicy }
|
|
1616
|
+
const results = await searchContent(apiKey, provider, {
|
|
1617
|
+
query,
|
|
1618
|
+
allowedDomains: allowed_domains,
|
|
1619
|
+
blockedDomains: blocked_domains
|
|
1518
1620
|
});
|
|
1519
|
-
const results = (search.results || []).map((result) => ({
|
|
1520
|
-
title: result.title ?? "",
|
|
1521
|
-
url: result.url ?? "",
|
|
1522
|
-
snippet: result.excerpts?.join(`
|
|
1523
|
-
`) ?? "",
|
|
1524
|
-
metadata: result.publish_date ? { publish_date: result.publish_date } : undefined
|
|
1525
|
-
}));
|
|
1526
1621
|
return {
|
|
1527
1622
|
results,
|
|
1528
1623
|
total_results: results.length,
|
package/dist/sandbox/e2b.d.ts
CHANGED
|
@@ -18,4 +18,11 @@ export interface Sandbox {
|
|
|
18
18
|
fileExists(path: string): Promise<boolean>;
|
|
19
19
|
isDirectory(path: string): Promise<boolean>;
|
|
20
20
|
destroy(): Promise<void>;
|
|
21
|
+
/**
|
|
22
|
+
* Sandbox ID for reconnection (cloud providers only).
|
|
23
|
+
* - For new sandboxes: available after first operation
|
|
24
|
+
* - For reconnected sandboxes: available immediately
|
|
25
|
+
* - For local sandboxes: always undefined
|
|
26
|
+
*/
|
|
27
|
+
readonly id?: string;
|
|
21
28
|
}
|
package/dist/sandbox/vercel.d.ts
CHANGED
package/dist/tools/index.d.ts
CHANGED
|
@@ -69,7 +69,7 @@ export type { SubagentEventData, SubagentStepEvent, SubagentTypeConfig, TaskErro
|
|
|
69
69
|
export { createTaskTool } from "./task";
|
|
70
70
|
export type { TodoItem, TodoState, TodoWriteError, TodoWriteOutput, } from "./todo-write";
|
|
71
71
|
export { createTodoWriteTool } from "./todo-write";
|
|
72
|
-
export type { WebFetchError, WebFetchOutput } from "./web-fetch";
|
|
72
|
+
export type { ExtractResult, WebFetchError, WebFetchOutput } from "./web-fetch";
|
|
73
73
|
export { createWebFetchTool } from "./web-fetch";
|
|
74
74
|
export type { WebSearchError, WebSearchOutput, WebSearchResult, } from "./web-search";
|
|
75
75
|
export { createWebSearchTool } from "./web-search";
|
|
@@ -10,6 +10,14 @@ export interface WebFetchError {
|
|
|
10
10
|
status_code?: number;
|
|
11
11
|
retryable?: boolean;
|
|
12
12
|
}
|
|
13
|
+
/**
|
|
14
|
+
* Result from a web fetch provider's extract operation.
|
|
15
|
+
* New providers should return this shape.
|
|
16
|
+
*/
|
|
17
|
+
export interface ExtractResult {
|
|
18
|
+
content: string;
|
|
19
|
+
finalUrl?: string;
|
|
20
|
+
}
|
|
13
21
|
export declare function createWebFetchTool(config: WebFetchConfig): import("ai").Tool<{
|
|
14
22
|
url: string;
|
|
15
23
|
prompt: string;
|
package/dist/types.d.ts
CHANGED
|
@@ -25,10 +25,26 @@ export type GrepToolConfig = ToolConfig & {
|
|
|
25
25
|
/** Use ripgrep (rg) instead of grep. Requires ripgrep to be installed. Default: false */
|
|
26
26
|
useRipgrep?: boolean;
|
|
27
27
|
};
|
|
28
|
+
/**
|
|
29
|
+
* Supported web search providers.
|
|
30
|
+
* Currently only 'parallel' is implemented.
|
|
31
|
+
* Add new providers here as union types (e.g., 'parallel' | 'serper' | 'tavily')
|
|
32
|
+
*/
|
|
33
|
+
export type WebSearchProvider = "parallel";
|
|
34
|
+
/**
|
|
35
|
+
* Supported web fetch providers.
|
|
36
|
+
* Currently only 'parallel' is implemented.
|
|
37
|
+
* Add new providers here as union types (e.g., 'parallel' | 'firecrawl' | 'jina')
|
|
38
|
+
*/
|
|
39
|
+
export type WebFetchProvider = "parallel";
|
|
28
40
|
export type WebSearchConfig = {
|
|
41
|
+
/** Provider to use for web search. Default: 'parallel' */
|
|
42
|
+
provider?: WebSearchProvider;
|
|
29
43
|
apiKey: string;
|
|
30
44
|
} & SDKToolOptions;
|
|
31
45
|
export type WebFetchConfig = {
|
|
46
|
+
/** Provider to use for web fetching. Default: 'parallel' */
|
|
47
|
+
provider?: WebFetchProvider;
|
|
32
48
|
apiKey: string;
|
|
33
49
|
model: LanguageModel;
|
|
34
50
|
} & SDKToolOptions;
|