Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1156,3 +1156,43 @@ describe("formatWarpGrepResult edge cases", () => {
expect(result).toBe("Search failed: timeout after 60s");
});
});

describe("warpgrep_codebase_search result handling", () => {
test("awaits the async generator return value (Bun compatibility)", async () => {
const fakeResult = {
success: true,
contexts: [
{ file: "src/auth.ts", content: "code", lines: [[1, 5]] as Array<[number, number]> },
],
summary: "found auth",
};

const original = WarpGrepClient.prototype.execute;
// Async generator that returns a result via `return` (not yield).
// In Bun, `return value` in an async generator may not auto-await,
// so the plugin must explicitly await the final .next() value.
WarpGrepClient.prototype.execute = async function* (): AsyncGenerator {
return fakeResult;
} as any;

try {
const { default: MorphPlugin } = await importPluginWithEnv({
MORPH_API_KEY: "sk-test-key",
});
const hooks = await MorphPlugin(
makePluginInput("/tmp/morph-warpgrep-async-test"),
);
const output = (await hooks.tool.warpgrep_codebase_search.execute(
{ search_term: "auth flow" },
makeToolContext("/tmp/morph-warpgrep-async-test"),
)) as string;

// Without the `await` fix, `value` is a Promise, `result.success` is
// undefined, and formatWarpGrepResult returns the generic failure message.
expect(output).toContain("Relevant context found:");
expect(output).toContain("src/auth.ts");
} finally {
WarpGrepClient.prototype.execute = original;
}
});
});
6 changes: 5 additions & 1 deletion index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1046,7 +1046,11 @@ Get your API key at: https://morphllm.com/dashboard/api-keys`;
for (;;) {
const { value, done } = await generator.next();
if (done) {
result = value;
// Bun: morphsdk's async generator returns an unawaited Promise
// from processAgentResult() via `return promise`. Node.js
// auto-awaits it per spec, but Bun does not. Explicitly await
// so the resolved WarpGrepResult is used instead of a Promise.
result = await value as WarpGrepResult;
break;
}
turnCount = value.turn;
Expand Down