# Web App: workspace-grouped sidebar, key-aware model picker, chat rendering, letter avatars

## Sidebar groups by Workspace

The chat sidebar now groups conversations by Workspace by default, with a persisted toggle to switch back to Agent grouping. Workspace groups are labeled by the directory's basename (full path in the tooltip), ordered by their newest session; auto-created temp workspaces (`workspaces/tmp-<8hex>`) collapse into a single "Temp workspaces" group instead of one group per session. Each workspace header's "+" starts a new conversation pre-filled with that workspace; rows in workspace mode carry a small agent avatar so the agent context stays visible. Group collapse state persists per Project across reloads. Agent mode is unchanged.

Groups gained polish and structure since: headers share one consistent hover height, the workspace folder icon opens and closes with the group, and both grouping modes support pinning groups to the top (persisted per Project). Sessions created by subagents and by scheduled tasks file into two collapsed folders — Subagents and Scheduled — parallel to Archived inside each group, and each group lists at most a page of sessions with a More row that loads further pages on demand (the session-list API gained `limit`/`offset` so the sidebar never fetches unbounded lists).

## Model picker lists configured models first

The chat model dropdown shows only models with a configured API key (a stored, masked key — an env-var name alone doesn't count) and a muted bottom row reveals the rest on demand, each marked with a key-with-slash icon (the localized label kept for assistive tech). The selected model and the project default are always visible, and when no model has a key yet the dropdown falls back to showing everything rather than rendering empty.

## Letter avatars for custom model groups and Agents

User-defined model provider groups all shared one generic icon, making same-named models across groups hard to tell apart in the model picker. Custom groups now render an initial-letter tile — the name's first grapheme on a softly tinted background derived from the name, with theme-aware colored ink that holds WCAG AA contrast in both light and dark mode — so each group keeps a stable, distinct look. Agent avatars adopt the same treatment, with the color keyed to the agent id so renames keep the color.

## Collapsed rail navigation

The collapsed sidebar is now a full navigation rail with eight entries in a fixed order — last conversation (the Project's newest non-archived session; disabled only when none exists, not while loading), new chat, Agents, Skills, Models, Costs, Traces, and Benchmark (previously missing) — each with bilingual hover tooltips, and a rail-level active highlight for any open conversation.

## Cost center tooltips

The daily-token chart's hover bubble follows the pointer at a lower-right offset, flipping near the edges so it never covers the hovered mark or clips; pointer moves position it imperatively (no re-render per mousemove). The Cache Read segment's bubble additionally shows the cache hit rate — cache reads over reads plus writes — computed and labeled identically to the Trace page's existing hit rate.

## Settings forms

In the model detail dialog, context window and max output tokens sit side by side with the Token unit inside each box and the explanation as placeholder plus hover tooltip; the model homepage moved to the dialog header as a button; the three price fields carry self-contained labels with no heading row; and vision support became an iPhone-style switch with no explanation text. Agent settings' runtime dropdowns no longer offer a default row — a reset link restores the inherited state instead — and all dropdowns render at the same text size as inputs.

## Copied task stats are localized

The per-task stats line produced by the copy-message action was hardcoded Chinese; it now goes through the dictionaries like every other UI string, so English sessions copy English stats.

## Chat message rendering

Links in chat messages always open in a new tab (`target="_blank" rel="noreferrer"`), covering explicit links and GFM autolinked bare URLs alike. The expanded subagent conversation now renders below the tool call's own arguments and output instead of above them, and every chat dropdown stays inside the viewport on mobile (three panels used to overflow by up to 143px, one of them side-scrolling the whole page). Long URLs and inline-code tokens wrap with `overflow-wrap: anywhere` — they break at the container edge without ever splitting ordinary Latin words inside CJK prose — and wide tables scroll inside the message instead of widening the page, matching the docs site's rule. The streaming pipeline's stable component maps are preserved, so code blocks keep their selection and copy state while a reply streams.
