82 lines
2.9 KiB
Markdown
82 lines
2.9 KiB
Markdown
|
|
# Story 13: Stop Button
|
||
|
|
|
||
|
|
## User Story
|
||
|
|
**As a** User
|
||
|
|
**I want** a Stop button to cancel the model's response while it's generating
|
||
|
|
**So that** I can immediately stop long-running or unwanted responses without waiting for completion
|
||
|
|
|
||
|
|
## The Problem
|
||
|
|
|
||
|
|
**Current Behavior:**
|
||
|
|
- User sends message → Model starts generating
|
||
|
|
- User realizes they don't want the response (wrong question, too long, etc.)
|
||
|
|
- **No way to stop it** - must wait for completion
|
||
|
|
- Tool calls will execute even if user wants to cancel
|
||
|
|
|
||
|
|
**Why This Matters:**
|
||
|
|
- Long responses waste time
|
||
|
|
- Tool calls have side effects (file writes, searches, shell commands)
|
||
|
|
- User has no control once generation starts
|
||
|
|
- Standard UX pattern in ChatGPT, Claude, etc.
|
||
|
|
|
||
|
|
## Acceptance Criteria
|
||
|
|
|
||
|
|
- [ ] Stop button (⬛) appears in place of Send button (↑) while model is generating
|
||
|
|
- [ ] Clicking Stop immediately cancels the backend request
|
||
|
|
- [ ] Tool calls that haven't started yet are NOT executed after cancellation
|
||
|
|
- [ ] Streaming stops immediately
|
||
|
|
- [ ] Partial response generated before stopping remains visible in chat
|
||
|
|
- [ ] Stop button becomes Send button again after cancellation
|
||
|
|
- [ ] User can immediately send a new message after stopping
|
||
|
|
- [ ] Input field remains enabled during generation
|
||
|
|
|
||
|
|
## Out of Scope
|
||
|
|
- Escape key shortcut (can add later)
|
||
|
|
- Confirmation dialog (immediate action is better UX)
|
||
|
|
- Undo/redo functionality
|
||
|
|
- New Session flow (that's Story 14)
|
||
|
|
|
||
|
|
## Implementation Approach
|
||
|
|
|
||
|
|
### Backend
|
||
|
|
- Add `cancel_chat` command callable from frontend
|
||
|
|
- Use `tokio::select!` to race chat execution vs cancellation signal
|
||
|
|
- Check cancellation before executing each tool
|
||
|
|
- Return early when cancelled (not an error - expected behavior)
|
||
|
|
|
||
|
|
### Frontend
|
||
|
|
- Replace Send button with Stop button when `loading` is true
|
||
|
|
- On Stop click: call `invoke("cancel_chat")` and set `loading = false`
|
||
|
|
- Keep input enabled during generation
|
||
|
|
- Visual: Make Stop button clearly distinct (⬛ or "Stop" text)
|
||
|
|
|
||
|
|
## Testing Strategy
|
||
|
|
|
||
|
|
1. **Test Stop During Streaming:**
|
||
|
|
- Send message requesting long response
|
||
|
|
- Click Stop while streaming
|
||
|
|
- Verify streaming stops immediately
|
||
|
|
- Verify partial response remains visible
|
||
|
|
- Verify can send new message
|
||
|
|
|
||
|
|
2. **Test Stop Before Tool Execution:**
|
||
|
|
- Send message that will use tools
|
||
|
|
- Click Stop while "thinking" (before tool executes)
|
||
|
|
- Verify tool does NOT execute (check logs/filesystem)
|
||
|
|
|
||
|
|
3. **Test Stop During Tool Execution:**
|
||
|
|
- Send message with multiple tool calls
|
||
|
|
- Click Stop after first tool executes
|
||
|
|
- Verify remaining tools do NOT execute
|
||
|
|
|
||
|
|
## Success Criteria
|
||
|
|
|
||
|
|
**Before:**
|
||
|
|
- User sends message → No way to stop → Must wait for completion → Frustrating UX
|
||
|
|
|
||
|
|
**After:**
|
||
|
|
- User sends message → Stop button appears → User clicks Stop → Generation cancels immediately → Partial response stays → Can send new message
|
||
|
|
|
||
|
|
## Related Stories
|
||
|
|
- Story 14: New Session Cancellation (same backend mechanism, different trigger)
|
||
|
|
- Story 18: Streaming Responses (Stop must work with streaming)
|