Spaces:
Sleeping
Sleeping
File size: 3,419 Bytes
04e0266 ae80634 04e0266 9510bea 04e0266 ae80634 04e0266 bf51166 04e0266 bf51166 04e0266 9510bea bf51166 04e0266 9510bea 04e0266 9510bea 04e0266 9510bea bf51166 9510bea bf51166 9510bea bf51166 9510bea 04e0266 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 | import { NextRequest, NextResponse } from "next/server";
import { createClient } from "@/lib/supabase/server";
const GRADIO_URL = process.env.CLAUSEGUARD_GRADIO_URL || "https://gaurv007-clauseguard.hf.space";
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 { text_a, text_b } = body;
if (!text_a || !text_b || text_a.trim().length < 50 || text_b.trim().length < 50) {
return NextResponse.json(
{ error: "Both contracts must have at least 50 characters." },
{ status: 400 }
);
}
// FIX v4.3: REMOVED HTML-escaping that CORRUPTED contract text before analysis.
// The old code did text_a.replace(/</g, "<") which permanently mutated
// the text (e.g., ">$10,000" → ">$10,000"). Sanitization is the
// frontend's job — React auto-escapes in JSX. Never mutate analysis input.
// Call Gradio Space API
const submitRes = await fetch(`${GRADIO_URL}/gradio_api/call/compare`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ data: [text_a, text_b] }),
});
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");
// Poll for result with retry
let resultText = "";
let attempts = 0;
const maxAttempts = 60;
let delay = 500;
while (attempts < maxAttempts) {
const resultRes = await fetch(
`${GRADIO_URL}/gradio_api/call/compare/${event_id}`,
{ headers: { Accept: "text/event-stream" } }
);
resultText = await resultRes.text();
if (resultText.includes("event: complete")) break;
if (resultText.includes("event: error")) {
const errMatch = resultText.match(/data:\s*(.+)/);
throw new Error(errMatch ? errMatch[1] : "Comparison failed in backend");
}
await new Promise(r => setTimeout(r, delay));
delay = Math.min(delay * 1.2, 2000);
attempts++;
}
if (!resultText.includes("event: complete")) {
throw new Error("Comparison timed out. Please try again.");
}
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);
// gradioData[0] = comparison HTML
// gradioData[1] = raw JSON comparison data
const comparisonResult = gradioData[1];
if (typeof comparisonResult === "object" && comparisonResult !== null) {
return NextResponse.json(comparisonResult);
}
// If it's a string (JSON stringified), parse it
if (typeof comparisonResult === "string") {
return NextResponse.json(JSON.parse(comparisonResult));
}
throw new Error("Unexpected comparison result format");
} catch (error: any) {
console.error("Compare error:", error.message);
return NextResponse.json({ error: error.message || "Comparison failed" }, { status: 500 });
}
}
|