From 2e2a0f28b4f48da6f9cbab665b40524e0008f41d Mon Sep 17 00:00:00 2001 From: Jack Merrill Date: Tue, 6 May 2025 01:43:35 -0400 Subject: [PATCH] i gave up we're using elevenlabs --- app/actions.ts | 126 +++++++++---------- app/api/process-document/route.ts | 198 ++++++++++++++++++++++++++++++ bun.lockb | Bin 343350 -> 352728 bytes components/KokoroReader.tsx | 10 +- components/TTSProvider.tsx | 69 +++++++---- components/UploadZone.tsx | 2 +- package.json | 1 + 7 files changed, 310 insertions(+), 96 deletions(-) create mode 100644 app/api/process-document/route.ts diff --git a/app/actions.ts b/app/actions.ts index 784a66e..a2f3899 100644 --- a/app/actions.ts +++ b/app/actions.ts @@ -6,6 +6,8 @@ import { headers } from "next/headers"; import { redirect } from "next/navigation"; import { Provider } from "@supabase/supabase-js"; import { revalidatePath } from "next/cache"; +import { ElevenLabsClient } from "elevenlabs"; +import { Readable } from "stream"; export const signUpAction = async (formData: FormData) => { const email = formData.get("email")?.toString(); @@ -75,79 +77,61 @@ export const signInAction = async (formData: FormData) => { redirect("/dashboard"); }; -export const forgotPasswordAction = async (formData: FormData) => { - const email = formData.get("email")?.toString(); - const supabase = await createClient(); - const origin = (await headers()).get("origin"); - const callbackUrl = formData.get("callbackUrl")?.toString(); - - if (!email) { - return encodedRedirect("error", "/forgot-password", "Email is required"); - } - - const { error } = await supabase.auth.resetPasswordForEmail(email, { - redirectTo: `${origin}/auth/callback?redirect_to=/protected/reset-password`, - }); - - if (error) { - console.error(error.message); - return encodedRedirect( - "error", - "/forgot-password", - "Could not reset password" - ); - } - - if (callbackUrl) { - return redirect(callbackUrl); - } - - return encodedRedirect( - "success", - "/forgot-password", - "Check your email for a link to reset your password." - ); -}; - -export const resetPasswordAction = async (formData: FormData) => { - const supabase = await createClient(); - - const password = formData.get("password") as string; - const confirmPassword = formData.get("confirmPassword") as string; - - if (!password || !confirmPassword) { - encodedRedirect( - "error", - "/protected/reset-password", - "Password and confirm password are required" - ); - } - - if (password !== confirmPassword) { - encodedRedirect( - "error", - "/protected/reset-password", - "Passwords do not match" - ); - } - - const { error } = await supabase.auth.updateUser({ - password: password, - }); - - if (error) { - encodedRedirect( - "error", - "/protected/reset-password", - "Password update failed" - ); - } - - encodedRedirect("success", "/protected/reset-password", "Password updated"); -}; - export const signOutAction = async () => { const supabase = await createClient(); await supabase.auth.signOut(); return redirect("/login"); }; + +const elevenLabs = new ElevenLabsClient({ + apiKey: process.env.ELEVENLABS_API_KEY, +}); + +export const synthesizeTTSAction = async (data: { + text: string; + previous_text: string; + next_text: string; + voice: string; + index: number; +}) => { + const { text, voice, index } = data; + console.log("Generating TTS for text:", text, "with voice:", voice); + + if (!text) { + throw new Error("Text is required"); + } + + try { + // Call ElevenLabs API to generate the audio + const audioStream = await elevenLabs.textToSpeech.convertAsStream( + "gUABw7pXQjhjt0kNFBTF", + { + text, + output_format: "mp3_44100_128", + voice_settings: { + stability: 0.75, + speed: 1.0, + similarity_boost: 0.75, + }, + previous_text: data.previous_text, + next_text: data.next_text, + model_id: "eleven_multilingual_v2", + } + ); + const chunks: Buffer[] = []; + + for await (const chunk of audioStream) { + chunks.push(chunk); + } + + const audioBuffer = Buffer.concat(chunks); + + // Create a Blob from the Buffer + const audioBlob = new Blob([audioBuffer], { type: "audio/mpeg" }); + + return audioBlob; + } catch (error) { + console.error("Error generating TTS:", error); + throw new Error("Failed to generate TTS audio stream"); + } +}; diff --git a/app/api/process-document/route.ts b/app/api/process-document/route.ts new file mode 100644 index 0000000..7f271af --- /dev/null +++ b/app/api/process-document/route.ts @@ -0,0 +1,198 @@ +import { NextRequest, NextResponse } from "next/server"; +import { Mistral } from "@mistralai/mistralai"; +import pLimit from "p-limit"; +import { createClient } from "@/utils/supabase/server"; + +const corsHeaders = { + "Access-Control-Allow-Origin": "*", + "Access-Control-Allow-Headers": + "authorization, x-client-info, apikey, content-type", +}; + +const apiKey = process.env.MISTRAL_API_KEY!; +const client = new Mistral({ apiKey }); + +const PROCESSING_PROMPT = ` +You are a document processing AI. Your task is to process the Markdown text scanned from a document page and return it in a clean and structured format. + +The textual page data should only be returned in valid Markdown format. Use proper headings and subheadings to structure the content. **Do not add headings if they do not exist in the original text.** +Any images should be included. +Do not return the Markdown as a code block, only as a raw string, without any new lines. + +No data or information should ever be removed, it should only be processed and formatted. + +There are in-text citations/references in the text, remove them from the text (**but most importantly, keep the reference number in the text. use a tag**) and put them into an object where the key is the reference number and the value is the text. If any citations contain JSON-breaking characters, ensure they are properly escaped. This includes characters like double quotes, backslashes, and newlines. + +The Markdown should be human-readable and well-formatted. The markdown string should properly sanitized and should not break a JSON parser when returned as the final format. + +Return the final result as a text object with the following structure (without code block formatting): + +""" + + +--------- + +{ + "citations": [ + { + "number": 1, // The number as it appears in the text + "text": "Citation text 1" // Ensure any JSON-breaking characters are properly escaped + }, + { + "number": 2, + "text": "Citation text 2" + } + ] +} +""" + +Do not return the text object as a code block, only as a raw string. +`; + +async function getCitations(citationsStr: string) { + try { + const citations = JSON.parse(citationsStr).citations || {}; + + return + } + + +} + +export async function POST(req: NextRequest) { + if (req.method === "OPTIONS") { + return new NextResponse(null, { + headers: { + ...corsHeaders, + "Access-Control-Allow-Methods": "POST, OPTIONS", + }, + }); + } + + const formData = await req.formData(); + const accessToken = formData.get("access_token") as string; + const refreshToken = formData.get("refresh_token") as string; + + if (!formData.has("file") || !accessToken || !refreshToken) { + return NextResponse.json( + { + error: "Missing required fields: file, access_token, or refresh_token", + }, + { status: 400 } + ); + } + + const supabase = await createClient(); + + const file = formData.get("file") as File; + const fileName = file.name; + const uuid = crypto.randomUUID(); + + try { + // Authenticate the user + const { + data: { user }, + error: sessionError, + } = await supabase.auth.setSession({ + access_token: accessToken, + refresh_token: refreshToken, + }); + + if (sessionError) { + throw new Error("Failed to set session: " + sessionError.message); + } + + if (!user) { + throw new Error("User not authenticated"); + } + + // Upload the file to Supabase storage + const { data: storageData, error: storageError } = await supabase.storage + .from("documents") + .upload(`${user.id}/${uuid}.pdf`, file); + + if (storageError) { + throw new Error("Failed to upload file: " + storageError.message); + } + + // Insert document record + const { error: docError } = await supabase.from("documents").insert({ + id: uuid, + file_name: file.name, + owner: user.id, + raw_file: storageData.id, + is_processing: true, + }); + + if (docError) { + throw new Error("Failed to insert document record: " + docError.message); + } + + // Upload file to Mistral + const uploadedPdf = await client.files.upload({ + file: { fileName, content: file }, + purpose: "ocr", + }); + + const signedUrl = await client.files.getSignedUrl({ + fileId: uploadedPdf.id, + }); + + // Process OCR + const ocrResponse = await client.ocr.process({ + model: "mistral-ocr-latest", + document: { type: "document_url", documentUrl: signedUrl.url }, + }); + + const limit = pLimit(2); + const promises = ocrResponse.pages.map((page) => + limit(async () => { + const response = await client.chat.complete({ + model: "mistral-small-latest", + messages: [ + { + role: "system", + content: [{ type: "text", text: PROCESSING_PROMPT }], + }, + { role: "user", content: [{ type: "text", text: page.markdown }] }, + ], + }); + + const split = response.choices[0].message.content.split("---------"); + const content = split[0].trim(); + const citationsStr = split[1]?.trim() || "{}"; + console.log(citationsStr); + + const citations = await getCitations(citationsStr); + + return { + ...page, + markdown: content, + citations, + }; + }) + ); + + const results = await Promise.all(promises); + + // Update document record with OCR data + const { error: updateError } = await supabase + .from("documents") + .update({ ocr_data: results, is_processing: false }) + .eq("id", uuid); + + if (updateError) { + throw new Error( + "Failed to update document record: " + updateError.message + ); + } + + return NextResponse.json({ + message: "Document processed successfully", + results, + }); + } catch (error: any) { + console.error("Error processing document:", error); + return NextResponse.json({ error: error.message }, { status: 500 }); + } +} diff --git a/bun.lockb b/bun.lockb index e0ee5d7d42e610497f04037186617784bf91b4b1..f87940c5467af20bf5c3b63b7b26207cd9043b50 100755 GIT binary patch delta 69456 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 ZU21K%%#J#jGqdNYQ8(4k-RyCJ{{*WTBj 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 diff --git a/components/KokoroReader.tsx b/components/KokoroReader.tsx index 6c38a84..f80c9a4 100644 --- a/components/KokoroReader.tsx +++ b/components/KokoroReader.tsx @@ -22,6 +22,7 @@ export default function KokoroReader({ pages }: { pages: any[] }) { playSentence, playInOrder, status, + pause, } = useTTS(); const [playing, setPlaying] = useState(false); @@ -40,6 +41,11 @@ export default function KokoroReader({ pages }: { pages: any[] }) { playInOrder(currentSentence || 0); }; + const paused = () => { + setPlaying(false); + pause(); + }; + return (
@@ -48,13 +54,13 @@ export default function KokoroReader({ pages }: { pages: any[] }) { variant="ghost" size="icon" className="h-10 w-10" - onClick={play} + onClick={status === "ready" ? play : paused} disabled={status === null} > {status === "running" ? ( ) : ( - Play + {playing ? "Pause" : "Play"} )} {playing ? : } diff --git a/components/TTSProvider.tsx b/components/TTSProvider.tsx index 7b85e16..6c2338d 100644 --- a/components/TTSProvider.tsx +++ b/components/TTSProvider.tsx @@ -10,7 +10,7 @@ import React, { } from "react"; import removeMarkdown from "remove-markdown"; import { toast } from "sonner"; -import * as Echogarden from "echogarden"; +import { synthesizeTTSAction } from "@/app/actions"; // More robust sentence splitter using Intl.Segmenter for better accuracy. function splitIntoSentences(text: string): string[] { @@ -50,7 +50,6 @@ export const TTSProvider = ({ children: ReactNode; }) => { const supabase = createClient(); - // Combine pages and split into sentences. const fullText = pages.join("\n"); const sentences = splitIntoSentences(fullText).filter( (sentence) => sentence.trim() !== "\\n" && sentence.trim() !== "" @@ -63,30 +62,42 @@ export const TTSProvider = ({ const [voices, setVoices] = useState([]); const [status, setStatus] = useState<"ready" | "running" | null>("ready"); + // Cache for preloaded audio + const audioCache = useRef>(new Map()); + + // Preload audio for a range of sentences + const preloadAudio = async (startIndex: number, range: number = 3) => { + for ( + let i = startIndex; + i < Math.min(sentences.length, startIndex + range); + i++ + ) { + if (!audioCache.current.has(i)) { + console.log(`Preloading audio for sentence ${i}: ${sentences[i]}`); + try { + const audioUrl = await generateTTS(sentences[i], i); + audioCache.current.set(i, audioUrl); // Cache the audio URL + } catch (error) { + console.error(`Error preloading audio for sentence ${i}:`, error); + } + } + } + }; + async function generateTTS(sentence: string, index: number): Promise { try { - // const { data, error } = await supabase.functions.invoke("generate-tts", { - // body: { - // text: sentence, - // voice: selectedSpeaker, - // index, - // }, - // }); - - const { audio } = await Echogarden.synthesize(sentence, { - engine: "kokoro", + const blob = await synthesizeTTSAction({ + text: sentence, + previous_text: sentences[index - 1] || "", + next_text: sentences[index + 1] || "", voice: selectedSpeaker, + index, }); - - setStatus("running"); - - if (!Buffer.isBuffer(audio)) { - throw new Error("Audio data is not a buffer"); + if (!blob) { + throw new Error("Failed to generate TTS"); } - - const blob = new Blob([audio], { type: "audio/wav" }); - - return URL.createObjectURL(blob); + const audioUrl = URL.createObjectURL(blob); + return audioUrl; } catch (error) { console.error("Error generating TTS:", error); toast.error("Failed to generate TTS. Please try again."); @@ -99,7 +110,15 @@ export const TTSProvider = ({ const sentence = removeMarkdown(sentences[index]); try { - const audioUrl = await generateTTS(sentence, index); + let audioUrl = audioCache.current.get(index); + if (!audioUrl) { + console.log( + `Audio not preloaded for sentence ${index}, generating on the fly.` + ); + audioUrl = await generateTTS(sentence, index); + audioCache.current.set(index, audioUrl); // Cache the generated audio + } + if (audioRef.current) { audioRef.current.src = audioUrl; await new Promise((res) => { @@ -125,6 +144,7 @@ export const TTSProvider = ({ console.log("Playing sentence:", i, sentences[i]); try { await playSentence(i); + preloadAudio(i + 1); // Preload the next sentence after playing } catch (error) { console.error("Error playing sentence:", error); break; // Stop playback on error @@ -151,6 +171,11 @@ export const TTSProvider = ({ } }; + // Preload sentences when the current sentence changes + useEffect(() => { + preloadAudio(currentSentence); + }, [currentSentence]); + const value: TTSContextType = { sentences, currentSentence, diff --git a/components/UploadZone.tsx b/components/UploadZone.tsx index 58f6e47..2c52db0 100644 --- a/components/UploadZone.tsx +++ b/components/UploadZone.tsx @@ -27,7 +27,7 @@ export default function UploadZone({ user }: { user?: { id: string } }) { body.append("access_token", data.session?.access_token || ""); body.append("refresh_token", data.session?.refresh_token || ""); - const edgeFunctionUrl = `${process.env.NEXT_PUBLIC_SUPABASE_URL}/functions/v1/process-document`; + const edgeFunctionUrl = `/api/process-document`; // Start listening to the SSE stream const eventSource = new SSE(edgeFunctionUrl, { diff --git a/package.json b/package.json index 3e662aa..2dae9b9 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,7 @@ "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "echogarden": "^2.7.0", + "elevenlabs": "^1.57.0", "kokoro-js": "^1.2.0", "lucide-react": "^0.486.0", "next": "latest",