forked from ConardLi/easy-agent
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathstep2.js
More file actions
67 lines (53 loc) · 1.67 KB
/
Copy pathstep2.js
File metadata and controls
67 lines (53 loc) · 1.67 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
58
59
60
61
62
63
64
65
66
67
/**
* Step 2 - Minimal interactive REPL
*
* Goal:
* - show how multi-turn chat works in the terminal
* - keep state in memory
* - print streaming text incrementally
*
* This version uses Node readline for teaching simplicity.
* The real project uses React/Ink for a richer terminal UI.
*/
import readline from "node:readline/promises";
import { stdin as input, stdout as output } from "node:process";
import { streamMessage } from "./step1.js";
export async function runRepl({ model, system } = {}) {
const rl = readline.createInterface({ input, output });
const messages = [];
console.log("Easy Agent REPL");
console.log("Type /exit to quit, /clear to clear history.");
while (true) {
const text = (await rl.question("> ")).trim();
if (!text) continue;
if (text === "/exit") break;
if (text === "/clear") {
messages.length = 0;
console.log("(history cleared)");
continue;
}
messages.push({ role: "user", content: text });
const stream = streamMessage({ messages, model, system });
let finalResult = null;
process.stdout.write("assistant: ");
while (true) {
const { value, done } = await stream.next();
if (done) {
finalResult = value;
break;
}
if (value.type === "text") {
process.stdout.write(value.text);
}
if (value.type === "tool_use_start") {
process.stdout.write("\n[tool: " + value.name + "]\n");
}
}
process.stdout.write("\n\n");
messages.push(finalResult.assistantMessage);
console.log(
"(tokens in/out: " + finalResult.usage.input_tokens + "/" + finalResult.usage.output_tokens + ")",
);
}
rl.close();
}