import { Message, OpenAIModel } from '@/types'; import { createParser, ParsedEvent, ReconnectInterval, } from 'eventsource-parser'; import { OPENAI_API_HOST } from '../app/const'; export const OpenAIStream = async ( model: OpenAIModel, systemPrompt: string, key: string, messages: Message[], ) => { const res = await fetch(`${OPENAI_API_HOST}/v1/chat/completions`, { headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${key ? key : process.env.OPENAI_API_KEY}`, }, method: 'POST', body: JSON.stringify({ model: model.id, messages: [ { role: 'system', content: systemPrompt, }, ...messages, ], max_tokens: 1000, temperature: 1, stream: true, }), }); if (res.status !== 200) { const statusText = res.statusText; throw new Error(`OpenAI API returned an error: ${statusText}`); } const encoder = new TextEncoder(); const decoder = new TextDecoder(); const stream = new ReadableStream({ async start(controller) { const onParse = (event: ParsedEvent | ReconnectInterval) => { if (event.type === 'event') { const data = event.data; if (data === '[DONE]') { controller.close(); return; } try { const json = JSON.parse(data); const text = json.choices[0].delta.content; const queue = encoder.encode(text); controller.enqueue(queue); } catch (e) { controller.error(e); } } }; const parser = createParser(onParse); for await (const chunk of res.body as any) { parser.feed(decoder.decode(chunk)); } }, }); return stream; };