Chat model menu polished and Trace Ingestion moved to Observability
· 2 min read
The Chat header now uses a dark, searchable model menu for all 9Router models, and Trace Ingestion has moved out of the Chat area into the existing Observability activity-bar page.
What changed
index.htmlreplaced the native#brainModelSelectwith an app-owned model picker:#brainModelTrigger,#brainModelMenu,#brainModelSearch, and#brainModelList. It also added thedata-view="observability"right-panel view and the new#observabilitySlotmount target.src/brain-ui.tsnow renders the model list as a custom listbox while keeping the existingchatModels,selectedChatModel, andexepert.brainChat.model.v1persistence flow. The menu supports provider grouping, search, variant badges, Escape, ArrowUp/ArrowDown, Enter, outside-click dismissal, and disabled state while streaming.src/ui/observability.tsnow prefers#observabilitySlot, falls back to the old#obsSlotonly for older shells, and usesexepert.obsCollapsed.v2so the activity-page panel defaults to expanded.css/app.cssadds the dark model popover, selected/active row states, responsive badge behavior, Observability workbench view rules, and the wider Trace Ingestion page layout.
User impact
- Opening the Chat model picker no longer shows a white operating-system dropdown in the dark UI.
- Codex and Claude models from 9Router are searchable and grouped by provider.
- Chat keeps its full vertical space because Trace Ingestion is no longer mounted under the chat tile.
- The Observability activity icon now opens a focused Trace Ingestion page with the existing import, sample, trace viewer, live, project, Supabase status, and summary controls.
Verification
Checked locally with:
pnpm typecheck
pnpm build
The browser smoke test confirmed that the menu listed 25 models, filtering
worked for Claude models, keyboard selection worked, a chat request used the
selected cx/gpt-5.4 model, and #obs-panel mounted inside
#observabilitySlot rather than the Chat area.