Skip to content

feat(local-models): expand catalog with Hugging Face fallback and opt-in scanning - #1804

Merged
AnishSarkar22 merged 21 commits into
MODSetter:devfrom
AnishSarkar22:feat/local-model-catalog
Sep 17, 2026
Merged

AnishSarkar22 merged 21 commits into
MODSetter:devfrom
AnishSarkar22:feat/local-model-catalog

Conversation

@AnishSarkar22

@AnishSarkar22 AnishSarkar22 commented Sep 17, 2026

Copy link
Copy Markdown
Collaborator

Description

  • Expand available models via hf.co/<repo>[:<quant>] fallback pulls when Ollama's registry lacks a model — ~91 → 1,400+ usable models.
  • Opt-in hardware scanning: persistent fingerprinted cache skips rescans; curated + installed models show instantly, "Scan hardware" is explicit.
  • Split catalog into curated (staff picks, always visible) and explore (scan-derived, ranked by fit).
  • Fix quant trust: only tag pulls with best_quant when scored against llama_cpp; untrusted quants get an untagged pull + downgraded "Marginal" fit.
  • Fix :latest mismatch: untagged fallback pulls now request :latest explicitly, matching what Ollama actually stores — fixes broken install verification and "already installed" detection.
  • Fix display names: clean provider/repo name shown consistently (Chat summary, model picker, catalog list, Installed) before and after scanning.
  • UI fixes: search + reserved-height scroll fix for "More models", long-name truncation, Models dialog clipping.
  • Tests: new coverage for the fallback/quant logic, scan cache, curated manifest, and display-name consistency — full suite passing (427 backend tests).

Motivation and Context

FIX #

Screenshots

API Changes

  • This PR includes API changes

Change Type

  • Bug fix
  • New feature
  • Performance improvement
  • Refactoring
  • Documentation
  • Dependency/Build system
  • Breaking change
  • Other (specify):

Testing Performed

  • Tested locally
  • Manual/QA verification

Checklist

  • Follows project coding standards and conventions
  • Documentation updated as needed
  • Dependencies updated as needed
  • No lint/build errors or new warnings
  • All relevant tests are passing

High-level PR Summary

This PR expands the local model catalog by enabling SurfSense to offer models from Hugging Face GGUF repositories that aren't in Ollama's native registry, increasing available models from ~91 to over 1,400. It introduces a fallback mechanism where llmfit scan results with gguf_sources but no ollama_name are automatically mapped to hf.co/<repo> pull targets that Ollama natively supports. The implementation adds persistent, fingerprinted caching of llmfit scan results to avoid expensive rescans, restructures the catalog API to distinguish curated (staff picks, always visible) from explore (scan-derived, ranked by fit), and adds a scanned flag so the UI can show curated models and a "Scan hardware" prompt immediately without blocking on hardware detection. GPU verification on Windows confirmed that llmfit correctly scores these GGUF models with trustworthy quantization tags on non-Mac platforms, validating the approach.

⏱️ Estimated Review Time: 30-90 minutes

💡 Review Order Suggestion
Order File Path
1 LLMFIT_MODEL_CATALOG_EXPANSION_SPEC.md
2 surfsense_local/backend/modules/llm/recommendations/types.py
3 surfsense_local/backend/modules/llm/recommendations/curated_models.py
4 surfsense_local/backend/modules/llm/recommendations/curated-models.json
5 surfsense_local/backend/modules/llm/recommendations/llmfit.py
6 surfsense_local/backend/modules/llm/recommendations/dependencies.py
7 surfsense_local/backend/modules/llm/recommendations/catalog.py
8 surfsense_local/backend/modules/llm/schemas.py
9 surfsense_local/backend/tests/unit/llm/recommendations/test_llmfit.py
10 surfsense_local/backend/tests/unit/llm/recommendations/test_curated_models.py
11 surfsense_local/backend/tests/unit/llm/recommendations/test_catalog.py
12 surfsense_local/backend/tests/integration/llm/test_routes.py
13 surfsense_local/frontend/src/features/model-catalog/api.ts
14 surfsense_local/frontend/src/features/model-catalog/model-catalog-page.tsx
15 surfsense_local/frontend/src/features/model-catalog/model-card.tsx
16 surfsense_local/frontend/src/features/model-catalog/model-catalog.test.tsx
17 surfsense_local/frontend/src/features/model-selection/model-selection-content.tsx
18 surfsense_local/frontend/src/features/onboarding/onboarding-page.tsx
19 surfsense_local/frontend/src/features/settings/models-settings.tsx
20 surfsense_local/frontend/src/app/app-bootstrap.test.tsx
21 surfsense_local/frontend/src/features/dashboard/dashboard-page.test.tsx
22 surfsense_local/frontend/src/features/onboarding/onboarding-page.test.tsx
23 surfsense_local/frontend/src/features/settings/settings-dialog.test.tsx

