import { defineBackground } from 'wxt/sandbox'; export default defineBackground(() => { console.log('LexAI background service worker started'); // Handle messages from content scripts chrome.runtime.onMessage.addListener((message, sender, sendResponse) => { if (message.type === 'ANALYZE_TEXT') { handleAnalyzeText(message.payload).then(sendResponse); return true; // Keep channel open for async response } }); }); async function handleAnalyzeText(payload: { text: string; action: string }) { try { const config = await chrome.storage.local.get(['provider', 'apiKey', 'model']); if (!config.apiKey) { return { error: 'No API key configured. Please open LexAI settings.' }; } // Route to correct provider switch (config.provider) { case 'openai': return await callOpenAI(payload, config); case 'anthropic': return await callAnthropic(payload, config); case 'groq': return await callGroq(payload, config); default: return { error: 'Unknown provider. Please check settings.' }; } } catch (err) { return { error: String(err) }; } } async function callOpenAI(payload: { text: string; action: string }, config: any) { const res = await fetch('https://api.openai.com/v1/chat/completions', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${config.apiKey}`, }, body: JSON.stringify({ model: config.model || 'gpt-4o-mini', messages: [ { role: 'system', content: getSystemPrompt(payload.action) }, { role: 'user', content: payload.text }, ], }), }); const data = await res.json(); return { result: data.choices?.[0]?.message?.content }; } async function callAnthropic(payload: { text: string; action: string }, config: any) { const res = await fetch('https://api.anthropic.com/v1/messages', { method: 'POST', headers: { 'Content-Type': 'application/json', 'x-api-key': config.apiKey, 'anthropic-version': '2023-06-01', }, body: JSON.stringify({ model: config.model || 'claude-3-5-haiku-20241022', max_tokens: 1024, system: getSystemPrompt(payload.action), messages: [{ role: 'user', content: payload.text }], }), }); const data = await res.json(); return { result: data.content?.[0]?.text }; } async function callGroq(payload: { text: string; action: string }, config: any) { const res = await fetch('https://api.groq.com/openai/v1/chat/completions', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${config.apiKey}`, }, body: JSON.stringify({ model: config.model || 'llama-3.3-70b-versatile', messages: [ { role: 'system', content: getSystemPrompt(payload.action) }, { role: 'user', content: payload.text }, ], }), }); const data = await res.json(); return { result: data.choices?.[0]?.message?.content }; } function getSystemPrompt(action: string): string { const prompts: Record = { grammar: 'You are a grammar checker. Fix grammar, spelling, and punctuation errors in the text. Return only the corrected text without explanations.', rephrase: 'You are a writing assistant. Rephrase the given text to be clearer and more professional. Return only the rephrased text.', tone: 'You are a writing coach. Analyze the tone of the text and suggest improvements. Be concise.', shorten: 'You are an editor. Shorten the text while keeping the key message. Return only the shortened version.', expand: 'You are a writer. Expand the given text with more detail and context. Return only the expanded version.', }; return prompts[action] || prompts.grammar; }