|
| 1 | +import { NextResponse } from "next/server" |
| 2 | +import { withAuth } from "@lib/api-utils" |
| 3 | + |
| 4 | +const appServerUrl = |
| 5 | + process.env.NEXT_PUBLIC_ENVIRONMENT === "selfhost" |
| 6 | + ? process.env.INTERNAL_APP_SERVER_URL |
| 7 | + : process.env.NEXT_PUBLIC_APP_SERVER_URL |
| 8 | + |
| 9 | +export const POST = withAuth(async function POST(request, { authHeader }) { |
| 10 | + try { |
| 11 | + const { messages, chatId } = await request.json() |
| 12 | + |
| 13 | + // Fetch user pricing/credits to pass to the backend |
| 14 | + const pricingResponse = await fetch( |
| 15 | + `${appServerUrl}/api/get-user-data`, |
| 16 | + { |
| 17 | + method: "POST", |
| 18 | + headers: { "Content-Type": "application/json", ...authHeader } |
| 19 | + } |
| 20 | + ) |
| 21 | + const userData = await pricingResponse.json() |
| 22 | + const pricing = userData?.data?.pricing || "free" |
| 23 | + const credits = userData?.data?.proCredits || 0 |
| 24 | + |
| 25 | + const backendResponse = await fetch(`${appServerUrl}/chat/message`, { |
| 26 | + method: "POST", |
| 27 | + headers: { "Content-Type": "application/json", ...authHeader }, |
| 28 | + body: JSON.stringify({ |
| 29 | + // Pass `messages` array instead of `input` |
| 30 | + messages, |
| 31 | + chatId, |
| 32 | + pricing, // Note: pricing and credits are still sent for backend logic |
| 33 | + credits |
| 34 | + }), |
| 35 | + // IMPORTANT: duplex must be set to 'half' to stream response body in Next.js Edge/Node runtime |
| 36 | + duplex: "half" |
| 37 | + }) |
| 38 | + |
| 39 | + if (!backendResponse.ok) { |
| 40 | + const errorText = await backendResponse.text() |
| 41 | + let errorMessage |
| 42 | + try { |
| 43 | + const errorJson = JSON.parse(errorText) |
| 44 | + errorMessage = |
| 45 | + errorJson.detail || |
| 46 | + errorJson.message || |
| 47 | + "Backend chat endpoint failed" |
| 48 | + } catch (e) { |
| 49 | + errorMessage = |
| 50 | + errorText || |
| 51 | + `Backend chat endpoint failed with status ${backendResponse.status}` |
| 52 | + } |
| 53 | + throw new Error(errorMessage) |
| 54 | + } |
| 55 | + |
| 56 | + // Return the streaming response directly to the client |
| 57 | + return new Response(backendResponse.body, { |
| 58 | + status: 200, |
| 59 | + headers: { |
| 60 | + // Use application/x-ndjson for newline-delimited JSON streams |
| 61 | + "Content-Type": "application/x-ndjson", |
| 62 | + "Cache-Control": "no-cache", |
| 63 | + Connection: "keep-alive", |
| 64 | + "X-Accel-Buffering": "no", // Disable buffering on Netlify/Vercel |
| 65 | + "Content-Encoding": "identity" |
| 66 | + } |
| 67 | + }) |
| 68 | + } catch (error) { |
| 69 | + console.error("API Error in /chat/message:", error) |
| 70 | + return NextResponse.json( |
| 71 | + { message: "Internal Server Error", error: error.message }, |
| 72 | + { status: 500 } |
| 73 | + ) |
| 74 | + } |
| 75 | +}) |
0 commit comments