diff --git a/background.js b/background.js index d9ddabb..d1b5337 100644 --- a/background.js +++ b/background.js @@ -13,6 +13,13 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => { .catch(err => sendResponse({ success: false, error: err.message })); return true; // Keep message channel open for async } + + if (message.type === 'GEMINI_PROCESS_VOICE') { + handleVoiceProcessing(message.payload) + .then(result => sendResponse({ success: true, data: result })) + .catch(err => sendResponse({ success: false, error: err.message })); + return true; // Keep message channel open for async + } }); // ─── Core API call ─────────────────────────────────────────────────────────── @@ -54,7 +61,7 @@ async function handleGeminiRequest({ apiKey, prompt, tab, action = 'generateText if (response.ok) { const data = await response.json(); - + if (action === 'generatePdf') { if (!data.pdf) throw new Error('Empty PDF response from server.'); await incrementUsage(); @@ -191,3 +198,77 @@ function storageGet(keys) { function storageSet(data) { return new Promise(resolve => chrome.storage.local.set(data, resolve)); } + +// ─── Voice Processing (for Claude Arabic Voice extension) ──────────────────── + +async function handleVoiceProcessing({ apiKey, model, text, language }) { + if (!apiKey) { + throw new Error('Gemini API key is required'); + } + + // Detect if text is Arabic + const isArabic = /[\u0600-\u06FF]/.test(text); + const langName = isArabic ? 'Arabic' : 'the detected language'; + + const prompt = `You are a text refinement assistant. Your task is to: + +1. Correct any speech recognition errors in the following text +2. Fix punctuation, capitalization, and formatting +3. Keep the original meaning and content intact +4. Do NOT add any new information or commentary +5. Return ONLY the corrected text, nothing else + +The text is in ${langName}. Preserve the original language. + +TEXT TO REFINE: +${text} + +CORRECTED TEXT:`; + + const response = await fetch('https://cv.intaleqapp.com/cv/server/generate_cv.php', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + action: 'generateText', + apiKey: apiKey, + prompt: prompt + }) + }); + + if (!response.ok) { + const errText = await response.text().catch(() => ''); + let errMsg; + try { + const errData = JSON.parse(errText); + errMsg = errData.error?.message || `HTTP ${response.status}`; + } catch (e) { + errMsg = `HTTP ${response.status}: ${errText.substring(0, 200)}`; + } + throw new Error(`Gemini API error: ${errMsg}`); + } + + const responseText = await response.text(); + let data; + try { + data = JSON.parse(responseText); + } catch (e) { + return { text: responseText.trim() }; + } + + if (data.candidates && data.candidates[0]) { + const resultText = data.candidates[0].content?.parts?.[0]?.text; + if (resultText) { + return { text: resultText.trim() }; + } + } + + if (data.error) { + throw new Error(`Server error: ${data.error}${data.details ? ' - ' + JSON.stringify(data.details) : ''}`); + } + + if (typeof data === 'string') { + return { text: data.trim() }; + } + + throw new Error('Empty response from Gemini API'); +}