| import { NextResponse } from 'next/server'; |
|
|
| const MEDGEMMA_BACKEND_URL = |
| process.env.MEDGEMMA_BACKEND_URL || 'http://localhost:8100'; |
| const MEDGEMMA_API_KEY = process.env.MEDGEMMA_API_KEY || ''; |
|
|
| function backendHeaders(): Record<string, string> { |
| const h: Record<string, string> = { 'Content-Type': 'application/json' }; |
| if (MEDGEMMA_API_KEY) h['x-api-key'] = MEDGEMMA_API_KEY; |
| return h; |
| } |
|
|
| interface TranslateRequest { |
| text: string; |
| source_lang?: string; |
| target_lang?: string; |
| provider?: string; |
| model_id?: string; |
| quantize?: string | null; |
| } |
|
|
| |
| export async function POST(request: Request) { |
| try { |
| const body: TranslateRequest = await request.json(); |
|
|
| if (!body.text || body.text.trim().length === 0) { |
| return NextResponse.json( |
| { success: false, error: 'Text to translate is required' }, |
| { status: 400 } |
| ); |
| } |
|
|
| const backendResponse = await fetch( |
| `${MEDGEMMA_BACKEND_URL}/api/v1/translate`, |
| { |
| method: 'POST', |
| headers: backendHeaders(), |
| body: JSON.stringify({ |
| text: body.text, |
| source_lang: body.source_lang ?? 'hr', |
| target_lang: body.target_lang ?? 'en', |
| provider: body.provider ?? 'local', |
| model_id: body.model_id ?? 'google/translategemma-12b-it', |
| quantize: body.quantize ?? null, |
| }), |
| |
| signal: AbortSignal.timeout(600_000), |
| } |
| ); |
|
|
| if (!backendResponse.ok) { |
| const errorData = await backendResponse.json().catch(() => null); |
| const errorMessage = |
| errorData?.detail || `Backend returned ${backendResponse.status}`; |
|
|
| return NextResponse.json( |
| { success: false, error: errorMessage }, |
| { status: backendResponse.status } |
| ); |
| } |
|
|
| const data = await backendResponse.json(); |
|
|
| return NextResponse.json({ |
| success: true, |
| translated_text: data.translated_text, |
| source_lang: data.source_lang, |
| target_lang: data.target_lang, |
| chunks_count: data.chunks_count, |
| elapsed_ms: data.elapsed_ms, |
| model_id: data.model_id, |
| provider: data.provider, |
| }); |
| } catch (error) { |
| const message = |
| error instanceof Error ? error.message : 'Translation failed'; |
|
|
| if (message.includes('timeout') || message.includes('Timeout')) { |
| return NextResponse.json( |
| { |
| success: false, |
| error: |
| 'Translation timed out. The model may still be loading or the text is very long.', |
| }, |
| { status: 504 } |
| ); |
| } |
|
|
| if ( |
| message.includes('ECONNREFUSED') || |
| message.includes('fetch failed') || |
| message.includes('connect') |
| ) { |
| return NextResponse.json( |
| { |
| success: false, |
| error: |
| 'Cannot connect to translation backend. Make sure the MedGemma backend is running on port 8100.', |
| }, |
| { status: 503 } |
| ); |
| } |
|
|
| return NextResponse.json( |
| { success: false, error: message }, |
| { status: 500 } |
| ); |
| } |
| } |
|
|