Need help? Join our Discord

AnishSarkar22 and others added 13 commits September 17, 2026 16:03
Bump schema to v2 and add label, parameter_count, and size_bytes to
each curated entry so curated rows can be shown before any hardware
scan has run.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Rename CatalogResult.recommended/AdvisorCatalog fields to curated and
add a scanned flag distinguishing a scan-free result (cache miss, no
scan requested) from one served without a scan.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…name

Persist scan results to a fingerprinted cache file keyed on llmfit
version, hardware profile, and max context, so scan() only spawns the
expensive scoring subprocess on an explicit refresh=True. Also build a
fallback hf.co/<repo> pull target when llmfit doesn't return a native
ollama_name, so llama.cpp-runnable models no longer silently drop out
of the explore list, with the fit badge downgraded to Marginal when
the pull's quant can't be trusted.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Build scan-free placeholder rows for curated manifest entries and
unmatched installed models so the catalog is useful before any scan
runs, and register synthetic install plans for curated placeholders so
/install works pre-scan. A curated model now always lands in its own
section at whatever fit the scan found, rather than being folded into
"More models" by a hidden fit threshold.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Rename recommended to curated in the ModelCatalog type, key catalog
rows by the scan-stable canonical_id instead of the refresh-sensitive
catalog_id, and replace the explore section with a "Scan hardware"
prompt until data.scanned is true.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Installed models now always sort via the fixed section order in
ModelCatalogPage, so callers no longer need to control it.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…scan

An 'unknown' fit before any scan is every row, all the time, so
repeating a badge that says nothing is noise and stays hidden. An
'unknown' fit after a scan means llmfit had no estimate for this
specific model despite a real scan having run, which is the rare,
actually-notable case and now keeps its badge via a new scanned prop.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Sep 17, 2026

Copy link
Copy Markdown

@AnishSarkar22 is attempting to deploy a commit to the Rohan Verma's projects Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai

coderabbitai Bot commented Sep 17, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: 73508641-9752-47c4-a146-a61e53723a84

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

AnishSarkar22 and others added 8 commits September 17, 2026 20:02
Narrowing the explore list to a few matches (or none) shrunk the
page's scrollable area, which clamped scrollTop and yanked the whole
page upward. Reserve a fixed height for the list while a search query
is active so filtering leaves blank space below instead of moving the
page.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…pi/05d

Relocate LLMFIT_MODEL_CATALOG_EXPANSION_SPEC.md into
plans/community-local/api/, alongside 05a-model-recommendations.md
which owns the recommendations module this spec extends, and retitle
it to match the phase-numbered convention used by its siblings.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>"
A bare hf.co/<repo> pull is accepted by Ollama but silently stored as
hf.co/<repo>:latest, so every later exact-string match against the
ollama_name we handed out (install verification, already-installed
detection on rescan) would permanently fail. Request :latest
explicitly so the identifier we track matches what Ollama actually
names it.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ollama pull ids

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…owing the settings dialog

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
… on explicit "Scan hardware"

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Grid items default to min-width: auto, same as flex items — without
min-w-0, a whitespace-nowrap descendant (the hardware-scan row's
buttons) forced this row's grid item past its 1fr track. The extra
width rendered honestly, then got hard-clipped with no scrollbar by
the settings section's overflow-hidden, cutting off the "Rescan
hardware" button and each model row's action buttons once a scan
populated enough rows to need scrolling.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@AnishSarkar22 AnishSarkar22 changed the title Feat/local model catalog feat(local-models): expand catalog with Hugging Face fallback and opt-in scanning Sep 17, 2026
@AnishSarkar22
AnishSarkar22 merged commit ad8d196 into MODSetter:dev Sep 17, 2026
3 of 7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant