refactor: redirect reasoning output to stderr
This commit is contained in:
parent
712666255a
commit
4716712a92
2 changed files with 38 additions and 38 deletions
22
index.ts
22
index.ts
|
|
@ -78,25 +78,19 @@ async function main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
const start = Date.now();
|
const start = Date.now();
|
||||||
|
await new StreamRenderer().renderStream(fullStream);
|
||||||
const streamRender = new StreamRenderer().renderStream(fullStream);
|
|
||||||
|
|
||||||
const [width] = process.stdout.getWindowSize();
|
|
||||||
const glow = Bun.spawn({
|
|
||||||
cmd: ["glow", "-w", `${width}`, "-"],
|
|
||||||
stdin: textStream,
|
|
||||||
stdout: "inherit",
|
|
||||||
});
|
|
||||||
|
|
||||||
await streamRender;
|
|
||||||
|
|
||||||
const stop = Date.now();
|
const stop = Date.now();
|
||||||
|
|
||||||
await glow.exited;
|
|
||||||
|
|
||||||
convo.messages.push({ role: "assistant", content: await text });
|
convo.messages.push({ role: "assistant", content: await text });
|
||||||
await convoFile.write(JSON.stringify(convo));
|
await convoFile.write(JSON.stringify(convo));
|
||||||
|
|
||||||
|
const [width] = process.stdout.getWindowSize();
|
||||||
|
await Bun.spawn({
|
||||||
|
cmd: ["glow", "-w", `${width}`, "-"],
|
||||||
|
stdin: textStream,
|
||||||
|
stdout: "inherit",
|
||||||
|
}).exited;
|
||||||
|
|
||||||
const { inputTokens, outputTokens } = await totalUsage;
|
const { inputTokens, outputTokens } = await totalUsage;
|
||||||
const context = (inputTokens ?? 0) / 1000;
|
const context = (inputTokens ?? 0) / 1000;
|
||||||
const output = (outputTokens ?? 0) / 1000;
|
const output = (outputTokens ?? 0) / 1000;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
import os from "node:os";
|
import os from "node:os";
|
||||||
|
import type { WriteStream } from "node:tty";
|
||||||
import type { AsyncIterableStream, TextStreamPart, ToolSet } from "ai";
|
import type { AsyncIterableStream, TextStreamPart, ToolSet } from "ai";
|
||||||
import styles from "ansi-styles";
|
import styles from "ansi-styles";
|
||||||
import { supportsColor } from "chalk";
|
import { supportsColorStderr } from "chalk";
|
||||||
|
|
||||||
const home = os.homedir();
|
const home = os.homedir();
|
||||||
const reasoningWriter = Bun.file(`${home}/.aicl_reasoning.md`).writer();
|
const reasoningWriter = Bun.file(`${home}/.aicl_reasoning.md`).writer();
|
||||||
|
|
@ -15,18 +16,21 @@ export default class StreamRenderer {
|
||||||
process.stdout.addListener("drain", () => {
|
process.stdout.addListener("drain", () => {
|
||||||
this.memOk = true;
|
this.memOk = true;
|
||||||
});
|
});
|
||||||
|
process.stderr.addListener("drain", () => {
|
||||||
|
this.memOk = true;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private write(text: string) {
|
private write(text: string, pipe: WriteStream = process.stdout) {
|
||||||
this.memOk = process.stdout.write(text);
|
this.memOk = pipe.write(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
private moveCursor(x: number, y: number) {
|
private moveCursor(y: number, pipe: WriteStream = process.stdout) {
|
||||||
this.memOk = process.stdout.moveCursor(x, y);
|
this.memOk = pipe.moveCursor(-9999, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
private clearScreenDown() {
|
private clearScreenDown(pipe: WriteStream = process.stdout) {
|
||||||
this.memOk = process.stdout.clearScreenDown();
|
this.memOk = pipe.clearScreenDown();
|
||||||
}
|
}
|
||||||
|
|
||||||
private resetCounts() {
|
private resetCounts() {
|
||||||
|
|
@ -34,8 +38,8 @@ export default class StreamRenderer {
|
||||||
this.charsSinceNL = 0;
|
this.charsSinceNL = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private checkContainment(text: string) {
|
private checkContainment(text: string, pipe: WriteStream = process.stdout) {
|
||||||
const [columns, rows] = process.stdout.getWindowSize();
|
const [columns, rows] = pipe.getWindowSize();
|
||||||
this.charsSinceNL += text.length;
|
this.charsSinceNL += text.length;
|
||||||
if (text.includes("\n")) {
|
if (text.includes("\n")) {
|
||||||
this.lineCount += text.match(/\n/g)?.length ?? 1;
|
this.lineCount += text.match(/\n/g)?.length ?? 1;
|
||||||
|
|
@ -46,10 +50,9 @@ export default class StreamRenderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.lineCount >= Math.floor(rows * 0.75)) {
|
if (this.lineCount >= Math.floor(rows * 0.75)) {
|
||||||
this.moveCursor(0, -this.lineCount);
|
this.moveCursor(-this.lineCount, pipe);
|
||||||
this.clearScreenDown();
|
this.clearScreenDown(pipe);
|
||||||
this.lineCount = 0;
|
this.resetCounts();
|
||||||
this.charsSinceNL = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -58,18 +61,21 @@ export default class StreamRenderer {
|
||||||
|
|
||||||
for await (const part of stream) {
|
for await (const part of stream) {
|
||||||
if (part.type === "reasoning-start") {
|
if (part.type === "reasoning-start") {
|
||||||
if (supportsColor)
|
if (supportsColorStderr)
|
||||||
this.write(`${styles.dim.open}${styles.italic.open}`);
|
this.write(`${styles.dim.open}${styles.italic.open}`, process.stderr);
|
||||||
this.write("\n");
|
this.write("\n", process.stderr);
|
||||||
} else if (part.type === "reasoning-delta") {
|
} else if (part.type === "reasoning-delta") {
|
||||||
this.write(part.text);
|
this.write(part.text, process.stderr);
|
||||||
reasoningWriter.write(part.text);
|
reasoningWriter.write(part.text);
|
||||||
this.checkContainment(part.text);
|
this.checkContainment(part.text, process.stderr);
|
||||||
} else if (part.type === "reasoning-end") {
|
} else if (part.type === "reasoning-end") {
|
||||||
if (supportsColor)
|
if (supportsColorStderr)
|
||||||
this.write(`${styles.italic.close}${styles.dim.close}`);
|
this.write(
|
||||||
this.moveCursor(0, -this.lineCount - 1);
|
`${styles.italic.close}${styles.dim.close}`,
|
||||||
this.clearScreenDown();
|
process.stderr,
|
||||||
|
);
|
||||||
|
this.moveCursor(-this.lineCount - 1, process.stderr);
|
||||||
|
this.clearScreenDown(process.stderr);
|
||||||
this.resetCounts();
|
this.resetCounts();
|
||||||
reasoningWriter.end();
|
reasoningWriter.end();
|
||||||
} else if (part.type === "text-start") {
|
} else if (part.type === "text-start") {
|
||||||
|
|
@ -78,8 +84,8 @@ export default class StreamRenderer {
|
||||||
this.write(part.text);
|
this.write(part.text);
|
||||||
this.checkContainment(part.text);
|
this.checkContainment(part.text);
|
||||||
} else if (part.type === "text-end") {
|
} else if (part.type === "text-end") {
|
||||||
this.moveCursor(0, -this.lineCount - 1);
|
this.moveCursor(-this.lineCount - 1);
|
||||||
this.clearScreenDown();
|
this.clearScreenDown(process.stderr);
|
||||||
this.resetCounts();
|
this.resetCounts();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue