| |
| import { createInterface } from 'readline'; |
| import { createRuntime } from '../state/factory.js'; |
| import { EventRenderer } from '../renderers/index.js'; |
| import type { Message } from '../../core/provider/index.js'; |
| import { now, type HarnessEvent } from '../../core/events/index.js'; |
|
|
| export async function chatCommand(opts: { |
| provider: string; |
| model?: string; |
| skills: string[]; |
| verbose?: boolean; |
| compact?: boolean; |
| }): Promise<void> { |
| const renderer = new EventRenderer({ verbose: opts.verbose ?? false, compact: opts.compact ?? false }); |
| const { runtime, eventBus, provider } = await createRuntime(opts); |
|
|
| eventBus.on((event) => renderer.render(event)); |
|
|
| const rl = createInterface({ input: process.stdin, output: process.stdout }); |
| const prompt = () => new Promise<string>((resolve) => rl.question('\x1b[36mβ―\x1b[0m ', resolve)); |
|
|
| console.log(`\x1b[90mProvider: ${provider.label} | Type your message (Ctrl+C to exit)\x1b[0m\n`); |
|
|
| const messages: Message[] = [{ role: 'system', content: 'You are a helpful AI assistant with access to tools.' }]; |
|
|
| while (true) { |
| const input = await prompt(); |
| if (!input.trim()) continue; |
| if (input.trim() === '/quit' || input.trim() === '/exit') break; |
|
|
| messages.push({ role: 'user', content: input }); |
|
|
| eventBus.emit({ type: 'model.request.start', provider: provider.id, model: opts.model ?? 'default', timestamp: now() }); |
| const startMs = Date.now(); |
|
|
| try { |
| for await (const event of provider.stream({ |
| model: opts.model ?? (await provider.listModels())[0]!.id, |
| messages, |
| tools: runtime ? undefined : undefined, |
| })) { |
| if (event.type === 'text-delta') { |
| process.stdout.write(event.text); |
| } else if (event.type === 'finish') { |
| const durationMs = Date.now() - startMs; |
| eventBus.emit({ type: 'model.request.end', provider: provider.id, model: opts.model ?? 'default', usage: event.result.usage, durationMs, timestamp: now() }); |
| messages.push({ role: 'assistant', content: event.result.content }); |
| if (!event.result.content.endsWith('\n')) process.stdout.write('\n'); |
| } |
| } |
| } catch (err) { |
| const errMsg = err instanceof Error ? err.message : String(err); |
| console.error(`\x1b[31mError: ${errMsg}\x1b[0m`); |
| } |
| console.log(); |
| } |
|
|
| rl.close(); |
| console.log('\x1b[90mGoodbye.\x1b[0m'); |
| process.exit(0); |
| } |
|
|