-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathstream.ts
More file actions
57 lines (48 loc) · 1.56 KB
/
stream.ts
File metadata and controls
57 lines (48 loc) · 1.56 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
// # Stream a GitHub Search
//
// Same as github-search, but streams each turn as it happens.
// Useful for showing progress in a UI — the user sees what
// WarpGrep is doing instead of staring at a spinner.
//
// Usage:
// MORPH_API_KEY=your-key npx tsx stream.ts
// MORPH_API_KEY=your-key npx tsx stream.ts "your query" owner/repo
import { MorphClient } from "@morphllm/morphsdk";
const morph = new MorphClient({ apiKey: process.env.MORPH_API_KEY });
const query = process.argv[2] || "Find how middleware chains work";
const repo = process.argv[3] || "expressjs/express";
console.log(`Streaming search on ${repo}: "${query}"\n`);
// searchGitHub with streamSteps returns an async generator.
const stream = morph.warpGrep.searchGitHub({
query,
github: repo,
streamSteps: true,
});
// Each yield is one agent turn — typically 2-4 turns total.
let result;
for (;;) {
const { value, done } = await stream.next();
if (done) {
result = value;
break;
}
console.log(`Turn ${value.turn}:`);
for (const call of value.toolCalls) {
const args = Object.entries(call.arguments)
.map(([k, v]) => `${k}=${JSON.stringify(v)}`)
.join(", ");
console.log(` ${call.name}(${args})`);
}
console.log();
}
if (!result.success) {
console.error("Search failed:", result.error);
process.exit(1);
}
console.log(`Found ${result.contexts?.length ?? 0} files:\n`);
for (const ctx of result.contexts ?? []) {
console.log(`--- ${ctx.file} ---`);
console.log(ctx.content.slice(0, 300));
if (ctx.content.length > 300) console.log(" ...");
console.log();
}