Local-first, offline AI UI primitives + blocks - run ML models (chat, RAG, vision, audio) entirely in the browser. No servers, no API keys.
Attachment surface for the composer: image/file attach via picker, paste, and drag-and-drop with preview thumbnails, per-item removal, a hovercard preview, media-category auto-detection, and upload-state chips. Produces attachments via a bundled readFileAsDataUrl helper (copy-owned); the shape matches common chat image-content models.
Displays the RESOLVED provider identity - composing ProviderFallbackBadge for the tier and name - alongside the model id that actually served the request. While providerName is null it shows a Resolving provider placeholder, so the badge never claims a provider before one has resolved. Takes generic display props (providerName / tier / modelId / note). Distinct from ProviderFallbackBadge (the tier chip it composes): this adds the resolved provider identity plus the served model id. Data source: a provider-fallback resolver.
Surfaces the active AI backend tier — a zero-download built-in (Chrome AI) vs a model-download provider (Transformers.js) — plus a WASM threading variant (Multi-thread when cross-origin isolated / SharedArrayBuffer is available, else Single-thread). A software-side sibling to DeviceBadge; data source useCapabilities (crossOriginIsolated) + provider identifier.
Streaming grounded RAG over its OWN text/PDF corpus — token-by-token answers through the engine-owned generator (granite-4.0-350M) with [n] markers upgraded to hover-card inline citations resolved to retrieved sources (PDF page attribution + similarity), wall-clock duration, and cancel — carrying the core-pipeline ⇄ LangChain engine toggle. Split from ui/blocks/knowledge-base (Ask tab RAG lane; absorbs langchain-rag).
The model's own thinking tokens (DeepSeek-R1 style) in a collapsible region: auto-expands while streaming with an elapsed timer and auto-collapses on the final answer, plus a compact ThinkingBar one-line status strip. Tier of the thinking taxonomy: ThinkingBar -> Reasoning -> ChainOfThought.
An inline-annotated text renderer interleaving plain text with color-coded redaction tokens (e.g. [PER], [LOC]) styled per entity type with native tooltips, including a scanning loading skeleton and an empty placeholder. Takes source text + detected entity spans (start/end) from useExtractEntities; segments internally (overlaps resolved by earliest). Exports segmentText().
A tool-using ReAct research agent over its OWN on-device WebGPU-only WebLLM model (default Qwen3-1.7B-q4f16_1-MLC): three block-local tools (search over a bundled 8-article knowledge base, note, calculate), a step-by-step reasoning timeline, and a human-in-the-loop tool-approval gate (default on) with pause/approve/deny-feedback and immutable decision receipts. Ships a justified block-local WebLLM catalog slice (model-catalog.ts) and toolset + fixture corpus (tools.ts). Models download only behind an explicit Load action. Split from ui/blocks/agent-structured-data (Research Agent mode).
Streaming markdown renderer for assistant output: shows a cursor while streaming, tolerates partial/unterminated markdown without layout breakage, supports an optional typewriter reveal, and routes LaTeX/Mermaid blocks to swappable renderers gated behind props (declare katex/mermaid if used).
A ranked vertical list of {label, score} pairs — each row shows the label, a confidence percentage (via ConfidenceScoreBadge), and an animated horizontal fill bar proportional to the 0–1 score, with the top row highlighted. Ships skeleton-loading and empty-state slots. One data contract serves useClassify / useClassifyZeroShot / useDetectObjects / useFillMask / useSemanticSearch.
A floating scroll-to-bottom affordance tied to a chat container's scroll state — appears when the user scrolls up, scrolls to and pins the latest content. Pairs with a ScrollAnchor pin element. Data source: useChat.
A pill toggle for 2–4 mutually-exclusive named modes (ring-bordered container, active item tinted + ringed), plus a typed TabBar variant with disabledTabs gating. Fully controlled, generic over the id type. Covers OCR content-type, summary length, translation formality, browse/inspect modes.
A compact toolbar row for useSemanticCache complementing CacheBadge: entry count, hit-rate percentage, an icon-only clear-cache button (when entries > 0), and an enable/disable toggle (with a spinner while the embedding model loads). Pairs with a per-message CachedAnnotation ("Cached (38ms)"). Distinct from CacheBadge (model-download cache) — this surfaces semantic-cache hits on responses. Data source useSemanticCache.
Full text/PDF/OCR ingest into its OWN corpus with off/recursive/semantic chunking and a live chunk-boundary preview, then reranked vector search (over-fetch topK×3 → a real cross-encoder from the transformers ONNX group or the wllama GGUF group; raw + rerank scores preserved, never fabricated) with category facets and preset or corpus-calibrated similarity thresholds — carrying the core-pipeline ⇄ LangChain engine toggle. Over the promoted useKnowledgeBase engine layer; ships justified block-local ingest-panel + search-panel siblings. Nothing downloads until an explicit action. Split from ui/blocks/knowledge-base (Ingest + Search tabs; absorbs pdf-search + ocr-scanner).
Classify one text or thousands with DistilBERT SST-2 (one item per line, or a .txt/.csv first column) via useSequentialBatch — streaming results in input order with per-item error isolation, a cancel that keeps partial results, determinate progress plus throughput (items/sec, elapsed, ETA), aggregate positive/negative stats over every completed item, and a 100-row windowed result list. The model downloads only behind Run. No model bytes download until an explicit in-block action.
A '/'-triggered command palette over a local tool/command list — name, category, description, and icon — to layer onto a PromptInput Tools slot. Purely presentational; the consumer opens it (e.g. when the composer starts with '/') and supplies the query. Built on the shadcn/ui Command (cmdk) primitive.
Adaptive, device-aware CLIP photo ingest (streamEmbedManyImages at a computeOptimalBatchSize batch size shown on an adaptive-batch-card) with per-item progress, per-batch zero-shot categorization (other/0 fallback), and a grid/list gallery with filename + category + confidence + similar-count — per-photo delete, clear-all, and a cancellable ingest. Own usePhotoLibrary instance; CLIP downloads only behind an explicit Load. Split from ui/blocks/photo-search (Gallery tab).
In-message attributed-sources list extending Sources: numbered items, a similarity score with a radial confidence ring, and clamped body text with staggered fade-in, behind a collapsible Show N sources toggle. Data source: useSemanticSearch / useAnswerQuestion / useAskDocument.
Retrieval citations from local RAG results: a collapsible container with favicon/title/excerpt chips, a 0-1 relevance score, and an optional Web/Images/News tabbed layout. All metadata is local — no remote unfurl.
Shows origin/IndexedDB storage usage against quota as a meter, with a warning state past a configurable threshold and a graceful unavailable state (estimates are approximate and blocked in Safari private mode). Bind to useStorageQuota (default) or pass an explicit quota. Complements ContextUsageMeter (the token-budget gauge).
A streaming-TTS status surface: active state (WaveformActivityBars + spinner, synthesizing/playing label, processed-clause count, highlighted now-playing clause box) and finished state (clause-count summary, a generated-locally privacy note, and a Download WAV action). Driven by useStreamSpeech (isSynthesizing/isPlaying/currentClause/clauses); download via downloadBlob.
A result panel for useGenerateObject extending Response: pretty-printed JSON, an independently-usable inference-stats footer (tokens, duration, attempts), and a navigable typed schema-tree view.
A horizontal row of selectable prompt chips; each Suggestion invokes a callback with its text to seed the composer.
Summarize a document with extractive and abstractive modes and short/medium/long length presets, rendered in a split pane with input/summary word counts, a compression-ratio badge and bar, and a reading-time-saved estimate. On the Transformers.js path abstractive is served by DistilBART and extractive by a real on-device sentence-extraction algorithm drawing sentences verbatim from the source; Chrome summary styles are offered only when the Chrome Summarizer API actually serves the block. Resolves Chrome Built-in AI when available and falls back automatically behind an explicit download gate, with a truthful provider badge. No model bytes download until an explicit in-block action.
A karaoke-style transcript viewer that highlights words in lockstep with audio playback using word-level alignment timestamps — the playback-time -> word-index sync is pure client-side (binary search on timeupdate). Clicking a word seeks the audio to its start. Driven by useTranscribe word-level timestamps over a local audio Blob.
An in-conversation info/warning banner (not a message bubble) for local-first state changes: offline/online, model switch, capability-unavailable, WebGPU->WASM fallback, cache eviction, or download-required. Data source: useNetworkStatus / useCapabilities.
A controlled system-prompt editor (value in, onChange out) with quick-pick presets composed via the OptionList primitive: selecting a preset replaces the textarea value; free-form edits that match no preset deselect all presets. Exports SYSTEM_PROMPT_PRESETS and DEFAULT_SYSTEM_PROMPT. Presentational: persistence and model wiring stay in the consumer. Feeds useChat / useGenerateText systemPrompt.
A multi-step agent process as an ordered list of steps (index, tool, status, args, observation) with the final-answer step distinguished. Its data shape aligns with @localmode/react useAgent steps so agent UIs wire up without adapters.
Custom-label zero-shot classification with MobileBERT MNLI over a user-editable label set (add trimmed + case-insensitively deduped, remove, live count) with an email/message textarea and sample loader. Results render a top-result hero (winning label + confidence) above a ranked score list of all candidate labels. Guards empty input and an empty label set; the model downloads only behind Run. No model bytes download until an explicit in-block action.
A two-column (stacked on mobile) single-input → single-output NLP shell: labeled textarea + live word count + optional CharLimitIndicator on the left; a result pane (spinner / pre-wrap text / empty slot) with copy-with-feedback on the right; a run/cancel/clear toolbar; and an optional header slot. Layout-only — compatible with useSummarize/useTranslate/useFillMask/useAnswerQuestion/useGenerateText.
A presentational panel for similarity-threshold calibration results: the empirically calibrated threshold shown side-by-side with the model's preset default (or an explicit no-preset state), calibration metadata (percentile, sample size, model ID, distance function), the pairwise similarity-distribution statistics (mean / median / std-dev / min / max / pair count), and a reference list of known-good preset thresholds with the active model highlighted. Loading and empty states carry optional calibrate / cancel affordances. Designed from the ThresholdCalibration result shape; the full-fidelity standalone complement to evaluation-metrics-dashboard's embedded calibration sub-view. Driven by useCalibrateThreshold (pair presetThreshold with getDefaultThreshold and presets with MODEL_THRESHOLD_PRESETS). All in-component SVG-free token styling — no chart library.
Calibrate a similarity threshold from corpus embeddings via useCalibrateThreshold at percentile 90, over a selected embedding model and corpus, rendering the calibrated threshold versus the model's getDefaultThreshold preset, metadata, distribution statistics, and the MODEL_THRESHOLD_PRESETS reference with the selected model highlighted. The provider-prefixed model id is normalized so the panel, preset highlight, and presets reference align. The model downloads only behind Calibrate. No model bytes download until an explicit in-block action.
A single tool invocation card with a status taxonomy (pending/running/streaming/completed/error), expandable ToolInput/ToolOutput, a per-tool renderer registry with a Fallback for unregistered tools, and a ToolGroup that collapses consecutive calls behind a stacked-icon summary. Data source: useAgent / wllama/transformers tool calling.
A human-in-the-loop confirmation card that gates a tool call before execution (pending tool + args with approve/reject), then re-renders read-only as an immutable receipt. Pairs with Tool and feeds the choice back into the agent loop. Data source: useAgent.
A hero card highlighting the single winning classification result — large label, prominent radial confidence dial (via ConfidenceScoreBadge), and a tier-tinted gradient-border glow. Designed to pair above a ScoredResultBarList; serves any single-winner output (sentiment, intent, language detection, gesture, zero-shot). Pairs with useClassifyZeroShot (top result).
A transcription list item pairing transcript text with inline <audio> playback — relative timestamp (hover -> absolute), transcribed body, and a hover-revealed delete — plus a transcribing… placeholder variant (WaveformActivityBars + label) that morphs into the populated card. The canonical useOperationList-backed STT list pattern; driven by useTranscribe.
Translate across 24 directed offline Opus-MT language pairs (English-centric, every model id verified) with swap-direction that carries the output into the input, per-panel character counts, copy-with-confirmation, and cancel. Resolves the Chrome Translator API when available (zero download) and automatically falls back to the pair's Opus-MT Transformers.js model behind an explicit download gate, with a truthful provider badge. No model bytes download until an explicit in-block action.
A React hook that owns a getUserMedia video stream: start() acquires (or re-acquires after a denial - the retry path), stop() releases every track, and unmount cleanup guarantees the camera light goes off. Runtime permission denial surfaces as a recoverable error (permission / hardware / unknown) rather than a thrown exception. Returns { stream, isActive, error, start, stop, clearError }; exports WebcamError / WebcamErrorKind. Imports only React and browser APIs - zero @localmode. Powers webcam-driven vision surfaces (object detection, live landmark tracking).
A lock-state-aware card for an encrypted note or text document: locked renders a masked body with disabled actions (no plaintext in the DOM); unlocked renders title/timestamp with reveal/hide toggling of caller-supplied decrypted content and a delete action, all via callbacks. Never receives ciphertext or key material. Pairs with useEncryptedVault.
Four-format vector import (Pinecone/ChromaDB/CSV/JSONL + native JSON) with auto format-detection, preview, batched cancellable import and a re-embed toggle for text-only rows; native JSON/CSV/JSONL export via vector-export-panel (native export round-trips); embedding-drift banner + cancellable reindex; and storage-quota + vector-storage observability + the device-adaptive batch size — all over its OWN corpus. CORE engine only. Split from ui/blocks/knowledge-base (Data tab; absorbs data-migrator).
An export surface for vector data — the counterpart to VectorImportFlow: a record/dimension count line, a row per export format (native JSON with vectors, CSV, JSONL — label, description, vectors-included / text-only indicator, per-format export action emitting onExport(formatId)), a busy state that disables all actions with a spinner on the active format, a zero-records disabled state, and an optional last-export banner (format, records, human-readable size, filename). Works with any backend; data source useImportExport (exportCSV, exportJSONL) plus a native JSON export.
A guarded vector-import flow for useImportExport: a preview panel (detected-format badge, total / with-vectors / text-only counts, detected dimensions, dimension-mismatch warning, Cancel/Confirm), a phased progress bar (parsing → validating → embedding → importing), a result stats banner (imported/skipped/re-embedded counts, source format, duration), and a record-preview table for row-level sanity checks before a destructive ingest. References the cross-family FormatDetectionBadge and inlines a minimal fallback so it builds independently. Data source useImportExport.
VectorDB observability complementing StorageMeter (quota): a compression-stats badge (SQ8 ratio + before/after size, e.g. "4.0x — 15KB→3.7KB"), a three-tier storage estimate (Raw Float32 / SQ8 4x / PQ 8–32x with the active tier highlighted), and a GPU-aware search-latency badge (accented when WebGPU-accelerated). Values derive from getCompressionStats() (a core function) + search timing, passed in as props; the nearest shipped hook is useStorageQuota.
A mirrored 16:9 webcam surface — a video element with a pixel-aligned transparent canvas overlay for landmark / skeleton drawing, an FPS badge, and a child slot. A shell for the MediaPipe streaming trackers (useDetectHands / useDetectPose / useDetectFace / useRecognizeGesture); the app supplies the stream and draw callback.
A press-to-record / release-to-transcribe push-to-talk button with an explicit visual state machine: idle -> recording (pulse rings + live waveform) -> processing (loader) -> success/error. Recording uses getUserMedia/MediaRecorder (useVoiceRecorder); transcription routes to local Whisper (useTranscribe). Controlled — the app advances the state.
A/B voice comparison — two labeled columns, each with a language-grouped voice select (VoicePicker) and a native <audio> player shown once audio is set, a shared comparison textarea, and a Compare button with a loading state. Wire onCompare to two useSynthesizeSpeech runs and pass the resulting Blobs back per column.
Browse, search, preview, and A/B-compare all 29 Kokoro voices (grouped by language label; play/stop preview where starting one preview stops the previous; sequential A→B synthesis over shared text with a cancel). Kokoro (~86MB) downloads only on the first preview or comparison. Fully on-device. Split from ui/blocks/audio-studio (Voices tab).
Record (push-to-talk from a selectable mic) or upload audio → Whisper/Moonshine transcription → saved notes with synced word-by-word replay (real Whisper segment timestamps; disabled with a hint for Moonshine), block-local semantic search over the notes (bge-small), a [No speech detected] fallback, cancel-in-flight, and delete-leaves-the-index. Owns its own speech-to-text model selector; every model downloads only behind an explicit action. Ships a justified block-local note index hook (use-note-index.ts — the VectorDB + indexed-id set that WAS a module-scoped singleton in audio-studio/models.ts, now block-local under the blocks carve-out). Fully on-device. Split from ui/blocks/audio-studio (Notes tab).
An animated Canvas 2D voice-agent orb/visualizer that reflects discrete agent states (idle/connecting/listening/thinking/speaking/muted) and pulses with input/output audio volume via getInputVolume()/getOutputVolume() callbacks, with color/glow variants. Visual state is fully decoupled from the audio source — feed volume from a local AnalyserNode. Driven by useLiveTranscribe / useTurnTaker.