2024-04-04 00:47:44 +00:00
|
|
|
import type { SmartAi } from "./classes.smartai.js";
|
|
|
|
import { OpenAiProvider } from "./provider.openai.js";
|
|
|
|
|
2024-03-30 11:45:53 +00:00
|
|
|
type TProcessFunction = (input: string) => Promise<string>;
|
|
|
|
|
2024-04-04 00:47:44 +00:00
|
|
|
export interface IConversationOptions {
|
2024-03-30 11:45:53 +00:00
|
|
|
processFunction: TProcessFunction;
|
|
|
|
}
|
|
|
|
|
2024-04-04 00:47:44 +00:00
|
|
|
/**
|
|
|
|
* a conversation
|
|
|
|
*/
|
|
|
|
export class Conversation {
|
|
|
|
// STATIC
|
|
|
|
public static async createWithOpenAi(smartaiRef: SmartAi) {
|
|
|
|
const openaiProvider = new OpenAiProvider(smartaiRef.options.openaiToken);
|
|
|
|
const conversation = new Conversation(smartaiRef, {
|
|
|
|
processFunction: async (input) => {
|
|
|
|
return '' // TODO implement proper streaming
|
|
|
|
}
|
|
|
|
});
|
|
|
|
return conversation;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static async createWithAnthropic(smartaiRef: SmartAi) {
|
|
|
|
const anthropicProvider = new OpenAiProvider(smartaiRef.options.anthropicToken);
|
|
|
|
const conversation = new Conversation(smartaiRef, {
|
|
|
|
processFunction: async (input) => {
|
|
|
|
return '' // TODO implement proper streaming
|
|
|
|
}
|
|
|
|
});
|
|
|
|
return conversation;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// INSTANCE
|
|
|
|
smartaiRef: SmartAi
|
|
|
|
private systemMessage: string;
|
2024-03-30 11:45:53 +00:00
|
|
|
private processFunction: TProcessFunction;
|
|
|
|
private inputStreamWriter: WritableStreamDefaultWriter<string> | null = null;
|
|
|
|
private outputStreamController: ReadableStreamDefaultController<string> | null = null;
|
|
|
|
|
2024-04-04 00:47:44 +00:00
|
|
|
constructor(smartairefArg: SmartAi, options: IConversationOptions) {
|
2024-03-30 11:45:53 +00:00
|
|
|
this.processFunction = options.processFunction;
|
|
|
|
}
|
|
|
|
|
2024-04-04 00:47:44 +00:00
|
|
|
setSystemMessage(systemMessage: string) {
|
|
|
|
this.systemMessage = systemMessage;
|
|
|
|
}
|
|
|
|
|
2024-03-30 11:45:53 +00:00
|
|
|
private setupOutputStream(): ReadableStream<string> {
|
|
|
|
return new ReadableStream<string>({
|
|
|
|
start: (controller) => {
|
|
|
|
this.outputStreamController = controller;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
private setupInputStream(): WritableStream<string> {
|
|
|
|
return new WritableStream<string>({
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
public getInputStreamWriter(): WritableStreamDefaultWriter<string> {
|
|
|
|
if (!this.inputStreamWriter) {
|
|
|
|
const inputStream = this.setupInputStream();
|
|
|
|
this.inputStreamWriter = inputStream.getWriter();
|
|
|
|
}
|
|
|
|
return this.inputStreamWriter;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getOutputStream(): ReadableStream<string> {
|
|
|
|
return this.setupOutputStream();
|
|
|
|
}
|
|
|
|
}
|