Studio: list Ollama models in the chat picker and load their manifest refs by lonexreb · Pull Request #9237 · unslothai/unsloth · GitHub
Skip to content

Studio: list Ollama models in the chat picker and load their manifest refs - #9237

Merged
wasimysaid merged 19 commits into
unslothai:mainfrom
lonexreb:fix/chat-picker-ollama-models
Aug 20, 2026
Merged

Studio: list Ollama models in the chat picker and load their manifest refs#9237
wasimysaid merged 19 commits into
unslothai:mainfrom
lonexreb:fix/chat-picker-ollama-models

Conversation

@lonexreb

Copy link
Copy Markdown
Contributor

What

Models pulled with Ollama never appeared in the chat model picker: the hub inventory returned them (source="ollama"), and the frontend threw the rows away. Fixes #9226.

Why it was missing

The exclusion was deliberate, not an oversight. /api/hub/local scans read-only and hands back an opaque ollama-manifest: reference; the design documented in hub/services/models/ollama.py was for the load path to resolve it via materialize_ollama_model_ref() — but nothing ever called it, so the picker withheld rows that would have failed on click (the old comment in local-model-options.ts says exactly this).

What this does

Backend_resolve_model_identifier_for_request() now materializes ollama-manifest: refs into the .gguf link (covers both POST /load and validate; 400 with redacted detail on a bad ref). New test file pins the hand-off, including the outside-known-dirs rejection.

Frontend"ollama" joins PICKER_LOCAL_SOURCES / CHAT_LOCAL_SOURCES and the LocalModelInfo source union; rows list under Custom Folders (where the reporter expected them) as direct loads, labelled "Ollama" in Chat's local list.

Contracts kept — Ollama stays out of the API auto-switch promise: isOllamaLinkPath() now also recognizes manifest refs so apiLoadable remains false at both call sites, AUTO_LOAD_LOCAL_SOURCES is untouched (comment updated to state the policy reason, since "not loadable" no longer holds), and all pinned assertions in tests/studio/test_model_picker_contracts.py still pass unchanged.

Known limitation

After a restart, a loaded Ollama model's row won't show the loaded badge: the runtime reports the resolved link path while the row id is the manifest ref. In-session selection state works. Happy to follow up with a ref→path identity mapping if you want it in this PR.

Tests

  • studio/backend/tests/test_ollama_manifest_load_resolution.py — new, 3 tests
  • studio/backend/hub/tests/test_model_services.py — 262 pass
  • tests/studio/test_model_picker_contracts.py — unchanged, 183 pass (1 pre-existing failure on main, unrelated)
  • studio/frontend/tests/chat-local-model-options.test.ts — first test flipped from "withheld" to "offered", per its own stated flip condition
  • Frontend tsc clean; kwarg-spacing formatter applied

… refs

The read-only hub inventory returns Ollama rows whose load id is an opaque
ollama-manifest: reference, and the picker deliberately dropped them because
nothing resolved that reference on load. Wire up the hand-off the design
already documented: POST /load (and validate) now materialize the reference
into a .gguf link via materialize_ollama_model_ref, and the picker lists the
rows under Custom Folders as direct loads.

Ollama rows stay out of the API auto-switch promise: isOllamaLinkPath now
also recognizes manifest refs, so apiLoadable remains false, and
AUTO_LOAD_LOCAL_SOURCES is untouched.

Fixes unslothai#9226
@danielhanchen

Copy link
Copy Markdown
Member

@wasimysaid

Copy link
Copy Markdown
Collaborator

Thanks — I reproduced one issue end to end at a4442684. A real Ollama model with num_predict 1 produced 1/1/1 tokens directly; Studio exposed and loaded the same row, but produced 7 tokens because only the base GGUF was materialized and the manifest behavior was dropped.

Fork repro: https://github.com/wasimysaid/unsloth/actions/runs/32273429355. Could you either preserve the supported manifest settings/layers or reject rich manifests explicitly, then reverify with a behavioral test? The malformed/out-of-root ref checks looked good.

wasimysaid added a commit to wasimysaid/unsloth that referenced this pull request Aug 20, 2026
@wasimysaid

Copy link
Copy Markdown
Collaborator

Pushed the fix directly. Studio now withholds Ollama manifests whose template/params/system/messages/adapters or unknown layers cannot be preserved by the raw llama.cpp handoff, and direct opaque refs get a clear 400 instead of silently changing model behavior. Plain model/projector/license manifests remain loadable.

