fix: stop polling llama-servers during external-model sessions

selectSessionUrls fell back to all discovered servers when the current
session's provider matched no candidate, so external sessions kept
polling local servers: one answered /slots with idle slots (showing
'- tps (TG)') while another rejected unknown models with HTTP 400
(flickering 'n/a'). Narrow to zero URLs instead and surface n/a.
This commit is contained in:
Troed Sångberg
2026-08-21 15:52:50 +02:00
parent e598af0a05
commit aa5ae2b724
3 changed files with 30 additions and 10 deletions
+3 -3
View File
@@ -284,7 +284,7 @@ export function selectSessionUrls(
): string[] {
if (typeof providerID !== "string" || providerID.trim() === "" || candidates.length === 0)
return candidates
if (!Array.isArray(providers)) return candidates
if (!Array.isArray(providers) || providers.length === 0) return candidates
for (const entry of providers) {
if (!entry || typeof entry !== "object") continue
const provider = entry as Record<string, unknown>
@@ -298,7 +298,7 @@ export function selectSessionUrls(
if (candidates.includes(normalized)) return [normalized]
}
}
break
return []
}
return candidates
return []
}
+22 -6
View File
@@ -178,10 +178,10 @@ test("selectSessionUrls returns candidates unchanged when provider not found", (
assert.deepEqual(selectSessionUrls(candidates, [], "nope"), ["http://a:1"])
})
test("selectSessionUrls returns candidates unchanged when matched provider URL is not a candidate", () => {
test("selectSessionUrls excludes polling when matched provider URL is not a candidate", () => {
const candidates = ["http://a:1"]
const providers = [{ id: "ollama", name: "Ollama", options: { baseURL: "http://d:4" } }]
assert.deepEqual(selectSessionUrls(candidates, providers, "ollama"), ["http://a:1"])
assert.deepEqual(selectSessionUrls(candidates, providers, "ollama"), [])
})
test("selectSessionUrls returns candidates unchanged for missing or empty providerID", () => {
@@ -191,20 +191,36 @@ test("selectSessionUrls returns candidates unchanged for missing or empty provid
assert.deepEqual(selectSessionUrls(["http://a:1"], [], 42), ["http://a:1"])
})
test("selectSessionUrls ignores non-string baseURL on matched provider", () => {
test("selectSessionUrls excludes polling when matched provider has no usable baseURL", () => {
const candidates = ["http://a:1"]
const providers = [{ id: "p", name: "P", options: { baseURL: 42 } }]
assert.deepEqual(selectSessionUrls(candidates, providers, "p"), ["http://a:1"])
assert.deepEqual(selectSessionUrls(candidates, providers, "p"), [])
})
test("selectSessionUrls returns empty candidates unchanged", () => {
assert.deepEqual(selectSessionUrls([], [], "p"), [])
})
test("selectSessionUrls tolerates non-array and malformed providers", () => {
test("selectSessionUrls tolerates non-array providers", () => {
const c = ["http://a:1"]
assert.deepEqual(selectSessionUrls(c, undefined, "p"), c)
assert.deepEqual(selectSessionUrls(c, [null, 42, {}, { id: "p" }], "p"), c)
})
test("selectSessionUrls excludes polling when id is absent from a non-empty provider list", () => {
assert.deepEqual(selectSessionUrls(["http://a:1"], [null, 42, {}], "p"), [])
assert.deepEqual(selectSessionUrls(["http://a:1"], [{ id: "other", options: { baseURL: "http://a:1" } }], "p"), [])
})
test("selectSessionUrls excludes polling during external-model sessions", () => {
// Mirrors the reported regression: local router + single-model server discovered,
// while the session runs on an unrelated external provider.
const candidates = ["http://localhost:8080", "http://127.0.0.1:40909"]
const providers = [
{ id: "llamacpp-router", name: "llama.cpp router", options: { baseURL: "http://localhost:8080/v1" } },
{ id: "ornith", name: "Ornith", options: { baseURL: "http://127.0.0.1:40909/v1" } },
{ id: "opencode", name: "OpenCode", options: { baseURL: "https://api.example.internal/v1" } },
]
assert.deepEqual(selectSessionUrls(candidates, providers, "opencode"), [])
})
test("selectSessionUrls first match wins for duplicate ids", () => {
+5 -1
View File
@@ -197,7 +197,11 @@ const tui: TuiPlugin = async (api, options) => {
}
const activeUrls = selectSessionUrls(llamaServerUrls, api.state.provider, sessionProviderId)
if (!activeUrls.length) return
if (!activeUrls.length) {
tracker.failure = "n/a"
bump()
return
}
for (const baseUrl of activeUrls) {
const now = Date.now()
const backoff = backoffByUrl.get(baseUrl)