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. 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. 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", "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.", "description": "Inspect, manage, and chat with local Ollama models, including shared persistent conversations, performance metrics, images, PDFs, URLs, and live memory telemetry.",
"icon": "Cpu", "icon": "Cpu",
"version": "1.5.17", "version": "1.5.18",
"tab": {"path": "/ollama-manager", "position": "after:models"}, "tab": {"path": "/ollama-manager", "position": "after:models"},
"entry": "dist/index.js", "entry": "dist/index.js",
"css": "dist/style.css", "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"]] 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]]: def _fetch_family_variants(family: str) -> list[dict[str, Any]]:
try: try:
html = _text_request(f"{REMOTE_OLLAMA}/library/{family}/tags", timeout=30) 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]]]: 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)}) families = {
return {family: _fetch_family_variants(family) for family in families if family} _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]: 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)] rows = [item for item in payload.get("models", []) if isinstance(item, dict) and not _is_mlx(item)]
catalog = { catalog = {
"fetched_at": datetime.now(timezone.utc).isoformat(), "fetched_at": datetime.now(timezone.utc).isoformat(),
"source": f"{REMOTE_OLLAMA}/api/tags", "source": f"{REMOTE_OLLAMA}/api/tags + {REMOTE_OLLAMA}/library",
"models": rows, "models": rows,
"families": _refresh_family_variants(_local_tags()), "families": _refresh_family_variants(_local_tags()),
} }
+1 -1
View File
@@ -1,5 +1,5 @@
name: ollama-manager 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. 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 auto_install_dependencies: true
python_dependencies: python_dependencies: