import { BaseProvider, ChatOptions, GatewayChatMessage } from "./BaseProvider"; import OpenAI from "openai"; import logManager from "@electron/service/logger" function _transformChunk(chunk: OpenAI.Chat.Completions.ChatCompletionChunk): UniversalChunk { const choice = chunk.choices[0]; const usage = (chunk as any).usage; return { isEnd: choice?.finish_reason != null || (chunk.choices.length === 0 && usage != null), result: choice?.delta?.content ?? '', usage: usage ?? undefined, } } export class OpenAIProvider extends BaseProvider { private client: OpenAI; constructor(apiKey: string, baseURL: string, headers?: Record) { super(); this.client = new OpenAI({ apiKey, baseURL, defaultHeaders: headers }); } async chat(messages: GatewayChatMessage[], model: string, options?: ChatOptions): Promise> { const startTime = Date.now(); const lastMessage = messages[messages.length - 1]; logManager.logApiRequest('chat.completions.create', { model, lastMessage: lastMessage?.content?.substring(0, 100) + (lastMessage?.content?.length > 100 ? '...' : ''), messageCount: messages.length, }, 'POST'); try { const chunks = await this.client.chat.completions.create({ model, messages: messages as any, stream: true, stream_options: { include_usage: true }, }, { signal: options?.signal, }); return { async *[Symbol.asyncIterator]() { try { for await (const chunk of chunks) { if (options?.signal?.aborted) break; yield _transformChunk(chunk); } const responseTime = Date.now() - startTime; logManager.logApiResponse('chat.completions.create', { success: true }, 200, responseTime); } catch (error) { const responseTime = Date.now() - startTime; logManager.logApiResponse('chat.completions.create', { error: error instanceof Error ? error.message : String(error) }, 500, responseTime); throw error; } } } } catch (error) { const responseTime = Date.now() - startTime; logManager.logApiResponse('chat.completions.create', { error: error instanceof Error ? error.message : String(error) }, 500, responseTime); throw error; } } }