Spaces:
Sleeping
Sleeping
| import { NextRequest, NextResponse } from "next/server"; | |
| import { createClient } from "@/lib/supabase/server"; | |
| /** | |
| * FIX v4.3: Redline route now works through the Gradio Space directly. | |
| * The old code pointed to a non-existent FastAPI Space (gaurv007-clauseguard-api.hf.space). | |
| * Since redlining is already part of the analyze pipeline (returned in analysis results), | |
| * this endpoint is primarily for re-running redlines on existing text. | |
| */ | |
| const GRADIO_URL = process.env.CLAUSEGUARD_GRADIO_URL || "https://gaurv007-clauseguard.hf.space"; | |
| const API_URL = process.env.CLAUSEGUARD_API_URL || ""; | |
| export async function POST(req: NextRequest) { | |
| try { | |
| const supabase = await createClient(); | |
| const { data: { user } } = await supabase.auth.getUser(); | |
| if (!user) { | |
| return NextResponse.json({ error: "Unauthorized. Please log in." }, { status: 401 }); | |
| } | |
| const body = await req.json(); | |
| const { session_id, text, use_llm } = body; | |
| if (!session_id && !text) { | |
| return NextResponse.json( | |
| { error: "Provide session_id or text" }, | |
| { status: 400 } | |
| ); | |
| } | |
| // Try FastAPI backend first (if configured and available) | |
| if (API_URL) { | |
| try { | |
| const response = await fetch(`${API_URL}/api/redline`, { | |
| method: "POST", | |
| headers: { "Content-Type": "application/json" }, | |
| body: JSON.stringify({ session_id, text, use_llm: use_llm ?? true }), | |
| }); | |
| if (response.ok) { | |
| const result = await response.json(); | |
| return NextResponse.json(result); | |
| } | |
| } catch { | |
| // Fall through to Gradio approach | |
| } | |
| } | |
| // Fallback: If text is provided, run full analysis via Gradio (includes redlines) | |
| if (text) { | |
| if (text.trim().length < 50) { | |
| return NextResponse.json({ error: "Text too short (min 50 chars)" }, { status: 400 }); | |
| } | |
| const submitRes = await fetch(`${GRADIO_URL}/gradio_api/call/analyze`, { | |
| method: "POST", | |
| headers: { "Content-Type": "application/json" }, | |
| body: JSON.stringify({ data: [text] }), | |
| }); | |
| if (!submitRes.ok) { | |
| throw new Error(`Gradio submit failed: ${submitRes.status}`); | |
| } | |
| const { event_id } = await submitRes.json(); | |
| if (!event_id) throw new Error("No event_id from Gradio"); | |
| let resultText = ""; | |
| let attempts = 0; | |
| while (attempts < 90) { | |
| const resultRes = await fetch( | |
| `${GRADIO_URL}/gradio_api/call/analyze/${event_id}`, | |
| { headers: { Accept: "text/event-stream" } } | |
| ); | |
| resultText = await resultRes.text(); | |
| if (resultText.includes("event: complete")) break; | |
| if (resultText.includes("event: error")) throw new Error("Redline analysis failed"); | |
| await new Promise(r => setTimeout(r, 1000)); | |
| attempts++; | |
| } | |
| if (!resultText.includes("event: complete")) { | |
| throw new Error("Analysis timed out"); | |
| } | |
| // Parse the result to extract redlines from the JSON report | |
| const completeIdx = resultText.indexOf("event: complete"); | |
| const dataIdx = resultText.indexOf("data: ", completeIdx); | |
| if (dataIdx === -1) throw new Error("No data in response"); | |
| const dataStr = resultText.substring(dataIdx + 6).trim(); | |
| const gradioData = JSON.parse(dataStr); | |
| // Download JSON report file | |
| const jsonFileObj = gradioData[8]; | |
| if (jsonFileObj?.url) { | |
| const jsonRes = await fetch(jsonFileObj.url); | |
| if (jsonRes.ok) { | |
| const analysisData = await jsonRes.json(); | |
| if (analysisData.redlines) { | |
| return NextResponse.json({ redlines: analysisData.redlines, count: analysisData.redlines.length }); | |
| } | |
| } | |
| } | |
| return NextResponse.json({ redlines: [], count: 0 }); | |
| } | |
| // No FastAPI backend and only session_id provided (can't access Gradio sessions) | |
| return NextResponse.json({ | |
| error: "Redline by session_id requires the FastAPI backend. Provide contract text instead, or use the analysis results which already include redline suggestions.", | |
| }, { status: 400 }); | |
| } catch (error: any) { | |
| console.error("Redline error:", error.message); | |
| return NextResponse.json( | |
| { error: error.message || "Redlining failed" }, | |
| { status: 500 } | |
| ); | |
| } | |
| } | |