Final head is 916e2fd5 (d345b6fe plus pre-commit's whitespace-only cleanup). The focused regression is green locally and on Linux, macOS, and Windows: 6 passed on each.

@wasimysaid

Copy link
Copy Markdown
Collaborator

@codex review

chatgpt-codex-connector[bot]

This comment was marked as resolved.

wasimysaid added a commit to wasimysaid/unsloth that referenced this pull request Aug 20, 2026
@wasimysaid

Copy link
Copy Markdown
Collaborator

Addressed both Codex findings and pushed them to the PR. The materialized GGUF link is now used only as the load artifact while the opaque ollama-manifest: ref remains the public/status identity, and non-object manifest/config/config-blob JSON is normalized to a clear 400 instead of escaping as a 500.

Final head da8d8972d (including pre-commit's formatting-only follow-up): focused tests 9 passed, dependent GGUF load suites 159 passed, Ruff and the retained real Ollama-store probe passed. Fork Actions also passed on Linux, macOS, and Windows.

@codex review

chatgpt-codex-connector[bot]

This comment was marked as resolved.

wasimysaid added a commit to wasimysaid/unsloth that referenced this pull request Aug 20, 2026
@wasimysaid

Copy link
Copy Markdown
Collaborator

Fixed and pushed. Ollama rows now keep both their GGUF format and an explicit direct-artifact marker, so Chat sends GGUF load metadata, matches loaded state without a variant, and still handles names containing -GGUF- correctly. Non-Ollama GGUF variant behavior is unchanged.

Added regression coverage for the direct/variant policy, merged current main to clear the conflict, and rechecked the final tree. Focused tests, typecheck, strict i18n, and the production build pass locally. The targeted fork Action also passed on Linux, macOS, and Windows.

@codex review

chatgpt-codex-connector[bot]

This comment was marked as resolved.

@unslothai unslothai deleted a comment from chatgpt-codex-connector Bot Aug 20, 2026
@unslothai unslothai deleted a comment from chatgpt-codex-connector Bot Aug 20, 2026
@unslothai unslothai deleted a comment from chatgpt-codex-connector Bot Aug 20, 2026
@unslothai unslothai deleted a comment from chatgpt-codex-connector Bot Aug 20, 2026
@unslothai unslothai deleted a comment from chatgpt-codex-connector Bot Aug 20, 2026
@unslothai unslothai deleted a comment from chatgpt-codex-connector Bot Aug 20, 2026
@unslothai unslothai deleted a comment from chatgpt-codex-connector Bot Aug 20, 2026
@unslothai unslothai deleted a comment from chatgpt-codex-connector Bot Aug 20, 2026
@unslothai unslothai deleted a comment from chatgpt-codex-connector Bot Aug 20, 2026
@unslothai unslothai deleted a comment from chatgpt-codex-connector Bot Aug 20, 2026
@unslothai unslothai deleted a comment from chatgpt-codex-connector Bot Aug 20, 2026
@unslothai unslothai deleted a comment from chatgpt-codex-connector Bot Aug 20, 2026
@unslothai unslothai deleted a comment from chatgpt-codex-connector Bot Aug 20, 2026
@unslothai unslothai deleted a comment from chatgpt-codex-connector Bot Aug 20, 2026
@unslothai unslothai deleted a comment from chatgpt-codex-connector Bot Aug 20, 2026
@unslothai unslothai deleted a comment from chatgpt-codex-connector Bot Aug 20, 2026
@unslothai unslothai deleted a comment from chatgpt-codex-connector Bot Aug 20, 2026
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Keep it up!

Reviewed commit: e45795f3ee

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@wasimysaid

Copy link
Copy Markdown
Collaborator

@wasimysaid
wasimysaid merged commit d55753f into unslothai:main Aug 20, 2026
1 check passed
atharvgaur1845 added a commit to atharvgaur1845/unsloth that referenced this pull request Aug 20, 2026
unslothai#9237 landed a large Ollama rewrite on main that overlapped this branch in
studio/backend/hub/services/models/ollama.py. Resolved by reapplying this
branch's refactors on top of main's version and adopting what unslothai#9237 added:

- Dropped this branch's is_ollama_manifest_ref; main added the same helper.
- The delete now resolves a reference through main's
  _validated_ollama_manifest_location instead of re-deriving it. That validates
  against the discovered AND registered Ollama roots, canonicalizes the path,
  and deletes the symlink-fallback branch this branch had written for the same
  job. Two validations that could disagree about which references are in bounds
  is how a delete reaches somewhere it never should have.
- unslothai#9237 gave materialization a per-manifest lock, which makes it the second
  writer of a model's links and blobs. The delete now takes that same lock for
  the whole plan-and-remove, so a load landing mid-delete cannot re-create the
  .studio_links directory the delete just collected, nor open a manifest whose
  blobs are already unlinked. The wait is bounded and answers 409 rather than
  hanging: a load holds its lease for the length of the load.

The links-root and stem-hash refactors reapply unchanged -- main did not touch
either -- so the scan and the delete still read one definition of where link
files live.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Studio Bug] Ollama models never appear in the model picker: source "ollama" has no branch in the UI

3 participants