Subagents: a new chat reads /models again, so subagents switched on later show
ci / check (push) Failing after 3s
ci / start (push) Failing after 3s

The Subagents chip on a new chat follows `/models` -> model.subagents.offered, the same
team_run.offered the web page renders from. The app read /models once, at sign-in, and kept
it while it stayed open in the tray: subagents switched on afterwards (or a model added)
never reached a new chat until a restart. startNew() now re-reads it (at most every 5 s,
keeping the last list if the read fails) and redraws the draft's chips (modelsChanged()).
An open chat already re-reads its own `subagents` with GET /chats/{id}.

tests/ui: A5 cases -- parallel model offered: chip, slider to the server's cap, no note;
one-request model offered named_only: the `own` note; offered false everywhere: no chip;
switched on while open: the next new chat has it; an open chat follows its `subagents`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
HomerandClaude Opus 5.5 committed 2026-11-10 08:17:30 +00:00
1 parent 5a87eec28d
commit ec32bca644
4 files changed
+132 -3

No files matched your search

+11 -3
View File
@@ -12,7 +12,7 @@ import { renderSettings, initSettings, scrollToSection } from "./settings.js"
import { initViewer, onViewer, closeViewer } from "./viewer.js"
import { initExplorer, showLocal, showFilesTab } from "./explorer.js"
import { initList, refreshList, markCurrent } from "./list.js"
import { initChat, openChat, newChat, closeChat, openChatId, chatMenu, statusChanged, draftKind, onThisComputer } from "./chat.js"
import { initChat, openChat, newChat, closeChat, openChatId, chatMenu, statusChanged, draftKind, onThisComputer, modelsChanged } from "./chat.js"
import { initAttach, allowAttach } from "./attach.js"
import { initPalette, openPalette } from "./palette.js"
import { initActivity, showPanel, togglePanel, panelOpen } from "./activity.js"
@@ -117,13 +117,17 @@ function stopApp() {
closeViewer()
}
async function loadModels() {
let modelsAt = 0 // when /models was last read
/** The account's models, with what a new chat on each is offered. `keep`: a failed read keeps the last list. */
async function loadModels({ keep = false } = {}) {
try {
const r = await get("/models")
models = r.models || []
noteSubagentsCap(r.subagents_cap)
modelsAt = Date.now()
} catch {
models = []
if (!keep) models = []
}
}
@@ -177,6 +181,10 @@ function startNew(kind) {
newChat(kind || draftKind())
markCurrent()
localPane()
// What a new chat is offered (its models, Subagents) is the server's word now, not at sign-in:
// an administrator may have switched subagents on or added a model while the app stayed open in
// the tray. Drawn at once from the last list, then again from the fresh one.
if (started && Date.now() - modelsAt > 5000) loadModels({ keep: true }).then(modelsChanged)
}
/** Open a chat, from the list or the palette. */