route.ts 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. import type { ChatRequest } from "../chat/typing";
  2. import { createParser } from "eventsource-parser";
  3. import { NextRequest } from "next/server";
  4. const apiKey = process.env.OPENAI_API_KEY;
  5. async function createStream(payload: string) {
  6. const encoder = new TextEncoder();
  7. const decoder = new TextDecoder();
  8. console.log("[ChatStream]", payload);
  9. const res = await fetch("https://api.openai.com/v1/chat/completions", {
  10. headers: {
  11. "Content-Type": "application/json",
  12. Authorization: `Bearer ${apiKey}`,
  13. },
  14. method: "POST",
  15. body: payload,
  16. });
  17. const stream = new ReadableStream({
  18. async start(controller) {
  19. function onParse(event: any) {
  20. if (event.type === "event") {
  21. const data = event.data;
  22. // https://beta.openai.com/docs/api-reference/completions/create#completions/create-stream
  23. if (data === "[DONE]") {
  24. controller.close();
  25. return;
  26. }
  27. try {
  28. const json = JSON.parse(data);
  29. const text = json.choices[0].delta.content;
  30. const queue = encoder.encode(text);
  31. controller.enqueue(queue);
  32. } catch (e) {
  33. controller.error(e);
  34. }
  35. }
  36. }
  37. const parser = createParser(onParse);
  38. for await (const chunk of res.body as any) {
  39. parser.feed(decoder.decode(chunk));
  40. }
  41. },
  42. });
  43. return stream;
  44. }
  45. export async function POST(req: NextRequest) {
  46. try {
  47. console.log("Request", req);
  48. const body = await req.text();
  49. const stream = await createStream(body);
  50. return new Response(stream);
  51. } catch (error) {
  52. console.error(error);
  53. }
  54. }
  55. export const config = {
  56. runtime: "edge",
  57. };