Skip to content

feat: search and download local models from the provider cards - #148

Merged
cmdaltctr merged 19 commits into
v3from
feat/add-model-search-and-download
Oct 29, 2026
Merged

cmdaltctr merged 19 commits into
v3from
feat/add-model-search-and-download

Conversation

@cmdaltctr

@cmdaltctr cmdaltctr commented Oct 29, 2026 •

Copy link
Copy Markdown
Owner

Summary

Adds a Get a model panel to the llama.cpp and Ollama provider cards. A user searches Hugging Face (GGUF repos only), picks a quantisation, and downloads it with progress and cancel. Ollama also offers built-in library names and a typed name. OpenSpec change: openspec/changes/add-model-search-and-download/ (39 of 39 tasks). Decision record: ADR-106 (Accepted).

  • core/providers/model_sources.py: name, label, revision and query rules, quantisation parser, split-file grouping. A new optional model_source field on ConnectionDescriptor turns the panel on (llama.cpp and Ollama only).
  • integrations/huggingface_models.py: search and file list over plain HTTP with no token, a 10 s timeout, a body limit and same-host paging. Downloads use hf_hub_download into the standard Hugging Face cache.
  • integrations/ollama_pull.py: streamed POST /api/pull with summed layer progress.
  • transports/api/model_download_job.py and routes/model_downloads.py: one job at a time, a 60 s stall check, cancel, shutdown, a free-space check (1 GiB margin) and a gated-repo check. The five new routes need the browser session manage scope.
  • web/src/settings/: the panel, the file list, progress, and the finished state. Use this model shows only when omrs runs the llama.cpp server. For an external server such as the Llama app, the panel shows the cache folder, a relaunch note and Refresh models.

Findings fixed during the build

  • Xet cancel. On Xet storage an exception from the progress class does not stop a download. Cancel uses huggingface_hub.utils._xet.abort_xet_session(), and a test pins that it exists. A cancelled download starts again from zero, because the library deletes partial files. The spec says so.
  • Xet stall (live check). The stall check stopped a healthy 1.8 GB download, because Xet reports assembly in steps more than 60 s apart. Progress now uses the larger of assembled and network bytes, capped at the file size.
  • Review. A scoped open-code-review on 15 source files gave 11 findings, and all valid ones are fixed: tree paging, a status-read race, a read-error branch, Ollama wording, and the start using the revision the user saw.

Checks

  • ./scripts/local_ci.sh passed on 418e3c7d, with no SKIPPED step. Python had 9,440 passed and 149 skipped. Web had 2,205 tests. OpenSpec validated 89 of 89.
  • Tripwire re-pinned by a test-ID diff against v3.
  • Browser check at 1280 px and 390 px: 6 of 6 pass. Screenshots are in openspec/changes/add-model-search-and-download/screenshots/.
  • Live checks: see live-checks.md.
    • The Llama app listed the downloaded model after a relaunch, and Refresh models showed it.
    • A Homebrew llama-server loaded a cached model with no new download.
    • An Ollama pull showed progress and listed the model.

Not in this PR

  • The OpenSpec change is not archived yet.
  • Two proposed low-score items: a gated result row lays out differently (score 2), and the dark-theme track was raised but not re-checked in a browser.

Summary by CodeRabbit

  • New Features
    • Search for models from provider settings and download GGUF models for llama.cpp or pull models through Ollama.
    • Choose model variants, view download progress, and cancel active downloads.
    • After downloading, use the model with a managed llama.cpp server or refresh the provider’s model list.
  • Documentation
    • Added guides covering model search, downloads, storage, access requirements, and server restart behaviour.

Record checks 1.1, 1.1b, 1.2 and 1.3 in design.md. A cancelled
Hugging Face download now starts again: huggingface_hub 1.27 deletes
the partial file, and Xet cancel needs abort_xet_session().
- Follow the Link header of the Hugging Face tree read, capped at 20
  pages and to the same host, so a large repo lists every file.
- Cancel an open status read before a start or cancel writes its
  status, so an older answer cannot stop the progress polling.
- Show a failed llama.cpp server read as an error, not as an own server.
- Give the Ollama list line its own words and a Refresh models button.
- Clear the saved line after the restart runs.
- Start lists the files at the revision the user saw, so a newer
  commit in the repo no longer gives not-found.
- Name each file-list radio group after its provider, so two cards
  that list one repo do not share it.
- Show an error when Cancel fails.
- Pass the abort signal to the provider model list read.
The live check found that the 60-second stall check stopped a healthy
1.8 GB Xet download. On Xet, huggingface_hub reports the file assembly
in large steps, which came 60 seconds apart, while network bytes went
to update_transfer about every second. The progress class now has
update_transfer, and each call resets the stall clock without adding
bytes. A test pins that the library sends network bytes there.
The browser check found that a Xet download showed 0 B until it ended.
Progress is now the larger of the assembled bytes and the network bytes,
capped at the file size, so the bar moves about every second.

