import { pipeline, env } from './transformers/transformers.min.js'; env.allowLocalModels = true; env.backends.onnx.wasm.wasmPaths = { 'default': './transformers/', 'threaded': './transformers/', 'simd': './transformers/', 'simd-threaded': './transformers/', }; env.allowRemoteModels = false; let classifier = null; let llmInitializationPromise = null; async function initializeLLM() { if (classifier) { return; } if (llmInitializationPromise) { return llmInitializationPromise; } llmInitializationPromise = (async () => { try { classifier = await pipeline( 'zero-shot-classification', 'nli-deberta-v3-small', { local_files_only: true, model_file_name: "model.onnx", } ); llmInitializationPromise = null; } catch (error) { classifier = null; llmInitializationPromise = null; throw error; } })(); return llmInitializationPromise; } initializeLLM(); chrome.runtime.onMessage.addListener((message, sender, sendResponse) => { (async () => { if (!classifier) { try { await initializeLLM(); } catch (error) { sendResponse({ type: "LLM_ERROR", error: "LLM initialization failed: " + error.message }); return; } } try { switch (message.type) { case 'ANALYZE_SENTIMENT': const headlineForSentiment = message.payload.headline; const sentimentLabels = ['negative', 'positive', 'neutral', 'depressing', 'worrying']; const sentimentOutput = await classifier(headlineForSentiment, sentimentLabels); let detectedSentiment = 'neutral'; if (sentimentOutput && sentimentOutput.scores && sentimentOutput.labels) { const sortedSentimentResults = sentimentOutput.scores.map((score, index) => ({ label: sentimentOutput.labels[index], score: score })).sort((a, b) => b.score - a.score); if (sortedSentimentResults.length > 0 && sortedSentimentResults[0].score > 0.7) { detectedSentiment = sortedSentimentResults[0].label; } else if (sortedSentimentResults.length > 0) { const topLabel = sortedSentimentResults[0].label; if (['negative', 'depressing', 'worrying'].includes(topLabel)) { detectedSentiment = topLabel; } else { } } } sendResponse({ type: "ANALYSIS_RESULT", result: { sentiment: detectedSentiment } }); break; case 'ANALYZE_HEADLINE_CATEGORY': const headline = message.payload.headline; const selectedIssues = message.payload.selectedIssues || []; const candidateLabels = ['gun-control', 'gun-rights', 'privacy', 'immigration', 'climate-change', 'healthcare', 'racial-justice', 'lgbtq-rights', 'economic-inequality', 'reproductive-rights', 'education-reform', 'criminal-justice', 'voting-rights', 'campaign-finance', 'foreign-policy', 'national-security', 'free-speech', 'net-neutrality', 'labor-rights', 'affordable-housing', 'environmental-protection', 'space-exploration', 'drug-policy-reform', 'veterans-affairs', 'senior-citizen-rights']; const analysisOutput = await classifier(headline, candidateLabels); let categories = []; if (analysisOutput && analysisOutput.scores && analysisOutput.labels) { const sortedResults = analysisOutput.scores.map((score, index) => ({ label: analysisOutput.labels[index], score: score })).sort((a, b) => b.score - a.score); categories = sortedResults .filter(item => item.score > 0.5 && selectedIssues.includes(item.label)) .map(item => item.label); if (categories.length === 0 && sortedResults.length > 0) { const topLabel = sortedResults[0].label; if (selectedIssues.includes(topLabel)) { categories.push(topLabel); } else { } } } sendResponse({ type: "ANALYSIS_RESULT", result: { categories: categories } }); break; default: sendResponse({ type: "UNKNOWN_MESSAGE" }); break; } } catch (error) { sendResponse({ type: "LLM_ERROR", error: "Processing error: " + error.message }); } })(); return true; });