Skip to content

perf(boot): render welcome + examples early via ChatUI setAgent() (Finding 4 of #130) #268

Description

@cboettig

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.examplesstatic 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)

  1. Split the agent-wiring out of ChatUI's constructor into a setAgent(agent) setter (callbacks + selectedModel read + input enable).
  2. Instantiate ChatUI with just config early in main() (right after step 1), so welcome + examples render immediately.
  3. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions