92 lines
3.0 KiB
Python
92 lines
3.0 KiB
Python
"""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
|