import message from './LLM' const streamToComponent = async ( chatContent: message[], setTargetText: React.Dispatch> ) => { const url = "https://api.openai.com/v1/chat/completions"; // set initial value for the chat setTargetText([...chatContent, { role: "", content: "" }]); const body = JSON.stringify({ messages: chatContent, stream: true, model: "gpt-3.5-turbo", max_tokens: 2000, }); try { const response = await fetch(url, { method: "POST", mode: "cors", headers: { "Content-Type": "application/json", Accept: "text/event-stream", Authorization: "Access-Control-Allow-Origin": "*", }, body, }); const reader = response.body!.getReader(); const decoder = new TextDecoder(); while (true) { // Read a chunk from the stream const { value, done } = await reader.read(); // If the stream is done, break the loop if (done) { break; } const string_payload: string = decoder.decode(value, { stream: true }); const list_payload: string[] = string_payload .split("\n") .filter((line) => line.trim() !== ""); for (const line of list_payload) { const message = line.replace(/^data: /, ""); if (message.startsWith("[DONE]")) { return; // Stream finished } try { const parsed = JSON.parse(message); const result: any = parsed.choices[0].delta; //console.log(result); if ("role" in result) { setTargetText((targetText: message[]) => [ ...targetText.slice(0, -1), { ...targetText[targetText.length - 1], role: result.role.toString(), }, ]); } if ("content" in result) { setTargetText((targetText: message[]) => [ ...targetText.slice(0, -1), { ...targetText[targetText.length - 1], content: targetText[targetText.length - 1].content + result.content.toString(), }, ]); } } catch (error) { console.error("Could not JSON parse stream message", message, error); } } } } catch (error) { console.error(error); } }; export default streamToComponent;