diff --git a/index.ts b/index.ts index d54a6f1..0cd87ed 100644 --- a/index.ts +++ b/index.ts @@ -1,58 +1,78 @@ import os from "node:os"; +import { parseArgs } from "node:util"; import { createOpenAICompatible } from "@ai-sdk/openai-compatible"; import { type ModelMessage, streamText } from "ai"; - import { renderStream } from "./src/render"; const home = os.homedir(); const convoFile = Bun.file(`${home}/.aicl_convo.json`); -const provider = createOpenAICompatible({ - name: "llama.cpp", - apiKey: "local", - baseURL: "http://127.0.0.1:8080/v1", - includeUsage: true, // Include usage information in streaming responses +const { values: args, positionals } = parseArgs({ + args: Bun.argv, + options: { + model: { + type: "string", + }, + new: { + type: "boolean", + }, + }, + strict: true, + allowPositionals: true, }); -const messages: ModelMessage[] = []; +async function main() { + const provider = createOpenAICompatible({ + name: "llama.cpp", + apiKey: "local", + baseURL: "http://127.0.0.1:8080/v1", + includeUsage: true, // Include usage information in streaming responses + }); -try { - const convo = await convoFile.json(); - messages.push(...convo); -} catch {} + const messages: ModelMessage[] = []; -const prompt = Bun.argv[2] ?? "Introduce yourself."; -messages.push({ role: "user", content: prompt }); + if (!args.new) { + try { + const convo = await convoFile.json(); + messages.push(...convo); + } catch {} + } -const { fullStream, textStream, text, totalUsage } = streamText({ - model: provider("gemma4-26b-a4b"), - messages, -}); + const prompt = positionals[2] ?? "Introduce yourself."; + messages.push({ role: "user", content: prompt }); -const start = Date.now(); + const { fullStream, textStream, text, totalUsage } = streamText({ + model: provider(args.model ?? "gemma4-26b-a4b"), + messages, + }); -const streamRender = renderStream(fullStream); + const start = Date.now(); -const [width] = process.stdout.getWindowSize(); -const glow = Bun.spawn({ - cmd: ["glow", "-w", `${width}`, "-"], - stdin: textStream, - stdout: "inherit", -}); + const streamRender = renderStream(fullStream); -await streamRender; + const [width] = process.stdout.getWindowSize(); + const glow = Bun.spawn({ + cmd: ["glow", "-w", `${width}`, "-"], + stdin: textStream, + stdout: "inherit", + }); -const stop = Date.now(); + await streamRender; -await glow.exited; + const stop = Date.now(); -messages.push({ role: "assistant", content: await text }); -await convoFile.write(JSON.stringify(messages)); + await glow.exited; -const { inputTokens, outputTokens } = await totalUsage; -const context = (inputTokens ?? 0) / 1000; -const output = (outputTokens ?? 0) / 1000; -const time = (stop - start) / 1000; -process.stderr.write( - `\u001b[2mContext: ${context.toFixed(1)}k, Output: ${output.toFixed(1)}k, Time: ${time.toFixed(2)}s\u001b[22m\n`, -); + messages.push({ role: "assistant", content: await text }); + await convoFile.write(JSON.stringify(messages)); + + const { inputTokens, outputTokens } = await totalUsage; + const context = (inputTokens ?? 0) / 1000; + const output = (outputTokens ?? 0) / 1000; + const time = (stop - start) / 1000; + process.stderr.write( + `\u001b[2mContext: ${context.toFixed(1)}k, Output: ${output.toFixed(1)}k, Time: ${time.toFixed(2)}s\u001b[22m\n`, + ); +} + +await main(); diff --git a/package.json b/package.json index ad55268..63aacf3 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ "dev": "bun run index.ts", "prod": "bun run out/index.js", "check": "bunx --bun @biomejs/biome check --write", - "build": "bun run check && bun run build:bundle && bun run shebang", + "build:js": "bun run check && bun run build:bundle && bun run shebang", "build:bundle": "bun build --target=bun --production --sourcemap --outdir=out index.ts", "build:bin": "bun build --compile --outfile=out/aicl index.ts", "shebang": "sed -i '1i#!\\/usr\\/bin\\/env bun' out/index.js" diff --git a/src/render/index.ts b/src/render/index.ts index 46be8e3..25d4a9d 100644 --- a/src/render/index.ts +++ b/src/render/index.ts @@ -59,9 +59,7 @@ export async function renderStream( resetCounts(); } - while (!memOk) { - await new Promise((resolve) => setTimeout(resolve, 10)); - } + while (!memOk) await Bun.sleep(10); } }