Releases: bobgsning/FrameScout
Release list
FrameScout — Offline AI Search: v3.1.0 — Codebase Refactor, GPU Inference & Full Source Release
FrameScout — Offline AI Search: v3.1.0 — Codebase Refactor, GPU Inference & Full Source Release
Release date: 2026-09-23
This is primarily a maintenance and consolidation release, but it also ships two real improvements: GPU-accelerated embeddings (via DirectML) and video frame indexing (previously broken). It does not change the AI models or search quality, but it substantially cleans up the codebase, fixes a long list of latent bugs, refactors the Tauri/Rust entry structure, and — importantly — publishes the complete project source tree to the repository.
✨ What's New
- ⚡ GPU-Accelerated Embeddings (DirectML) — The Python worker now runs on
onnxruntime-directml. SigLIP 2 embedding inference is executed on the GPU via the DirectML execution provider on Windows, delivering a substantial speedup over the previous CPU path (most noticeable for video frame extraction and bulk image encoding). This works across NVIDIA / AMD / Intel GPUs with zero CUDA or driver-version juggling. (EasyOCR text recognition still runs on CPU — only the embedding step is GPU-accelerated.) - 🎬 Video Frame Indexing (previously broken) —
_handle_batchnow detects video files and extracts frames viaextract_video_frames; images still go throughload_image_pil. Each path yields multiple timestampedFrameResultentries, so videos finally enter the index instead of being silently dropped. - 🗄️ Multi-Frame Data Model — The
frame_vectorstable primary key changed frompathto(path, timestamp). Old single-frame databases are migrated automatically inside a transactional block (rename → create → copy → drop, with rollback on any failure). - 📦 Complete Source Tree Published — The full Rust, Vue, and Python source — including the
model_codemodule, all build configs (Cargo.toml,ai_worker.spec), docs (BUILD.md,READMEs), and the bundledprotoc.exe— is now committed. This is a true full-source Community Edition. - 🔀 Smart Folder Result Consistency —
applySmartFoldernow reusesnormalizeResults, so smart-folder results behave identically to manual search (videos get a 25s load timeout with "File Unavailable" fallback; low-confidence images auto-collapse). Applying a folder from "Show All" mode no longer leaves the pagination bar stuck.
🐛 Bug Fixes
- "Show All" mode exited on page turn — While in "Show All" (full-file preview) mode, turning pages previously triggered a background re-search/refresh that reset the view back to paginated browsing, kicking you out of Show All. The view mode is now preserved across page turns.
- Worker crash on startup with missing models —
main.pynow catchesFileNotFoundErrorand prints a cleanFATALmessage then exits, instead of dumping a raw traceback. - Latent
UnboundLocalErrorin the worker loop —task_idis now initialized at the top of the request loop, fixing a crash when an exception occurred duringrecv()/ParseFromString()(wherereqwas never assigned). - OCR config never honored — The long-dormant
single_file_ocr_configproto field (field 6) is now actually read; when set it drives per-fileenable_ocr/languages, otherwise behavior is unchanged (always OCR, defaulten). - Stale data & inconsistent dedup — Search dedup was verified to preserve each file's highest-scoring frame and its
timestamp(used for instant seek); clarifying comments added.index_cmd.rsnow refreshesvector_jsononON CONFLICT(path, timestamp)to avoid mixing a first-frame vector with a last-frame OCR text. - HTML injection in results —
escapeHtmlnow escapes&,",'in addition to</>, preventing path text from breaking thev-htmlrendering. - HMR event-loss — Four Vue composables (
useSearch,useEngineStatus,useLicense,useScanner) now resetlifecycleBoundinonUnmounted, so engine-status / scan-progress / key listeners re-bind correctly after hot reload. - Redundant license refresh — Removed a duplicate
emit('refresh-license')+checkLicense()inLicenseModaland the corresponding binding inApp.vue.
🔧 Under the Hood
- Tauri entry refactor —
lib.rsnow owns all 7 module declarations and the TauriBuilder(run()carries#[cfg_attr(mobile, tauri::mobile_entry_point)], Apache header preserved);main.rsis a 4-line shell callingframescout_ui_lib::run(). - Dependency & metadata cleanup — Removed unused
tauri-plugin-opener(no frontend calls, no capability);Cargo.tomlversion3.0.0 → 3.1.0(aligned withtauri.conf.json);keywordstrimmed to the crates.io 5-item limit. - Zero-warning builds — Fixed several
cfg-gated dead-code/unused-import warnings (guard.rs,verifier.rs,index_cmd.rs,storage/mod.rs); merged the duplicatePaginatedResultstruct intoPagedResponse; removed a deprecated_stateparam fromping_engine. - Python worker hygiene — Replaced
__import__("PIL")hacks with a properfrom PIL import Image; removed an unusedEMBEDDING_DIMimport; cleaned leftover comments and a duplicate docstring invideo_extractor.py; added acap.isOpened()guard. - Packaging robustness —
ai_worker.specno longer hardcodes an absolute.venvpath (now resolved relative toSPECPATH), so the build works after moving the venv or the repo.requirements.txtis now pinned to a single ONNX Runtime package (onnxruntime-directml) — the CPUonnxruntimeand DirectML packages both provide theonnxruntimemodule and overwrite each other, so they must never be co-installed. The DirectML build also bundlesDirectML.dllfor the GPU path. - Type safety / IDE — Added
pyrightconfig.json(correct filename for basedpyright) plus a hand-writtensearch_pb2.pyistub and type annotations acrossserver.py/config.py/engines/video_extractor.py, bringing the wholeinference-workerto 0 errors / 0 warnings under basedpyright. - Frame-extraction guards — Added
MAX_FRAMES_PER_VIDEOandMAX_FRAMES_PER_ENCODING_BATCH(config + constants) so long videos are bounded in time/memory and large batches don't overflow GPU memory; batching also isolates a single-file failure from the rest of the batch. - Extension whitelist single-source —
IMAGE_EXTENSIONS/VIDEO_EXTENSIONSnow live in Rustconstants.rsand Pythonvideo_extractor.pywith a cross-language "keep in sync" note;scan_folderuses the constant instead of inline literals.
📋 Upgrade Notes
- No model re-download required — SigLIP 2 ONNX models are unchanged since v3.0.1; existing
models/remain valid. - Existing databases auto-migrate — Single-frame
frame_vectorstables are upgraded to the composite(path, timestamp)key on first launch; your previously indexed images are preserved. (Videos were never stored before, so there is no legacy video data to migrate.) - If you build from source: re-run
pyinstallerperBUILD.mdwithonnxruntime-directmlactive (soDirectML.dllis bundled), then copy the completedist/ai_worker(including its_internal/folder) intosrc-tauri/bin/ai_worker— the onedir layout requires_internal/python312.dllto be present.
🙏 Tech Stack
Google SigLIP 2 · ONNX Runtime (DirectML / GPU) · EasyOCR (CPU) · Tauri · ZeroMQ · Protobuf · Rust + Vue 3
Full Changelog: v3.0.3...v3.1.0
The main Tauri application executable stays lightweight (~5 MB); the Python AI worker is bundled as a separate sidecar. Embedding inference now runs on your GPU via DirectML — noticeably faster than before — while OCR remains on CPU.
FrameScout — Offline AI Search: v3.0.3 — Backend-Persistent Smart Folders, On-Demand OCR & Storage Cleanup
FrameScout — Offline AI Search: v3.0.3 — Backend-Persistent Smart Folders, On-Demand OCR & Storage Cleanup
Release date: 2026-08-10
This release brings three major improvements: fully backend-driven Smart Folders, on-demand OCR for selected files with custom languages, and complete removal of browser-local storage dependencies. Smart Folders are now truly persistent — surviving database backups, app reinstalls, and cross-machine transfers. OCR can be triggered independently on any indexed file with language-specific settings. Plus, we've fixed the misleading (0) badge on vector-only folders and cleaned up legacy localStorage remnants.
✨ What's New
📁 Backend-Driven Smart Folders
- Smart Folder definitions are stored exclusively in SQLite (
smart_folderstable). - New backend command
execute_smart_folderperforms the search natively using the same engine as manual queries. - Frontend no longer caches any folder rules — no more lost folders after clearing browser data.
- Each folder displays a live
match_countbadge. Pure vector folders show?instead of0for honest indication.
🔍 On-Demand OCR for Selected Files
- Run OCR on specific files with custom language codes (e.g.,
en,ch_sim,ja). - The
run_ocr_for_selected_filescommand updates both SQLite and in-memory metadata instantly. - A dedicated OCR button appears on each search result card; click it to trigger OCR with your preferred language.
- Language configuration is now fully separated from the scan/index process — you can index first, OCR later.
🧹 Complete Removal of Browser Storage
- The
savePathfunction and its associatedlocalStorage.setItemcalls have been deleted. - On startup, any remaining
framescout_smart_foldersorframescout_folder_pathkeys are cleared. - The folder path input no longer persists across sessions (future versions may add backend-based preference storage).
🐛 Bug Fixes
- Smart Folder count showing
0even when matching files exist (vector-only folders now display?). - Runtime error caused by calling a commented-out
savePathfunction. - Potential duplication of Smart Folders due to old localStorage data merging with backend data.
- OCR results not reflected in in-memory metadata after on-demand update.
🔧 Under the Hood
get_smart_foldersnow computesmatch_countby scanning in-memory metadata for text matches.SmartFolderstruct extended withmatch_count: usize.- Frontend
applySmartFolderdelegates entirely toexecute_smart_folder. - Template updated to conditionally render
?for pure vector folders. run_ocr_for_selected_filesnow properly updates both SQLite andFlatVectorMatrixmetadata.- Scan/index commands accept explicit
enable_ocrandocr_languagesparameters.
📋 Upgrade Notes
- No model re-download required — SigLIP 2 models from v3.0.1 remain unchanged.
- Existing Smart Folders in the database are automatically compatible; no migration needed.
- If you previously relied on
localStoragefor folder path memory, you'll need to re-enter the path after upgrading (we recommend using the Browse button). - On-demand OCR uses the same EasyOCR models already present in
models/easyocr/.
🙏 Tech Stack
Google SigLIP 2 · ONNX Runtime · EasyOCR · Tauri · ZeroMQ · Protobuf · Rust + Vue 3
Full Changelog: v3.0.2...v3.0.3
The packaged exe is only about 5 MB.
FrameScout — Offline AI Search: v3.0.2 — Stable Browsing, Index-Time Ordering & “Show All” Mode
FrameScout — Offline AI Search: v3.0.2 — Stable Browsing, Index-Time Ordering & “Show All” Mode
This release focuses on predictability and stability. It introduces index-time ordering so newly scanned files always appear first, a “Show All” mode for viewing every file at once, and numerous defensive fixes against unexpected UI changes.
✨ What’s New
-
📋 “Show All” Mode
Click the “📋 Show All” button in the pagination bar (or the search toolbar) to load every indexed file in one flat list. A hint bar shows the total count; click “📄 Paginated View” to return to paginated browsing. Works seamlessly with the incoming-file banner and ghost cleaning. -
⏱️ Index-Time Sorting
Each indexed file now carries a preciseindex_time(Unix timestamp). The browse-mode listing (list_all_files) sorts byindex_time DESC, so newly added files always appear at the top. No more confusing order after scanning.
🛡️ Stability Improvements
- Request debouncing in
performSearch: only the latest search/ page-turn takes effect – no more flickering from stale responses. clean_ghostsreturns detailed info: frontend accurately removes ghost paths from the current view and reloads appropriately.acceptIncomingFilesbehaves intuitively: clicking the banner now enters browse mode (first page) or refreshes “Show All” mode – never disrupts your current context.- Page boundary protection for
changePageanddoJump. clearImageSearchsafety guard: does nothing unless actually in image-search mode.toggleClusteringfixed: exiting clustering now correctly restores the previous result set.
🔧 Under the Hood
AppState.memory_dbupgraded toRwLock– concurrent searches don’t block each other.request_vectorcreates a fresh ZMQ socket per call – eliminates shared-socket race conditions.- New backend command
get_all_files– returns all records in one go, used by “Show All”. - Database migration:
frame_vectorsgainsindex_time REALcolumn (auto‑migrated on startup).
📋 Upgrade Notes
- No model re‑download required – SigLIP 2 models from v3.0.1 remain unchanged.
- Existing records get
index_time = 0.0after migration. To give them proper timestamps, simply re‑scan your folders. They will then sort correctly. - Recommended: run a full scan after upgrading to enjoy the best browsing experience.
🙏 Tech Stack
Google SigLIP 2 · ONNX Runtime · EasyOCR · Tauri · ZeroMQ · Protobuf · Rust + Vue 3
Full Changelog: v3.0.1...v3.0.2
The packaged exe is only about 5 MB.
FrameScout — Offline AI Search: v3.0.1 & ONNX + SigLIP 2 Upgrade
FrameScout v3.0.1 — ONNX + SigLIP 2 Upgrade
Release date: 2026-08-07
This release brings a major AI inference engine overhaul and several UX improvements. FrameScout now runs on ONNX Runtime with Google SigLIP 2 (768‑dimension embeddings), delivering better semantic understanding, broader GPU support, and faster inference.
✨ What's New
- 🧠 SigLIP 2 Embeddings — Upgraded from OpenAI CLIP (512D) to Google SigLIP 2 (768D). More accurate semantic matching, especially for non-English queries and fine-grained concepts.
- ⚡ ONNX Runtime — Replaced PyTorch with ONNX Runtime for inference. Automatic hardware acceleration detection:
- DirectML (AMD / NVIDIA / Intel GPUs on Windows)
- CUDA (NVIDIA GPU)
- CPU (fallback)
- Expect 15–30% faster batch inference compared to PyTorch.
- 🔽 Low-Score Collapsible Cards — Low-confidence results are now collapsed by default. Click the red prompt bar to expand details, and use the "▲ Collapse" button to hide them again. Cleaner search results.
- 📦 Fully Offline OCR — EasyOCR model storage is now fixed to
models/easyocr/. No unexpected network requests after initial download.
🔧 Improvements
- Model download script updated to fetch SigLIP 2 ONNX models (run
python scripts/download_models.pyagain). - Logging redirected to
%TEMP%\FrameScout_Global\for easier debugging. - Improved error handling for video frame extraction with NaN FPS values.
- Better tag display logic for low-confidence results.
🐛 Bug Fixes
- Fixed crash when processing video files with corrupted or unknown FPS metadata.
- Fixed conflicting display between low-score tags and semantic tags.
- Implemented polling loop with PING_ENGINE until engine responds.
- Fixed ZMQ REQ state machine by creating fresh socket per attempt.
- Moved timeout panic out of app.run to ensure early abort.
- Removed unused outer socket variable.
- Main socket now created only after engine is confirmed ready.
🗑️ Removed
- Runtime dependency on PyTorch (still available in
requirements.txtfor development).
📋 Upgrade Notes
⚠️ Model re-download required.
Due to the switch from CLIP to SigLIP 2, you must re-runpython scripts/download_models.pyto obtain the new ONNX models. Old CLIP models inmodels/openai-clip/are no longer used and can be deleted.
🚀 Quick Start (for new users)
git clone https://github.com/bobgsning/FrameScout.git
cd FrameScout
# Follow instructions in README.md🙏 Acknowledgments
Built with Google SigLIP 2, ONNX Runtime, EasyOCR, Tauri, ZeroMQ, and the Rust ecosystem.
Full Changelog: v3.0.0...v3.0.1
Did you notice? The packaged exe is only about 4 MB.
FrameScout v3.0.0 Community Edition
FrameScout v3.0.0 Community Edition
The first public release of FrameScout — a fully-offline, privacy-first, multi-modal desktop search engine.
✨ Features
- 🔒 100% Offline — No internet required. Your data never leaves your computer.
- 💡 Semantic Search (CLIP) — Search by meaning, not just filenames.
- 🖼️ Image-to-Image Search — Find visually similar images.
- 🔍 OCR Text Search — Extracts and indexes text from images.
- 🎬 Video Frame Indexing — Automatically extracts key frames from videos.
- 🧩 Visual Clustering — Discover groups of similar images.
- 📁 Smart Folders — Save any search as a dynamic folder.
- 📝 Personal Notes — Attach markdown notes to any image.
🔧 Technical Highlights
- Three-process architecture: Vue 3 frontend + Rust/Tauri core + Python inference worker
- Hybrid scoring: vector similarity + OCR + note + filename
- FlatVector matrix: Fast brute-force search for up to 50K images
- ZeroMQ + Protobuf: Microsecond-latency IPC
📋 System Requirements
- Windows 10/11
- Rust 1.75+, Python 3.10+, Node.js 18+
🚀 Quick Start
git clone https://github.com/bobgsning/FrameScout.git
cd FrameScout
# Follow the instructions in README.md📝 Notes
This is the Community Edition with full source code. See README.md for build instructions.
🙏 Acknowledgments
Built with OpenAI CLIP, EasyOCR, Tauri, ZeroMQ, and the Rust ecosystem.
Full Changelog: https://github.com/bobgsning/FrameScout/commits/v3.0.0