import { useEffect, useCallback } from 'react' import { WorkerMessage, ZeroShotWorkerInput } from '../../types' import { useModel } from '../../contexts/ModelContext' import { useZeroShotClassification } from '../../contexts/ZeroShotClassificationContext' import { Send, Loader2 } from 'lucide-react' function ZeroShotClassification() { const { text, setText, sections, setSections, config } = useZeroShotClassification() const { activeWorker, status, modelInfo, hasBeenLoaded, selectedQuantization } = useModel() const classify = useCallback(() => { if (!modelInfo || !activeWorker) { console.error('Model info or worker is not available') return } // Clear previous results setSections((sections) => sections.map((section) => ({ ...section, items: [] })) ) const message: ZeroShotWorkerInput = { type: 'classify', text, labels: sections .slice(0, sections.length - 1) .map((section) => section.title), model: modelInfo.id, dtype: selectedQuantization ?? 'fp32' } activeWorker.postMessage(message) }, [ text, sections, modelInfo, activeWorker, selectedQuantization, setSections ]) // Handle worker messages useEffect(() => { if (!activeWorker) return const onMessageReceived = (e: MessageEvent) => { const status = e.data.status if (status === 'output') { const { sequence, labels, scores } = e.data.output! // Threshold for classification const label = scores[0] > config.threshold ? labels[0] : 'Other' const sectionID = sections.map((x) => x.title).indexOf(label) ?? sections.length - 1 setSections((sections) => { const newSections = [...sections] newSections[sectionID] = { ...newSections[sectionID], items: [...newSections[sectionID].items, sequence] } return newSections }) } } activeWorker.addEventListener('message', onMessageReceived) return () => activeWorker.removeEventListener('message', onMessageReceived) }, [sections, activeWorker, config.threshold, setSections]) const busy: boolean = status !== 'ready' return (

Zero-Shot Classification

{/* Input Text Area */}