UNPKG

@sema-agent/core

Version:

Stateless, task-oriented AI agent core

91 lines (90 loc) • 2.74 kB
export class EventStream { queue = []; waiting = []; done = false; finalResolved = false; finalResultPromise; resolveFinalResult; rejectFinalResult; isComplete; extractResult; constructor(isComplete, extractResult) { this.isComplete = isComplete; this.extractResult = extractResult; this.finalResultPromise = new Promise((resolve, reject) => { this.resolveFinalResult = resolve; this.rejectFinalResult = reject; }); this.finalResultPromise.catch(() => { }); } push(event) { if (this.done) { return; } if (this.isComplete(event)) { this.done = true; this.finalResolved = true; this.resolveFinalResult(this.extractResult(event)); } const waiter = this.waiting.shift(); if (waiter) { waiter({ value: event, done: false }); } else { this.queue.push(event); } } end(result) { this.done = true; if (result !== undefined) { this.finalResolved = true; this.resolveFinalResult(result); } else if (!this.finalResolved) { this.finalResolved = true; this.rejectFinalResult(new Error("EventStream ended without a final result (end() called with no result and no terminal event was pushed)")); } while (this.waiting.length > 0) { const waiter = this.waiting.shift(); waiter({ value: undefined, done: true }); } } async *[Symbol.asyncIterator]() { while (true) { if (this.queue.length > 0) { yield this.queue.shift(); } else if (this.done) { return; } else { const result = await new Promise((resolve) => { this.waiting.push(resolve); }); if (result.done) { return; } yield result.value; } } } result() { return this.finalResultPromise; } } export class AssistantMessageEventStream extends EventStream { constructor() { super((event) => event.type === "done" || event.type === "error", (event) => { if (event.type === "done") { return event.message; } else if (event.type === "error") { return event.error; } throw new Error("Unexpected event type for final result"); }); } } export function createAssistantMessageEventStream() { return new AssistantMessageEventStream(); }