feat: expose Ollama models in Hermes picker

This commit is contained in:
Hermes Agent
2026-08-25 19:17:59 +10:00
parent 73a38617e3
commit 20555c802a
6 changed files with 127 additions and 2 deletions
+91
View File
@@ -0,0 +1,91 @@
"""Synchronize Ollama Models endpoints into Hermes' native model picker."""
from __future__ import annotations
import json
import logging
import os
from pathlib import Path
from typing import Any
from hermes_constants import get_hermes_home
logger = logging.getLogger(__name__)
LOCAL_PROVIDER_KEY = "ollama-manager-local"
REMOTE_PROVIDER_KEY = "ollama-manager-remote"
_OWNED_PROVIDER_KEYS = {LOCAL_PROVIDER_KEY, REMOTE_PROVIDER_KEY}
def _running_in_container() -> bool:
return Path("/.dockerenv").exists() or Path("/run/.containerenv").exists()
def _default_endpoint() -> str:
configured = os.environ.get("OLLAMA_HOST", "").strip().rstrip("/")
if configured:
return configured
return "http://ollama:11434" if _running_in_container() else "http://localhost:11434"
def _connections() -> dict[str, str]:
path = get_hermes_home() / "ollama-manager" / "connections.json"
try:
value = json.loads(path.read_text(encoding="utf-8"))
except (OSError, ValueError, TypeError):
value = {}
if not isinstance(value, dict):
value = {}
return {
key: str(value.get(key) or "").strip().rstrip("/")
for key in ("active_url", "local_url", "remote_url")
}
def _endpoint_to_api(endpoint: str) -> str:
endpoint = str(endpoint or "").strip().rstrip("/")
if endpoint.endswith("/v1"):
return endpoint
return endpoint + "/v1"
def _provider_entry(name: str, endpoint: str) -> dict[str, Any]:
return {
"name": name,
"api": _endpoint_to_api(endpoint),
"transport": "chat_completions",
"discover_models": True,
}
def sync_hermes_ollama_providers(connections: dict[str, str] | None = None) -> bool:
"""Upsert the plugin's local/remote providers without changing defaults."""
try:
from hermes_cli.config import load_config, save_config
saved = connections or _connections()
local = saved.get("local_url") or saved.get("active_url") or _default_endpoint()
remote = saved.get("remote_url")
if remote and remote == local:
remote = ""
config = load_config()
providers = config.get("providers")
if not isinstance(providers, dict):
providers = {}
config["providers"] = providers
for key in _OWNED_PROVIDER_KEYS:
providers.pop(key, None)
providers[LOCAL_PROVIDER_KEY] = _provider_entry("Ollama Models (Local)", local)
if remote:
providers[REMOTE_PROVIDER_KEY] = _provider_entry("Ollama Models (Remote)", remote)
# The provider is selectable, not the active default. Do not touch
# model.default or model.provider while installing/updating the plugin.
save_config(config, strip_defaults=False)
return True
except Exception as exc: # provider registration must never break the dashboard
logger.warning("Could not synchronize Ollama providers into Hermes config: %s", exc)
return False