import type { SmartAi } from "./classes.smartai.js"; import { OpenAiProvider } from "./provider.openai.js"; type TProcessFunction = (input: string) => Promise; export interface IConversationOptions { processFunction: TProcessFunction; } /** * a conversation */ export class Conversation { // STATIC public static async createWithOpenAi(smartaiRefArg: SmartAi) { if (!smartaiRefArg.openaiProvider) { throw new Error('OpenAI provider not available'); } const conversation = new Conversation(smartaiRefArg, { processFunction: async (input) => { return '' // TODO implement proper streaming } }); return conversation; } public static async createWithAnthropic(smartaiRefArg: SmartAi) { if (!smartaiRefArg.anthropicProvider) { throw new Error('Anthropic provider not available'); } const conversation = new Conversation(smartaiRefArg, { processFunction: async (input) => { return '' // TODO implement proper streaming } }); return conversation; } public static async createWithPerplexity(smartaiRefArg: SmartAi) { if (!smartaiRefArg.perplexityProvider) { throw new Error('Perplexity provider not available'); } const conversation = new Conversation(smartaiRefArg, { processFunction: async (input) => { return '' // TODO implement proper streaming } }); return conversation; } public static async createWithOllama(smartaiRefArg: SmartAi) { if (!smartaiRefArg.ollamaProvider) { throw new Error('Ollama provider not available'); } const conversation = new Conversation(smartaiRefArg, { processFunction: async (input) => { return '' // TODO implement proper streaming } }); return conversation; } // INSTANCE smartaiRef: SmartAi private systemMessage: string; private processFunction: TProcessFunction; private inputStreamWriter: WritableStreamDefaultWriter | null = null; private outputStreamController: ReadableStreamDefaultController | null = null; constructor(smartairefArg: SmartAi, options: IConversationOptions) { this.processFunction = options.processFunction; } public async setSystemMessage(systemMessageArg: string) { this.systemMessage = systemMessageArg; } private setupOutputStream(): ReadableStream { return new ReadableStream({ start: (controller) => { this.outputStreamController = controller; } }); } private setupInputStream(): WritableStream { const writableStream = new WritableStream({ write: async (chunk) => { const processedData = await this.processFunction(chunk); if (this.outputStreamController) { this.outputStreamController.enqueue(processedData); } }, close: () => { this.outputStreamController?.close(); }, abort: (err) => { console.error('Stream aborted', err); this.outputStreamController?.error(err); } }); return writableStream; } public getInputStreamWriter(): WritableStreamDefaultWriter { if (!this.inputStreamWriter) { const inputStream = this.setupInputStream(); this.inputStreamWriter = inputStream.getWriter(); } return this.inputStreamWriter; } public getOutputStream(): ReadableStream { return this.setupOutputStream(); } }