Context
Follow-up to #130 (boot-time optimizations). Findings 1–3 — dropping the redundant MCP listTools() health check, using the getTools() cache, and parallelizing the independent boot I/O — landed in #265. This issue tracks the one remaining item, Finding 4, which was deliberately deferred as a browser-verified UX change.
Problem
The welcome message and example questions come from appConfig.welcome.examples — static data already in memory right after the config fetch (app/main.js:24). But ChatUI isn't instantiated until the end of boot (app/main.js:363, after the agent at L358), so the welcome screen doesn't paint until the entire boot chain (catalog walk + map style + MCP connect + prompts) completes.
Net effect: the user stares at an empty panel for the full boot duration even though everything needed to render the welcome was available in the first ~100ms.
Why it wasn't done in #265
It's not a reorder — ChatUI's constructor is tightly coupled to the agent:
- it wires ~10
agent.onX callbacks (app/chat-ui.js:209–217),
- reads
agent.selectedModel (app/chat-ui.js:237),
- and calls
renderWelcome() at the end of the constructor (app/chat-ui.js:223).
So delivering this means a real (if small) restructure, and chat-ui.js is browser-bound with 0% test coverage — per AGENTS.md it can only be verified visually in a deployed app, not by the test harness. #265 kept to the surgical, unit-testable wins and left this one for a pass that includes deployed-app verification.
Proposed change (conservative variant from #130)
- Split the agent-wiring out of
ChatUI's constructor into a setAgent(agent) setter (callbacks + selectedModel read + input enable).
- Instantiate
ChatUI with just config early in main() (right after step 1), so welcome + examples render immediately.
- Disable the input with a "Loading tools…" placeholder until
setAgent() is called at the current L358–363 point.
The aggressive variant — letting a user click an example and queueing the message until the agent is ready — stays deferred (more state to manage; nicer UX but not required for the time-to-welcome win).
Validation plan (browser, not harness)
- DevTools network waterfall on the live demo, cold load (cache disabled, throttled to Fast 3G for signal): confirm time-to-first-welcome-render drops from end-of-boot to ~100ms.
- Confirm time-to-ready (agent + tools available, input enabled) is unchanged or better.
- Manual smoke test: load, click an example question, verify chat works end-to-end and the model selector reflects
agent.selectedModel.
Scope / non-goals
- No change to the boot I/O ordering (that's done).
- Keep the aggressive click-to-queue variant out of this pass.
Context
Follow-up to #130 (boot-time optimizations). Findings 1–3 — dropping the redundant MCP
listTools()health check, using thegetTools()cache, and parallelizing the independent boot I/O — landed in #265. This issue tracks the one remaining item, Finding 4, which was deliberately deferred as a browser-verified UX change.Problem
The welcome message and example questions come from
appConfig.welcome.examples— static data already in memory right after the config fetch (app/main.js:24). ButChatUIisn't instantiated until the end of boot (app/main.js:363, after the agent at L358), so the welcome screen doesn't paint until the entire boot chain (catalog walk + map style + MCP connect + prompts) completes.Net effect: the user stares at an empty panel for the full boot duration even though everything needed to render the welcome was available in the first ~100ms.
Why it wasn't done in #265
It's not a reorder —
ChatUI's constructor is tightly coupled to the agent:agent.onXcallbacks (app/chat-ui.js:209–217),agent.selectedModel(app/chat-ui.js:237),renderWelcome()at the end of the constructor (app/chat-ui.js:223).So delivering this means a real (if small) restructure, and
chat-ui.jsis browser-bound with 0% test coverage — perAGENTS.mdit can only be verified visually in a deployed app, not by the test harness. #265 kept to the surgical, unit-testable wins and left this one for a pass that includes deployed-app verification.Proposed change (conservative variant from #130)
ChatUI's constructor into asetAgent(agent)setter (callbacks +selectedModelread + input enable).ChatUIwith justconfigearly inmain()(right after step 1), so welcome + examples render immediately.setAgent()is called at the current L358–363 point.The aggressive variant — letting a user click an example and queueing the message until the agent is ready — stays deferred (more state to manage; nicer UX but not required for the time-to-welcome win).
Validation plan (browser, not harness)
agent.selectedModel.Scope / non-goals