Implemented Story 8: Collapsible Tool Outputs - Tool outputs now render in <details>/<summary> elements, collapsed by default - Summary shows tool name with key argument (e.g., ▶ read_file(src/main.rs)) - Added arrow rotation animation and scrollable content (max 300px) - Enhanced tool_calls display to show arguments inline - Added CSS styling for dark theme consistency Fixed: LLM autonomous coding behavior - Strengthened system prompt with explicit examples and directives - Implemented triple-reinforcement system (primary prompt + reminder + message prefixes) - Improved tool descriptions to be more explicit and action-oriented - Increased MAX_TURNS from 10 to 30 for complex agentic workflows - Added debug logging for Ollama requests/responses - Result: GPT-OSS (gpt-oss:20b) now successfully uses write_file autonomously Documentation improvements - Created MODEL_SELECTION.md guide with recommendations - Updated PERSONA.md spec to emphasize autonomous agent behavior - Updated UI_UX.md spec with collapsible tool output requirements - Updated SDSW workflow: LLM archives stories and performs squash merge Cleanup - Removed unused ToolTester.tsx component
3.1 KiB
Functional Spec: UI/UX Responsiveness
Problem
Currently, the chat command in Rust is an async function that performs a long-running, blocking loop (waiting for LLM, executing tools). While Tauri executes this on a separate thread from the UI, the frontend awaits the entire result before re-rendering. This makes the app feel "frozen" because there is no feedback during the 10-60 seconds of generation.
Solution: Event-Driven Feedback
Instead of waiting for the final array of messages, the Backend should emit Events to the Frontend in real-time.
1. Events
chat:token: Emitted when a text token is generated (Streaming text).chat:tool-start: Emitted when a tool call begins (e.g.,{ tool: "git status" }).chat:tool-end: Emitted when a tool call finishes (e.g.,{ output: "..." }).
2. Implementation Strategy (MVP)
For this story, we won't fully implement token streaming (as reqwest blocking/async mixed with stream parsing is complex). We will focus on State Updates:
- Refactor
chatcommand:- Instead of returning
Vec<Message>at the very end, it accepts aAppHandle. - Inside the loop, after every step (LLM response, Tool Execution), emit an event
chat:updatecontaining the current partial history. - The Frontend listens to
chat:updateand re-renders immediately.
- Instead of returning
3. Visuals
- Loading State: The "Send" button should show a spinner or "Stop" button.
- Auto-Scroll: The chat view should stick to the bottom as new events arrive.
Tool Output Display
Problem
Tool outputs (like file contents, search results, or command output) can be very long, making the chat history difficult to read. Users need to see the Agent's reasoning and responses without being overwhelmed by verbose tool output.
Solution: Collapsible Tool Outputs
Tool outputs should be rendered in a collapsible component that is closed by default.
Requirements
- Default State: Tool outputs are collapsed/closed when first rendered
- Summary Line: Shows essential information without expanding:
- Tool name (e.g.,
read_file,exec_shell) - Key arguments (e.g., file path, command name)
- Format: "▶ tool_name(key_arg)"
- Example: "▶ read_file(src/main.rs)"
- Example: "▶ exec_shell(cargo check)"
- Tool name (e.g.,
- Expandable: User can click the summary to toggle expansion
- Output Display: When expanded, shows the complete tool output in a readable format:
- Use
<pre>or monospace font for code/terminal output - Preserve whitespace and line breaks
- Limit height with scrolling for very long outputs (e.g., max-height: 300px)
- Use
- Visual Indicator: Clear arrow or icon showing collapsed/expanded state
- Styling: Consistent with the dark theme, distinguishable from assistant messages
Implementation Notes
- Use native
<details>and<summary>HTML elements for accessibility - Or implement custom collapsible component with proper ARIA attributes
- Tool outputs should be visually distinct (border, background color, or badge)
- Multiple tool calls in sequence should each be independently collapsible