import { ChatCompletionCreateParams, ChatCompletionChunk, ChatCompletion, CreateEmbeddingResponse, EmbeddingCreateParams, ImageGenerateParams, ImagesResponse } from "openai/resources"; import { OpenAILikeInterface } from "../interfaces/OpenAILike"; import { ChatCompletionStream } from "../utils/stream"; import OpenAI from "openai"; import { error } from "console"; import { Logger } from "../utils/Logger"; export class OpenAIService implements OpenAILikeInterface { host: string apiKey: string openai: OpenAI constructor(options?: { host?: string, apiKey?: string }) { this.host = options?.host || "https://api.openai.com/v1" this.apiKey = options?.apiKey || "" if (!this.apiKey) { throw new Error("apiKey is required") } this.openai = new OpenAI({ baseURL: this.host, apiKey: this.apiKey }) } async chatComplete(params: ChatCompletionCreateParams): Promise | ChatCompletion> { // 非多模态 if ((params as any).isNotMultiMode) { const messages: any[] = [] params.messages.forEach(m => { if (typeof m.content === 'string') { messages.push({ role: m.role, content: m.content }) } else { if (m.content && m.content[0].type === 'text') { messages.push({ role: m.role, content: m.content[0].text }) } } }) params.messages = messages } if (params.stream) { const stream = new ChatCompletionStream() this.openai.chat.completions.create(params).then(async (response) => { for await (const iterator of response) { stream.write(iterator) } setTimeout(() => { stream.end() }, 500) }).catch(error => { // console.log("error", error.message) Logger.error("api err", error.message) stream.end() }) return stream } else { const response = await this.openai.chat.completions.create(params) return response } } async embeddings(params: EmbeddingCreateParams): Promise { const result = await this.openai.embeddings.create(params) return result } async imageGenerate(params: ImageGenerateParams): Promise { const result = await this.openai.images.generate(params) return result } }