fix: show endpoint model names and duplicate targets

This commit is contained in:
Hermes Agent
2026-08-24 22:02:48 +10:00
parent da3293fff4
commit a9e8c63791
5 changed files with 11 additions and 6 deletions
+2 -2
View File
@@ -74,7 +74,7 @@
h("div", { className: "ollama-connection-heading" }, h("div", null, h("strong", null, "Ollama connection"), h("small", null, ollama.containerized ? "Docker runtime · local and remote endpoints supported" : "Physical runtime · local and remote endpoints supported"))),
h("div", { className: "ollama-connection-form" }, h("select", { className: "ollama-connection-role", value: role, onChange: function (event) { setRole(event.target.value); } }, h("option", { value: "local" }, "Local"), h("option", { value: "remote" }, "Remote")), h("input", { className: "ollama-connection-input", value: url, placeholder: "http://host-or-container:11434", onChange: function (event) { setUrl(event.target.value); } }), h(Button, { onClick: test, disabled: !url.trim() || !!busy }, busy === "test" ? "Testing…" : "Test"), h(Button, { onClick: save, disabled: !url.trim() || !!busy }, busy === "save" ? "Saving…" : "Save")),
result && h("div", { className: "ollama-connection-result " + (result.error ? "error" : "ok") }, result.error || ((result.value && result.value.version) ? "Online · v" + result.value.version + " · " + (result.value.models || 0) + " models" : "Connection accepted")),
h("div", { className: "ollama-connection-list" }, rows.length ? rows.map(function (item) { return h("button", { type: "button", className: "ollama-connection-row", key: item.kind + ":" + item.url, onClick: function () { useDetected(item); } }, h("span", { className: "ollama-connection-dot " + (item.available ? "online" : "offline") }), h("span", null, h("strong", null, (item.kind || "local").toUpperCase(), " · ", item.label || item.url), h("small", null, item.url, item.available ? " · v" + item.version + " · " + item.models + " models" : " · unavailable"))); }) : h("small", null, "No endpoints detected yet. Enter an Ollama URL and test it."))
h("div", { className: "ollama-connection-list" }, rows.length ? rows.map(function (item) { return h("button", { type: "button", className: "ollama-connection-row", key: item.kind + ":" + item.url, onClick: function () { useDetected(item); } }, h("span", { className: "ollama-connection-dot " + (item.available ? "online" : "offline") }), h("span", null, h("strong", null, (item.kind || "local").toUpperCase(), " · ", item.label || item.url), h("small", null, item.url, item.available ? " · v" + item.version + " · " + item.models + " models" + (item.model_names && item.model_names.length ? " · " + item.model_names.join(", ") : "") + (item.same_endpoint ? " · same endpoint as local" : "") : " · unavailable"))); }) : h("small", null, "No endpoints detected yet. Enter an Ollama URL and test it."))
);
}
@@ -376,7 +376,7 @@
if (kind === "delete" && !window.confirm("Remove " + name + " from Ollama?")) return;
if ((kind === "pull" || kind === "redownload") && !selectedTarget) {
var availableTargets = (data && data.connections ? data.connections : []).filter(function (item) { return item.available && (item.kind === "local" || item.kind === "remote"); });
var uniqueTargets = availableTargets.filter(function (item, index, rows) { return rows.findIndex(function (other) { return other.kind === item.kind; }) === index; });
var uniqueTargets = availableTargets.filter(function (item, index, rows) { return rows.findIndex(function (other) { return other.kind === item.kind || other.url === item.url; }) === index; });
if (uniqueTargets.length > 1) { setTargetDialog({ kind: kind, name: name, targets: uniqueTargets }); return; }
selectedTarget = uniqueTargets.length ? uniqueTargets[0].kind : "local";
}
+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.7",
"version": "1.5.8",
"tab": {"path": "/ollama-manager", "position": "after:models"},
"entry": "dist/index.js",
"css": "dist/style.css",
+6 -1
View File
@@ -333,7 +333,8 @@ def _probe_endpoint(url: str, timeout: int = 5) -> dict[str, Any]:
version_payload = _json_request(url + "/api/version", timeout=timeout)
tags_payload = _json_request(url + "/api/tags", timeout=timeout)
models = tags_payload.get("models", [])
return {"available": True, "url": url, "version": str(version_payload.get("version") or "unknown"), "models": len(models) if isinstance(models, list) else 0}
model_names = [str(item.get("name") or item.get("model")) for item in models if isinstance(item, dict) and (item.get("name") or item.get("model"))]
return {"available": True, "url": url, "version": str(version_payload.get("version") or "unknown"), "models": len(model_names), "model_names": model_names[:100]}
def _connection_snapshot() -> list[dict[str, Any]]:
@@ -365,6 +366,10 @@ def _connection_snapshot() -> list[dict[str, Any]]:
except Exception as exc:
result = {"available": False, "kind": kind, "label": label, "url": normalized, "error": str(exc)[:240]}
results.append(result)
local_urls = {row.get("url") for row in results if row.get("kind") == "local" and row.get("available")}
for row in results:
if row.get("kind") == "remote" and row.get("url") in local_urls:
row["same_endpoint"] = True
return results