feat: crawl full Ollama library catalog

This commit is contained in:
Hermes Agent
2026-08-26 00:21:23 +10:00
parent 2e47e0eae8
commit 29fe832929
4 changed files with 42 additions and 6 deletions
+4 -1
View File
@@ -47,7 +47,10 @@ The Available downloads controls support:
Popularity and date ordering use upstream metadata only; the plugin does not invent popularity, dates, RAM requirements, or token metrics.
## CPU and GPU telemetry
## Available catalog source
Available downloads now combine Ollama's popular API response with the public `https://ollama.com/library` index and each public family tag page. This means models that are not currently popular and are not installed locally—such as `ornith-1.5:9b` and `ornith-1.5:35b`—are discoverable. The catalog refresh found 235 public family slugs and 7,230 raw variants during validation. The existing MLX exclusion and host-RAM fit filter still apply, so very large variants such as `ornith-1.5:397b` remain hidden when they cannot fit the detected host RAM.
The Live runtime panel now shows overall CPU usage, logical CPU count, load averages, overall GPU utilization, and per-GPU VRAM usage. When multiple logical CPUs are detected, it expands into a scrollable responsive per-core grid. When multiple GPUs are detected, it expands into a responsive per-GPU grid showing utilization, VRAM used/free, temperature, and power when the driver reports them. The grids use auto-fit sizing and bounded scrolling so the panel scales to larger CPU and GPU counts without overflowing the dashboard.
+1 -1
View File
@@ -3,7 +3,7 @@
"label": "Ollama Models",
"description": "Inspect, manage, and chat with local Ollama models, including shared persistent conversations, performance metrics, images, PDFs, URLs, and live memory telemetry.",
"icon": "Cpu",
"version": "1.5.17",
"version": "1.5.18",
"tab": {"path": "/ollama-manager", "position": "after:models"},
"entry": "dist/index.js",
"css": "dist/style.css",
+36 -3
View File
@@ -1037,6 +1037,22 @@ def _parse_variant_page(html: str, family: str) -> list[dict[str, Any]]:
return [row for row in rows if not row["is_mlx"]]
def _fetch_library_families() -> list[str]:
"""Return all public model-family slugs from Ollama's library index."""
try:
html = _text_request(f"{REMOTE_OLLAMA}/library", timeout=30)
except (HTTPError, URLError, OSError, ValueError):
return []
families: set[str] = set()
for href in re.findall(r'href=["\'](/library/[^"\']+)["\']', html, re.I):
path = unquote(href.split("?", 1)[0]).strip("/")
parts = path.split("/")
if len(parts) != 2 or not re.fullmatch(r"[A-Za-z0-9][A-Za-z0-9._-]{0,190}", parts[1]):
continue
families.add(parts[1])
return sorted(families)
def _fetch_family_variants(family: str) -> list[dict[str, Any]]:
try:
html = _text_request(f"{REMOTE_OLLAMA}/library/{family}/tags", timeout=30)
@@ -1065,8 +1081,25 @@ def _write_catalog(value: dict[str, Any]) -> None:
def _refresh_family_variants(rows: list[dict[str, Any]]) -> dict[str, list[dict[str, Any]]]:
families = sorted({_family_key(str(row.get("name") or row.get("model"))) for row in rows if not _is_mlx(row)})
return {family: _fetch_family_variants(family) for family in families if family}
families = {
_family_key(str(row.get("name") or row.get("model")))
for row in rows
if not _is_mlx(row)
}
families.update(_fetch_library_families())
families.discard("")
# The public library currently contains hundreds of families. Fetch tag
# pages concurrently so a daily refresh does not serialize network waits.
result: dict[str, list[dict[str, Any]]] = {}
with ThreadPoolExecutor(max_workers=8) as executor:
futures = {executor.submit(_fetch_family_variants, family): family for family in sorted(families)}
for future in as_completed(futures):
family = futures[future]
try:
result[family] = future.result()
except Exception:
result[family] = []
return result
def refresh_catalog(force: bool = True) -> dict[str, Any]:
@@ -1077,7 +1110,7 @@ def refresh_catalog(force: bool = True) -> dict[str, Any]:
rows = [item for item in payload.get("models", []) if isinstance(item, dict) and not _is_mlx(item)]
catalog = {
"fetched_at": datetime.now(timezone.utc).isoformat(),
"source": f"{REMOTE_OLLAMA}/api/tags",
"source": f"{REMOTE_OLLAMA}/api/tags + {REMOTE_OLLAMA}/library",
"models": rows,
"families": _refresh_family_variants(_local_tags()),
}
+1 -1
View File
@@ -1,5 +1,5 @@
name: ollama-manager
version: 1.5.17
version: 1.5.18
description: Native dashboard manager and chat interface for local Ollama models, attachments, URLs, shared persistent conversations, performance metrics, and live runtime telemetry.
auto_install_dependencies: true
python_dependencies: