# AgentBar polish — capability tips + voice input + unified tool rendering - Date: 2026-06-21 - Surface: `components/edit/AgentPanel/*` (the "Edit with AI" editor sidebar) - Builds on: the editor-agent feature (read_scene_content / regenerate_scene / regenerate_scene_actions) - Status: design approved, pending spec review → implementation plan ## Background Three issues with the current AgentBar: 1. **Stale, chip-driven guidance.** A row of clickable quick-prompt chips sits above the composer (`重新生成讲解旁白 / 让讲解更口语一些 / 加一个生活化类比`), and the empty state says "让 AI 重新生成与内容匹配的讲解旁白" — both still frame the agent as a *narration regenerator*, which is stale: the agent now regenerates the **whole slide** (content + narration) per instruction, reads the slide, etc. The user wants the chips removed and replaced with clearer, read-only **capability tips**. 2. **No voice input.** The composer has no dictation affordance. 3. **Inconsistent tool-call rendering.** Only `regenerate_scene` and `regenerate_scene_actions` have registered tool UIs; `read_scene_content` renders *nothing*, so a turn that reads the slide shows a blank gap between the assistant's "let me look at this page" and its reply. ## Goal Make the AgentBar communicate the agent's real capabilities clearly, support voice input, and render every tool call consistently. ## Scope decisions (locked) | Decision | Choice | |---|---| | Capability guidance placement | **Empty state only** (vanishes once a conversation starts) | | Guidance interactivity | **Pure read-only text** (no clickable examples — not "recommendations") | | Guidance form | **Grouped capability list** — title + lead + 3 labeled rows w/ examples + boundary + "coming soon" closer | | Voice input | **Reuse `SpeechButton` + `useASRAvailable`**, in the composer footer | | Tool rendering | **Shared `ToolCard` shell**; `read_scene_content` gets a light card; generic fallback for unregistered tools | Non-goals: no change to agent capabilities/tools; no per-element @-chips; no model picker; no streaming-reasoning UI. ## Component changes — `components/edit/AgentPanel/` ### 1. Empty-state capability tips (`AgentPanel.tsx`) - **Remove** the `QUICK_PROMPT_KEYS` array and the `` chip row above the composer (the whole `scrollbar-hide … overflow-x-auto` div). - **Replace** the single-line empty hint with a grouped capability list inside the existing `` block: - Title: `有什么想改的?` (reuse `edit.agent.emptyTitle`) - Lead: `告诉我这一页怎么改,我会重做内容并对齐讲解。` - Three capability rows — each a bold/foreground **label** + one or two muted, quoted **examples** (read-only, NOT buttons): - `改内容` — `"精简成 3 个要点"` · `"加个生活化例子"` - `改讲解` — `"讲得更口语一些"` · `"对齐我刚改的画布"` - `问这页` — `"这页重点是什么?"` - Boundary line (muted): `增删 / 排序幻灯片请用左侧导航` - Closer (muted, with a sparkle): `更多能力陆续加入中,敬请期待 ✨` - Visual: left-aligned rows within the existing centered ~260px container; labels `text-foreground`, examples `text-muted-foreground`, small sizes, consistent with the rail's existing type scale. Quoted examples may use the brand-violet faintly to read as "things you can say". ### 2. Voice input button (`AgentPanel.tsx` composer footer) - Import `SpeechButton` (`@/components/audio/speech-button`) and render it in the composer's bottom action row, **left of** the Send/Stop button. - Wire `onTranscription={(text) => appendToComposer(text)}`. The composer uses assistant-ui's `ComposerPrimitive.Input` (not local state), so append via the composer runtime: `useComposerRuntime().setText(currentText + (currentText && !endsWithSpace ? ' ' : '') + text)`. Confirm the exact assistant-ui API (`useComposerRuntime` / `getState().text` / `setText`) against the installed version; fall back to a ref on the underlying `