Local-first, offline AI UI primitives + blocks - run ML models (chat, RAG, vision, audio) entirely in the browser. No servers, no API keys.
Newest-first devtools event log: relative timestamps (absolute on hover), namespace-colored type badges (vectordb/embedding/model/queue/pipeline/storage), serialized payloads, a case-insensitive substring type filter, a visible cap (default 100) with an overflow line, distinct no-events and no-match empty states, and an optional Clear affordance. Recommended data source: useDevToolsEvents from @localmode/devtools/react.
A generic, format-agnostic drag-and-drop + click-to-browse upload zone for non-image files (PDF/CSV/JSON/vector exports). Validates each file with a bundled validateFile helper (copy-owned — no @localmode dependency) against an accept MIME list and maxSize, emitting only valid files via onUpload; rejected files go to onReject. Disabled/processing overlay blocks input. Distinct from media-vision's MediaDropzone (no image-preview semantics).
A small badge displaying an auto-detected data format (PINECONE / CHROMA / CSV / JSONL or custom) with a per-format color map, used to confirm a detected source format after parsing. Fully self-contained and presentational — pass a format string and an optional colorMap; unknown formats fall back to neutral and a nullish format shows a pending state. Pairs with useImportExport (parseResult.format); also consumed by the local-first VectorImportFlow as a registry dependency.
Browse 160,000+ HuggingFace GGUF models and the curated wllama catalog, inspect any file's metadata via a ~4KB HTTP Range read (checkGGUFBrowserCompatFromURL — never a model download), get a browser-compat verdict, and hand a model off to the chat block. Consumes the PROMOTED @localmode/wllama model-discovery utils (searchGGUFModels / listGGUFFiles / HFApiError) instead of a block-local hf-api.ts; keeps a justified block-local chat-handoff emitter (handoff.ts). Cursor pagination, typed search errors + retry, and an explicit Download-to-cache prefetch. No model bytes on load. Split from ui/blocks/device-model-lab (GGUF explorer section).
Generate alt-text captions for images with ViT-GPT2 (Xenova/vit-gpt2-image-captioning, ~230MB) entirely on-device, accumulating results in a gallery (caption as the card label, native per-card delete) with copy-caption-to-clipboard + transient copied feedback, remove-single, Clear All, a captioned-count indicator, and a compact add-another dropzone once results exist. Validates JPEG/PNG/WebP/GIF up to 10MB; the model loads lazily on the first dropped image. Consumes none of the promoted image ops. Split out of the tabbed image-studio Caption tool (split-image-privacy).
Upscale and restore photos with Swin2SR super-resolution running fully in the browser — a 2x lightweight default (Xenova/swin2SR-lightweight-x2-64), plus 4x classical (Xenova/swin2SR-classical-sr-x4-64) and a real-world Restore variant (Xenova/swin2SR-realworld-sr-x4-64-bsrgan-psnr), each behind its own lazily-loaded model with persistent per-mode results. Presents the result in an Original/Enhanced toggle with a model/scale/status info panel and an Enhanced Nx badge; Download Enhanced PNG (promoted imageResultToDataUrl/getImageDimensions/downloadDataUrl), upload-new, cancel with a first-run hint, and dismissible validation + inference errors. Nothing downloads until you drop an image. Split out of the tabbed image-studio Enhance tool (split-image-privacy).
A full-bleed overlay over a dimmed source image while vision inference runs — spinner ring + icon + status + optional cancel, plus an animated scan variant (keyframes shipped inline). Renders nothing when idle. Driven by any vision hook's isLoading.
A responsive grid / list of image result cards sharing one data contract — in-flight overlay, hover metadata, confidence score, multi-select, delete, and staggered fade-in. Composes ConfidenceScoreBadge (Results family) via a registry dependency, with a minimal score-badge fallback inlined so it builds independently. Pairs with useClassifyImageZeroShot / useEmbedImage / useCaptionImage.
Text→image AND image→image search over one shared CLIP vector space — embed a free-text query or a reference image and rank the ingested photo library with a top-K slider (default 20), a visible min-similarity threshold (getDefaultThreshold ?? 0.2), and CLIP-scale score bars. Own usePhotoLibrary instance + its own media-dropzone ingest. Split from ui/blocks/photo-search (Search tab; absorbs cross-modal-search + product-search).
A card for a single locally-indexed document: truncated filename (native tooltip), chunk count, optional page count and file size, and a hover/focus-revealed delete with loading state. Presentational — page/chunk counts come from the app's ingest state (e.g. useSemanticChunk output length), not a single hook.
Per-queue inference observability: one card per registered queue showing pending, active, completed, failed, and average latency, with a live pulsing badge + emerald accent on active counts, amber on pending, and destructive on failures. Empty state directs users to registerQueue(). Recommended data source: useDevToolsQueueStats from @localmode/devtools/react — the hook snapshot spreads straight into the queues prop.
Inline superscript citation markers in prose that open a hovercard with the cited local chunk (title, excerpt, quoted snippet), with a carousel paging multiple sources for one claim. References locally-stored chunks only — no remote unfurl. Data source: useSemanticSearch.
An accessible per-message error/retry block rendered inline on a failed assistant message (not a global toast), with auto-extracted error text, a classified hint (OOM / WebGPU lost / model load), and a retry action. Data source: useChat error state.
Debounced (400 ms) automatic language detection across 110 languages (up to five candidates with name + ISO code + confidence) that runs once typed text reaches 10 characters with no button press, plus a two-text cosine-similarity comparison via the on-device MediaPipe text embedder. Fully on-device; models download only when typing crosses the auto-detect threshold or Compare is pressed. Regrouped from ui/blocks/vision-lab (Language tab) into a new standalone text category (roadmap D2 — NOT merged into text-insights).
A paired source/target language picker — From/To pill toggles with flag + name + a swap button, or a compact {source} → {target} pair of selects. Fully controlled via sourceCode/targetCode and onSelectSource/onSelectTarget/onSwap. Feeds useTranslate; composes with useDetectLanguage for auto-detect source.
Real-time MediaPipe streaming trackers on live webcam video — one 4-mode block: Hands (21-point skeleton + handedness), Pose (33-point skeleton + person count), Face (478-point mesh + top-8 expression blendshapes behind a default-on toggle), and Gestures (recognized category with a human-readable label). Live FPS; exactly one tracker/WASM task runs at a time. Ships a justified block-local hot-path canvas util (draw-landmarks.ts — single consumer, imports only @localmode/core topology constants under the blocks carve-out). Fully on-device. Split from ui/blocks/vision-lab (Track tab).
Open-mic streaming speech-to-text (useLiveTranscribe) with VAD-segmented utterances, plus a listen→plan→speak turn-taking assistant (useTurnTaker: Granite 4.0 350M plans, Kokoro speaks) selectable via a two-mode picker. VAD choice: the zero-download energy VAD (default) or a gated ~2MB Silero ONNX VAD. Stop calls dispose() so the microphone MediaStream is released; barge-in + interrupt supported. Owns its own STT selector, its own adapter-backed inference-device probe for the Granite planner, and holds the Silero provider block-local (the module-scoped Silero singleton in audio-studio/models.ts is eliminated). Fully on-device. Split from ui/blocks/audio-studio (Live tab).
A small family of busy indicators (dots / pulse / typing / spinner) plus a Shimmer skeleton-text variant, shown while a local model warms up or streams its first token.
A compact session-lock indicator accepting a status of locked, unlocked, or no-vault, with distinct iconography per state and an accessible text label (never color alone). Purely presentational — holds no key material. Pairs with the status field of useEncryptedVault.
A fill-mask / cloze textarea that detects a configurable mask token (default [MASK]), shows an inline highlighted preview of the mask span, a 'detected' vs 'Add [MASK]' validation hint, a randomize/sample button, and a Cmd+Enter submit badge. Presentational — feeds useFillMask.
A drag-and-drop + click-to-browse image upload zone with idle / drag-over / processing states, accept-list + max-size validation via validateFile, an "add another" variant, and an onFiles(File[]) callback.
Audio upload OR pasted transcript → Transcribe → Summarize (DistilBART, maxLength 200 / minLength 60) → Extract action items (useGenerateObject on Granite 4.0 350M) with a visible three-step indicator, a cancel that preserves completed steps, action-item priority badges + completion toggles with a live X/Y count, a [No speech detected] short-circuit, and a structured dated .txt export. Owns its own STT selector (Whisper Tiny EN default + Moonshine-Base recommendation hint) and its own adapter-backed inference-device probe for the Granite LM. Fully on-device. Split from ui/blocks/audio-studio (Meeting tab).
Role-aware chat message (data-role) rendering string or ContentPart[] — markdown text, image thumbnails with a fullscreen dialog, and file download chips from local bytes — with contained/flat variants and an inter-message Checkpoint savepoint marker. Matches @localmode/react's message model.
A microphone input-device picker with permission handling and live device enumeration — fully offline, using only browser device APIs (getUserMedia for the permission prompt, enumerateDevices for the list, a devicechange listener to stay current). Emits the chosen deviceId for a getUserMedia constraint; pairs with VoiceButton / VoiceOrb / useLiveTranscribe.
A React error boundary that isolates a render failure in its subtree: it catches the error, renders a compact recoverable role=alert notice with the message and a Reset button that clears the error and re-renders the children, so one failing surface cannot blank the whole page. A structural copy-owned utility with local prop shapes.
Ranked on-device model recommendations that compute their OWN device context via useCapabilities and rank useModelRecommendations / getModelRegistry over the in-memory registry with ZERO network: a 21-task grouped selector, ranked model-recommendation-card results with a device-context line + result-count + empty states, two-model comparison via model-comparison-panel (max 2, third replaces the older), and a collapsible custom-model registration form (11 ModelRegistryEntry fields, per-field validation, in-memory notice, registerModel() + refresh). No model download. Split from ui/blocks/device-model-lab (model advisor section).
Cached-model observability table: model ID (monospace, truncated), status badge (loaded/loading/error), load duration, and relative last-used time per model — with a human-formatted size column only when entries carry sizeBytes and a per-row evict control only when onEvict is provided. Recommended producer: useDevToolsModelCache from @localmode/devtools/react.
A rich tile for a single model catalog entry (wllama/webllm/transformers/litert/mediapipe shapes): name, a size badge, description, a metadata chip row (architecture, params, quantization, context), and a conditional capability sub-row (tools/vision/embedding/reranking/reasoning). Fires onClick(id) for selection with a selected ring. Complements (does not replace) ModelSelector; data source useModelRecommendations / model registry.
A side-by-side comparison of two scored entries with labeled rows (Score, Size, Speed, Quality, Device, Dimensions) where winning rows are accent-highlighted and losing rows dimmed, plus an onClear dismissal. Win-highlighting is derived purely from props (no orchestration state). Data source useModelRecommendations.
The headline local-first card a user sees while a model loads on-device: model name, size, context length, category, a live progress bar, and a clear first-time-downloading vs loading-from-cache distinction (with a ready state). Includes a lower-level DownloadProgress (bar + percentage from a 0–1 fraction or {loaded,total,percent,cached}). Presentational — bind progress to useModelLoader/useModelStatus; it does not own the download. Lifted out of a chat empty-state into a reusable primitive.
Evaluate a selected classifier over a selected labeled dataset via useEvaluateModel, reporting accuracy plus macro precision/recall/F1, run duration, and a color-coded confusion matrix, with completed/total progress and cancel, JSON export, and clear-results. Keeps one justified local file (datasets.ts) holding the labeled evaluation datasets and the radio-card selector, too large to inline without harming readability (design D5). No model bytes download until an explicit in-block action.
A full-height "waiting for model" splash — the richer blocking sibling of ModelDownloader — combining model metadata (size, context length, category, cached-vs-downloading badge) with a progress bar and a two-path help message (first-download vs cache-load). Composes the lower-level DownloadProgress; binds to useModelLoader/useModelStatus.
A structured key-value grid of parsed model metadata (GGUFMetadataCard, with a ModelMetadataCard alias) — architecture, parameter count, quantization, context length, embedding dimension, vocab size, head/layer counts, file size, optional author/license — driven by a field-descriptor array that skips absent fields. The GGUF shape originates from @localmode/wllama; the display is a generic metadata grid. Data source useModelStatus / model-loading metadata.
A single scored recommendation: a radial score dial (0–100), the model name, a monospace model id, a badge row (provider, size, speed/quality tiers, recommended device webgpu/wasm/cpu with a stable tier→color mapping), a description, and reason chips. Supports an optional onToggleCompare selection affordance. Data source useModelRecommendations.
A cmdk-based searchable model-repo browser: a controlled search input, a sort selector (downloads/likes/last-modified), result rows (repo id, author, compact download/like counts, relative last-modified, capped tag badges), load-more pagination, and a per-repo expandable file list (filename, quantization badge, human-readable size) with per-file select actions — plus loading, empty, and error-with-retry states. Purely presentational: every value arrives via props and every action leaves via a callback, so any backend can feed it (recommended wiring: the HuggingFace Hub API; a private registry or static fixtures work identically).
A device-aware model picker: a list grouped by category, backend filter chips (WebGPU/ONNX/WASM/LiteRT) with live counts, per-model vision/tool-calling/cached badges, a download affordance for uncached models, and a delete-from-cache affordance for cached ones. Device-unfit models (e.g. a WebGPU-only model on a non-WebGPU device) are de-emphasized and labeled. Emits onSelect(modelId) and owns no selection state. Bind models to useModelRecommendations and hasWebGPU to useCapabilities.
Progress surfaces for local workflows: a horizontal numbered-step indicator (active/completed/pending), a stage+percentage variant for ingest, a Steps/Plan vertical outline with expandable detail, and an inference-queue surface grouped by priority. Maps to usePipeline onProgress and useInferenceQueue.
A reactive online/offline indicator (NetworkBadge) sourced from useNetworkStatus, plus an OfflineReady badge that signals the app's required model is cached on-device and can run with no network. Because local models keep working offline, offline is informational, not an error.
One-shot DETR (Xenova/detr-resnet-50) object detection on an uploaded image, the bundled sample, or a webcam-captured still — color-coded bounding boxes, a unique-label legend, an N-found count, a ranked scored list, in-flight download progress with cancel, clear-to-reset, and dismiss+retry — plus a live MediaPipe BlazeFace webcam face loop with a numeric face count and captured-still overlay. Fully on-device; models download only behind explicit actions. Split from ui/blocks/vision-lab (Detect tab).
An inline multi-choice selection list (shows 5–7 options then paginates) for human-in-the-loop agent inquiries, distinct from quick-reply suggestion chips. The chosen option feeds back into a local agent inquiry loop. Presentational — feeds useAgent.
An inline range slider with a live value readout for reversible adjustment of a local generation parameter — temperature, top-k, top-p, maxTokens, nGpuLayers, KV-cache quant. Fully controlled; the emitted value feeds straight into useGenerateText/useChat options. Built on the shadcn/ui Slider primitive.
A controlled passphrase screen with create and unlock modes: create renders passphrase + confirmation with a minimum-length gate and composes the password-strength-bar from caller-computed strength props; unlock renders a single field with an error surface (e.g. wrong passphrase) and busy state. Submits the passphrase via onSubmit; performs no crypto and retains no passphrase. Pairs with useEncryptedVault.
A presentational password/passphrase strength meter — a themed bar + label driven by a caller-computed 0–100 strength score. The app computes strength (pairs with @localmode/core deriveKey/crypto); the component only renders. No turnkey hook.
Editable-label-set categorization with Photo/Product presets, on-device library re-categorization with progress + cancel (no re-embedding), and a counted, single-select category-facet-list filter over the ingested photos. Own usePhotoLibrary instance + its own media-dropzone ingest (photos are zero-shot categorized as they embed). Split from ui/blocks/photo-search (Categories tab).
Detect PII with on-device NER (Xenova/bert-base-NER, BIO prefixes stripped, low-confidence filtered), redact it with reverse-offset [<TYPE>] placeholders honoring per-type toggles plus a core redactPII() regex pass (emails/phones/SSNs/cards), render entity insights (stats bar + relationship graph), copy/export the redacted text, and demonstrate differential privacy over the redacted text's embedding (Xenova/all-MiniLM-L6-v2, ~23MB) via dpEmbeddingMiddleware + a createPrivacyBudget tracker with a DP-applied provenance badge. Models download only behind the explicit Scan action. Ships a block-local redaction.ts (pure entity-mapping/redaction/graph helpers) alongside the component — justified as >130 lines of block-specific logic, too large to inline. Split out of the tabbed privacy-vault Redact tab (split-image-privacy).
Per-run pipeline observability cards: status badge (running pulses on primary, completed emerald, failed destructive), a completed/total progress bar, the current step while running, total duration on completion, and optional expandable per-step timing rows. The runs record mirrors the @localmode/devtools PipelineSnapshot shape, so useDevToolsPipelineRuns() output feeds it directly; works with any backend.
A one-click 'enhance my prompt' control that hands the user's draft to a local model (via an onEnhance callback wired to useGenerateText) and applies the rewritten prompt — fully offline — with an optional few-shot example editor for interactive prompt tuning. Presentational + callback-driven.
Form-based, auto-resizing chat composer: Enter submits, Shift+Enter inserts a newline, the submit control swaps to a stop control while streaming, with optional controlled value/onValueChange, a PromptInputProvider, a voice/dictation mic toggle (wire to local Whisper), and a slash-command / + picker.