This repository has no description
1import type { StreamEvent } from "@niri/chat-client"
2import { publishWorkerEvent } from "./awp/outbox"
3
4export type { StreamEvent }
5
6type Listener = (event: StreamEvent) => void
7
8const listeners = new Set<Listener>()
9const BUFFER_SIZE = 50
10const buffer: StreamEvent[] = []
11let activeConsoleText = false
12
13function endConsoleText(): void {
14 if (!activeConsoleText) return
15 process.stdout.write("\n")
16 activeConsoleText = false
17}
18
19export function emit(event: StreamEvent): void {
20 if (event.type === "text") {
21 if (!activeConsoleText) {
22 process.stdout.write("[niri] ")
23 activeConsoleText = true
24 }
25 process.stdout.write(event.text)
26 } else if (event.type === "thinking") {
27 if (!activeConsoleText) {
28 process.stdout.write("[thinking] ")
29 activeConsoleText = true
30 }
31 process.stdout.write(event.text)
32 } else {
33 endConsoleText()
34 if (event.type === "user") console.log(`[user/${event.source}] ${event.text}`)
35 }
36 buffer.push(event)
37 if (buffer.length > BUFFER_SIZE) buffer.shift()
38 publishWorkerEvent("stream.event", event)
39 for (const fn of listeners) fn(event)
40}
41
42export function subscribe(fn: Listener): () => void {
43 for (const event of buffer) fn(event)
44 listeners.add(fn)
45 return () => listeners.delete(fn)
46}