Also from the browser check: hide a cancel line left from before the
page loaded, and raise the progress track contrast in the dark theme.
The live check found that the panel offered only built-in names and
hf.co/ repos, so a name such as smollm2:135m could not be pulled.
When the typed text passes the Ollama name rule and no result has it,
the panel shows it first with the badge Typed name (design D6).
@coderabbitai

coderabbitai Bot commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 26 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

Run configuration
Commits

Reviewing files that changed from the base of the PR and between 697f586 and b69411a.

Files ignored due to path filters: 18
  • openspec/changes/add-model-search-and-download/screenshots/1280-cancelled.png is excluded by !**/*.png
  • openspec/changes/add-model-search-and-download/screenshots/1280-files.png is excluded by !**/*.png
  • openspec/changes/add-model-search-and-download/screenshots/1280-finished.png is excluded by !**/*.png
  • openspec/changes/add-model-search-and-download/screenshots/1280-gated.png is excluded by !**/*.png
  • openspec/changes/add-model-search-and-download/screenshots/1280-ollama-search.png is excluded by !**/*.png
  • openspec/changes/add-model-search-and-download/screenshots/1280-progress-xet.png is excluded by !**/*.png
  • openspec/changes/add-model-search-and-download/screenshots/1280-progress.png is excluded by !**/*.png
  • openspec/changes/add-model-search-and-download/screenshots/1280-providers.png is excluded by !**/*.png
  • openspec/changes/add-model-search-and-download/screenshots/1280-search.png is excluded by !**/*.png
  • openspec/changes/add-model-search-and-download/screenshots/1280-stalled.png is excluded by !**/*.png
  • openspec/changes/add-model-search-and-download/screenshots/390-files.png is excluded by !**/*.png
  • openspec/changes/add-model-search-and-download/screenshots/390-finished.png is excluded by !**/*.png
  • openspec/changes/add-model-search-and-download/screenshots/390-get-a-model.png is excluded by !**/*.png
  • openspec/changes/add-model-search-and-download/screenshots/390-ollama-long-id.png is excluded by !**/*.png
  • openspec/changes/add-model-search-and-download/screenshots/390-ollama-search.png is excluded by !**/*.png
  • openspec/changes/add-model-search-and-download/screenshots/390-progress.png is excluded by !**/*.png
  • openspec/changes/add-model-search-and-download/screenshots/390-search.png is excluded by !**/*.png
  • uv.lock is excluded by !**/*.lock, !**/*.lock, !uv.lock
Files selected for processing: 66
  • docs/adr/106-app-searches-and-downloads-local-models.md
  • docs/adr/ADR_README.md
  • docs/guides/architecture.md
  • docs/guides/configuration.md
  • docs/guides/providers.md
  • docs/guides/web-workspace.md
  • openspec/changes/add-model-search-and-download/design.md
  • openspec/changes/add-model-search-and-download/live-checks.md
  • openspec/changes/add-model-search-and-download/screenshots/README.md
  • openspec/changes/add-model-search-and-download/specs/model-downloads/spec.md
  • openspec/changes/add-model-search-and-download/tasks.md
  • pyproject.toml
  • src/omrs/compose_connections.py
  • src/omrs/core/providers/llm/connection.py
  • src/omrs/core/providers/llm/llamacpp.py
  • src/omrs/core/providers/llm/llamacpp_rules.py
  • src/omrs/core/providers/llm/ollama.py
  • src/omrs/core/providers/model_sources.py
  • src/omrs/integrations/huggingface_models.py
  • src/omrs/integrations/ollama_pull.py
  • src/omrs/transports/api/AGENTS.md
  • src/omrs/transports/api/README.md
  • src/omrs/transports/api/app.py
  • src/omrs/transports/api/lifespan.py
  • src/omrs/transports/api/model_download_job.py
  • src/omrs/transports/api/openapi.yaml
  • src/omrs/transports/api/routes/model_downloads.py
  • tests/fixtures/huggingface_models/model_info_unsloth_Qwen3-4B-GGUF.json
  • tests/fixtures/huggingface_models/search_qwen3_4b.json
  • tests/fixtures/huggingface_models/tree_unsloth_Qwen3-4B-GGUF.json
  • tests/test_clean_base_tripwire.py
  • tests/test_dependency_floors.py
  • tests/unit/test_connection_summary.py
  • tests/unit/test_huggingface_download_files.py
  • tests/unit/test_huggingface_downloads.py
  • tests/unit/test_huggingface_models.py
  • tests/unit/test_llamacpp_server_rules.py
  • tests/unit/test_llm_connection_descriptors.py
  • tests/unit/test_model_download_job.py
  • tests/unit/test_model_sources.py
  • tests/unit/test_ollama_pull.py
  • tests/unit/test_web_model_downloads.py
  • tests/unit/test_web_openapi_conformance_support.py
  • web/src/api/modelDownloads.test.ts
  • web/src/api/modelDownloads.ts
  • web/src/api/settings.ts
  • web/src/settings/LlamacppServerFields.tsx
  • web/src/settings/LlamacppUseModel.tsx
  • web/src/settings/ModelDownloadDone.test.tsx
  • web/src/settings/ModelDownloadDone.tsx
  • web/src/settings/ModelDownloadPanel.test.tsx
  • web/src/settings/ModelDownloadPanel.tsx
  • web/src/settings/ModelDownloadProgress.test.tsx
  • web/src/settings/ModelDownloadProgress.tsx
  • web/src/settings/ModelFileList.test.tsx
  • web/src/settings/ModelFileList.tsx
  • web/src/settings/ModelListLine.tsx
  • web/src/settings/ModelSearchField.test.tsx
  • web/src/settings/ModelSearchField.tsx
  • web/src/settings/ProviderCard.tsx
  • web/src/settings/ProvidersSection.test.tsx
  • web/src/settings/modelDownloadWords.ts
  • web/src/settings/test/downloadFixtures.ts
  • web/src/settings/test/fixtures.ts
  • web/src/settings/useModelDownload.test.tsx
  • web/src/settings/useModelDownload.ts
Finishing Touches: 💡 1
🛠️ Fix failing CI checks: 💡
  • Commit to this branch
  • Create a new PR
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

@codecov

codecov Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 96.39037% with 27 lines in your changes missing coverage. Please review.
✅ Project coverage is 94.80%. Comparing base (697f586) to head (b69411a).
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
src/omrs/integrations/huggingface_models.py 96.38% 3 Missing and 5 partials ⚠️
src/omrs/transports/api/routes/model_downloads.py 95.95% 7 Missing and 1 partial ⚠️
src/omrs/core/providers/model_sources.py 93.25% 3 Missing and 3 partials ⚠️
src/omrs/integrations/ollama_pull.py 96.55% 1 Missing and 1 partial ⚠️
src/omrs/transports/api/lifespan.py 71.42% 2 Missing ⚠️
src/omrs/transports/api/model_download_job.py 99.41% 0 Missing and 1 partial ⚠️

❌ Your project check has failed because the head coverage (94.37%) is below the target coverage (95.00%). You can increase the head coverage or adjust the target coverage.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##               v3     #148      +/-   ##
==========================================
+ Coverage   94.76%   94.80%   +0.04%     
==========================================
  Files         365      370       +5     
  Lines       29302    30049     +747     
  Branches     3748     3845      +97     
==========================================
+ Hits        27767    28488     +721     
- Misses       1012     1028      +16     
- Partials      523      533      +10     
Files with missing lines Coverage Δ
src/omrs/compose_connections.py 95.60% <ø> (ø)
src/omrs/core/providers/llm/connection.py 100.00% <100.00%> (ø)
src/omrs/core/providers/llm/llamacpp.py 100.00% <ø> (ø)
src/omrs/core/providers/llm/llamacpp_rules.py 100.00% <100.00%> (ø)
src/omrs/core/providers/llm/ollama.py 91.66% <ø> (ø)
src/omrs/transports/api/app.py 100.00% <100.00%> (ø)
src/omrs/transports/api/model_download_job.py 99.41% <99.41%> (ø)
src/omrs/integrations/ollama_pull.py 96.55% <96.55%> (ø)
src/omrs/transports/api/lifespan.py 94.82% <71.42%> (-0.29%) ⬇️
src/omrs/core/providers/model_sources.py 93.25% <93.25%> (ø)
... and 2 more

The floor CI job installs the oldest allowed huggingface-hub. Model
downloads use the Xet session abort (from 1.20) and the update_transfer
progress route (from 1.23), so 5 tests failed at 1.0.0. The download
tests pass at 1.23.0, and one fails at 1.22.0.
@cmdaltctr
cmdaltctr merged commit 8c8b6f6 into v3 Oct 29, 2026
24 checks passed
cmdaltctr added a commit that referenced this pull request Oct 29, 2026
Sync the model-downloads spec into openspec/specs and point ADR-106 at
the archived change and the PR #148 merge.
@cmdaltctr
cmdaltctr deleted the feat/add-model-search-and-download branch October 29, 2026 18:57
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