Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions src/local_coding_slm/ollama_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,11 @@ def list_model_names(settings: OllamaSettings | None = None) -> list[str]:
return names


def _model_present(tag: str, names: list[str]) -> bool:
"""Exact tag, or the same tag with an Ollama suffix such as :latest."""
return any(name == tag or name.startswith(f"{tag}:") for name in names)


def status_report(settings: OllamaSettings | None = None) -> str:
settings = settings or OllamaSettings.from_env()
try:
Expand All @@ -168,8 +173,8 @@ def status_report(settings: OllamaSettings | None = None) -> str:
f"host={settings.host_label()} ok=false error={exc} "
f"fast={settings.fast_model} strong={settings.strong_model}"
)
have_fast = any(settings.fast_model in n for n in names)
have_strong = any(settings.strong_model in n for n in names)
have_fast = _model_present(settings.fast_model, names)
have_strong = _model_present(settings.strong_model, names)
return (
f"host={settings.host_label()} ok=true "
f"fast={settings.fast_model} present={have_fast} "
Expand Down
16 changes: 16 additions & 0 deletions tests/test_ollama_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,22 @@ def test_status_report_marks_present_models(self) -> None:
self.assertIn("fast=qwen3.5:9b present=True", report)
self.assertIn("strong=devstral-small-2 present=False", report)

def test_status_report_ignores_substring_model_names(self) -> None:
"""A name that merely contains the tag is not that model. A :latest suffix is."""
payload = {
"models": [
{"name": "not-qwen3.5:9b-extra"},
{"name": "devstral-small-2:latest"},
]
}
with patch(
"local_coding_slm.ollama_client._open",
return_value=_FakeResp(payload),
):
report = status_report(self.settings)
self.assertIn("fast=qwen3.5:9b present=False", report)
self.assertIn("strong=devstral-small-2 present=True", report)

def test_chat_returns_message_content(self) -> None:
payload = {"message": {"content": "def ping(): return True"}}
with patch(
Expand Down
Loading