Skip to content

Commit 8b8dfa2

Browse files
committed
Increase concurrency during tool setup
1 parent 79af3b2 commit 8b8dfa2

File tree

4 files changed

+60
-32
lines changed

4 files changed

+60
-32
lines changed

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"publishConfig": {
44
"access": "public"
55
},
6-
"version": "1.3.0",
6+
"version": "1.3.1",
77
"description": "Generic bash tool for AI agents, compatible with AI SDK",
88
"type": "module",
99
"main": "dist/index.js",
@@ -62,7 +62,7 @@
6262
"devDependencies": {
6363
"@biomejs/biome": "^2.3.11",
6464
"@types/node": "^22.10.0",
65-
"@vercel/sandbox": "^1.1.2",
65+
"@vercel/sandbox": "^1.1.6",
6666
"ai": "^6.0.13",
6767
"knip": "^5.80.0",
6868
"typescript": "^5.7.0",

pnpm-lock.yaml

Lines changed: 25 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/tool.ts

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ export async function createBashTool(
6868
let sandbox: Sandbox;
6969
let usingJustBash = false;
7070

71+
let fileWrittenPromise: Promise<void> | undefined;
72+
7173
if (options.sandbox) {
7274
// Check @vercel/sandbox first (more specific check)
7375
if (isVercelSandbox(options.sandbox)) {
@@ -84,7 +86,7 @@ export async function createBashTool(
8486
([filePath, content]) => ({ path: filePath, content }),
8587
);
8688
if (filesToWrite.length > 0) {
87-
await sandbox.writeFiles(filesToWrite);
89+
fileWrittenPromise = sandbox.writeFiles(filesToWrite);
8890
}
8991
} else {
9092
// Create just-bash sandbox with files
@@ -97,12 +99,15 @@ export async function createBashTool(
9799

98100
// 4. Discover available tools and generate prompt
99101
const fileList = Object.keys(loadedFiles);
100-
const toolPrompt = await createToolPrompt({
101-
sandbox,
102-
filenames: fileList,
103-
isJustBash: usingJustBash,
104-
toolPrompt: options.promptOptions?.toolPrompt,
105-
});
102+
const [toolPrompt, _] = await Promise.all([
103+
createToolPrompt({
104+
sandbox,
105+
filenames: fileList,
106+
isJustBash: usingJustBash,
107+
toolPrompt: options.promptOptions?.toolPrompt,
108+
}),
109+
fileWrittenPromise,
110+
]);
106111

107112
// 5. Create tools
108113
const bash = createBashExecuteTool({

src/tool.vercel.integration.test.ts

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ describe("createBashTool @vercel/sandbox integration", () => {
6262
assert(tools.bash.execute, "bash.execute should be defined");
6363
const result = (await tools.bash.execute(
6464
{ command: "ls -la" },
65-
opts
65+
opts,
6666
)) as CommandResult;
6767

6868
expect(result.exitCode).toBe(0);
@@ -82,16 +82,17 @@ describe("createBashTool @vercel/sandbox integration", () => {
8282
assert(tools.bash.execute, "bash.execute should be defined");
8383
const result = (await tools.bash.execute(
8484
{ command: "ls src" },
85-
opts
85+
opts,
8686
)) as CommandResult;
8787

88+
expect(result.stderr).toBe("");
8889
expect(result.exitCode).toBe(0);
8990
expect(result.stdout.trim()).toBe("index.ts\nutils");
9091
}, 30000);
9192
});
9293

9394
describe("find command", () => {
94-
it("find . -name '*.ts' finds TypeScript files", async () => {
95+
it(`find . -name '*.ts' finds TypeScript files`, async () => {
9596
const dest = uniqueDir();
9697
const { tools } = await createBashTool({
9798
sandbox: vercelSandbox,
@@ -102,17 +103,18 @@ describe("createBashTool @vercel/sandbox integration", () => {
102103
assert(tools.bash.execute, "bash.execute should be defined");
103104
const result = (await tools.bash.execute(
104105
{ command: "find . -name '*.ts'" },
105-
opts
106+
opts,
106107
)) as CommandResult;
107108

109+
expect(result.stderr).toBe("");
108110
expect(result.exitCode).toBe(0);
109111
expect(result.stdout).toContain("index.ts");
110112
expect(result.stdout).toContain("helpers.ts");
111113
expect(result.stdout).toContain("format.ts");
112114
expect(result.stdout).not.toContain("package.json");
113115
}, 30000);
114116

115-
it("find . -name '*.json' finds JSON files", async () => {
117+
it(`find . -name '*.json' finds JSON files`, async () => {
116118
const dest = uniqueDir();
117119
const { tools } = await createBashTool({
118120
sandbox: vercelSandbox,
@@ -123,11 +125,11 @@ describe("createBashTool @vercel/sandbox integration", () => {
123125
assert(tools.bash.execute, "bash.execute should be defined");
124126
const result = (await tools.bash.execute(
125127
{ command: "find . -name '*.json'" },
126-
opts
128+
opts,
127129
)) as CommandResult;
128-
130+
expect(result.stderr).toBe("");
129131
expect(result.exitCode).toBe(0);
130-
expect(result.stdout.trim()).toBe("./package.json");
132+
expect(result.stdout).toBe("./package.json\n");
131133
}, 30000);
132134
});
133135

@@ -143,7 +145,7 @@ describe("createBashTool @vercel/sandbox integration", () => {
143145
assert(tools.bash.execute, "bash.execute should be defined");
144146
const result = (await tools.bash.execute(
145147
{ command: "grep -r 'export' ." },
146-
opts
148+
opts,
147149
)) as CommandResult;
148150

149151
expect(result.stderr).toBe("");
@@ -164,12 +166,12 @@ describe("createBashTool @vercel/sandbox integration", () => {
164166
assert(tools.bash.execute, "bash.execute should be defined");
165167
const result = (await tools.bash.execute(
166168
{ command: "grep -r 'hello' ." },
167-
opts
169+
opts,
168170
)) as CommandResult;
169171

170172
expect(result.exitCode).toBe(0);
171173
expect(result.stdout.trim()).toBe(
172-
'./src/index.ts:export const hello = "world";'
174+
'./src/index.ts:export const hello = "world";',
173175
);
174176
}, 30000);
175177
});
@@ -186,7 +188,7 @@ describe("createBashTool @vercel/sandbox integration", () => {
186188
assert(tools.bash.execute, "bash.execute should be defined");
187189
const result = (await tools.bash.execute(
188190
{ command: "cat src/index.ts" },
189-
opts
191+
opts,
190192
)) as CommandResult;
191193

192194
expect(result.exitCode).toBe(0);
@@ -204,12 +206,12 @@ describe("createBashTool @vercel/sandbox integration", () => {
204206
assert(tools.bash.execute, "bash.execute should be defined");
205207
const result = (await tools.bash.execute(
206208
{ command: "cat package.json" },
207-
opts
209+
opts,
208210
)) as CommandResult;
209211

210212
expect(result.exitCode).toBe(0);
211213
expect(result.stdout).toBe(
212-
'{"name": "test-project", "version": "1.0.0"}'
214+
'{"name": "test-project", "version": "1.0.0"}',
213215
);
214216
}, 30000);
215217
});
@@ -225,7 +227,7 @@ describe("createBashTool @vercel/sandbox integration", () => {
225227
assert(tools.bash.execute, "bash.execute should be defined");
226228
const result = (await tools.bash.execute(
227229
{ command: "pwd" },
228-
opts
230+
opts,
229231
)) as CommandResult;
230232

231233
expect(result.exitCode).toBe(0);
@@ -243,7 +245,7 @@ describe("createBashTool @vercel/sandbox integration", () => {
243245
assert(tools.bash.execute, "bash.execute should be defined");
244246
const result = (await tools.bash.execute(
245247
{ command: "pwd" },
246-
opts
248+
opts,
247249
)) as CommandResult;
248250

249251
expect(result.exitCode).toBe(0);
@@ -263,7 +265,7 @@ describe("createBashTool @vercel/sandbox integration", () => {
263265
assert(tools.readFile.execute, "readFile.execute should be defined");
264266
const result = (await tools.readFile.execute(
265267
{ path: `${dest}/src/index.ts` },
266-
opts
268+
opts,
267269
)) as { content: string };
268270

269271
expect(result.content).toBe('export const hello = "world";');
@@ -287,12 +289,12 @@ describe("createBashTool @vercel/sandbox integration", () => {
287289
path: "newfile.txt",
288290
content: "Hello, World!",
289291
},
290-
opts
292+
opts,
291293
);
292294

293295
const result = (await tools.bash.execute(
294296
{ command: "cat newfile.txt" },
295-
opts
297+
opts,
296298
)) as CommandResult;
297299

298300
expect(result.stdout).toBe("Hello, World!");

0 commit comments

Comments
 (0)