Frontend chat view — message rendering & input #15

Open
opened 2026-04-16 11:31:36 +00:00 by claude-desktop · 0 comments
Collaborator

User story

As a user chatting with an AI agent, I want the chat view to render messages with Markdown formatting and syntax-highlighted code blocks, stream assistant responses in real-time, display tool calls as collapsible widgets, and provide a text input area with send functionality, so that I have a rich, responsive chat experience.

Acceptance criteria

ChatViewModel (RELM4 component, components/chat_view.rs)

  • Displays all messages for the active thread's turns (from read model)
  • Auto-scrolls to the latest message
  • Shows a spinner/indicator when the agent is running (ThreadStatus::Running)

Message rendering

  • MessageContent::Text — parsed as Markdown:
    • Inline text rendered via gtk::Label with Pango markup (markdown_to_pango() helper)
    • Code blocks rendered via sourceview5::View with syntax highlighting (language detection from fence)
    • sourceview5::View is read-only with line numbers enabled
  • MessageContent::ToolCall — collapsible widget showing tool name and JSON input
  • MessageContent::ToolResult — shown inline, errors highlighted in red
  • MessageContent::ThinkingBlock — rendered in a distinct visual style (muted, collapsible)
  • User messages vs assistant messages have distinct visual alignment/styling

Streaming

  • MessageChunkReceived events append text to the current assistant message in real-time
  • No full re-render on each chunk — incremental text append

Message input

  • GtkTextView (multi-line) at the bottom of the chat view
  • Ctrl+Return sends the message (dispatches StartTurn command)
  • Return inserts a newline (multi-line input)
  • Input is disabled when thread is running or in AwaitingApproval state
  • Clear input after sending

Supervised mode

  • When ThreadStatus::AwaitingApproval: show Approve/Reject buttons
  • Approve dispatches ApprovePendingAction, Reject dispatches RejectPendingAction

Tests

  • Test: markdown_to_pango converts basic markdown (bold, italic, inline code, links)
  • Test: code block extraction from markdown text produces correct language + code pairs
  • Test: chat view renders correct number of message widgets from read model

Out of scope

  • Image/attachment rendering (post-v1)
  • Message editing or deletion

References

  • Spec §10.3 (ChatView — rendu des messages)
  • Spec Annexe A (streaming flow)

Dependencies

  • Blocked by: #4 (MessageContent + ThreadStatus types), #13 (AppModel, AppMsg)
  • Blocks: none (v0.1 leaf)
  • Branch off: issue-13-app-shell
  • Full graph: #21
## User story As a **user chatting with an AI agent**, I want the chat view to render messages with Markdown formatting and syntax-highlighted code blocks, stream assistant responses in real-time, display tool calls as collapsible widgets, and provide a text input area with send functionality, so that I have a rich, responsive chat experience. ## Acceptance criteria ### ChatViewModel (RELM4 component, `components/chat_view.rs`) - [ ] Displays all messages for the active thread's turns (from read model) - [ ] Auto-scrolls to the latest message - [ ] Shows a spinner/indicator when the agent is running (ThreadStatus::Running) ### Message rendering - [ ] `MessageContent::Text` — parsed as Markdown: - Inline text rendered via `gtk::Label` with Pango markup (`markdown_to_pango()` helper) - Code blocks rendered via `sourceview5::View` with syntax highlighting (language detection from fence) - `sourceview5::View` is read-only with line numbers enabled - [ ] `MessageContent::ToolCall` — collapsible widget showing tool name and JSON input - [ ] `MessageContent::ToolResult` — shown inline, errors highlighted in red - [ ] `MessageContent::ThinkingBlock` — rendered in a distinct visual style (muted, collapsible) - [ ] User messages vs assistant messages have distinct visual alignment/styling ### Streaming - [ ] `MessageChunkReceived` events append text to the current assistant message in real-time - [ ] No full re-render on each chunk — incremental text append ### Message input - [ ] `GtkTextView` (multi-line) at the bottom of the chat view - [ ] `Ctrl+Return` sends the message (dispatches `StartTurn` command) - [ ] `Return` inserts a newline (multi-line input) - [ ] Input is disabled when thread is running or in AwaitingApproval state - [ ] Clear input after sending ### Supervised mode - [ ] When `ThreadStatus::AwaitingApproval`: show Approve/Reject buttons - [ ] Approve dispatches `ApprovePendingAction`, Reject dispatches `RejectPendingAction` ### Tests - [ ] Test: markdown_to_pango converts basic markdown (bold, italic, inline code, links) - [ ] Test: code block extraction from markdown text produces correct language + code pairs - [ ] Test: chat view renders correct number of message widgets from read model ## Out of scope - Image/attachment rendering (post-v1) - Message editing or deletion ## References - Spec §10.3 (ChatView — rendu des messages) - Spec Annexe A (streaming flow) ## Dependencies - **Blocked by:** #4 (MessageContent + ThreadStatus types), #13 (AppModel, AppMsg) - **Blocks:** none (v0.1 leaf) - **Branch off:** `issue-13-app-shell` - **Full graph:** #21
claude-desktop added this to the v0.1.0 milestone 2026-04-16 11:31:36 +00:00
Sign in to join this conversation.
No description provided.