- Add tokio watch channel for cancellation signaling - Implement cancel_chat command - Add cancellation checks in streaming loop and before tool execution - Stop button (■) replaces Send button (↑) during generation - Preserve partial streaming content when cancelled - Clean UX: no error messages on cancellation - Backend properly stops streaming and prevents tool execution Closes Story 13
3.6 KiB
3.6 KiB
Story 14: New Session Cancellation
User Story
As a User I want the backend to stop processing when I start a new session So that tools don't silently execute in the background and streaming doesn't leak into my new session
The Problem
Current Behavior (THE BUG):
- User sends message → Backend starts streaming → About to execute a tool (e.g.,
write_file) - User clicks "New Session" and confirms
- Frontend clears messages and UI state
- Backend keeps running → Tool executes → File gets written → Streaming continues
- Streaming tokens appear in the new session
- User has no idea these side effects occurred in the background
Why This Is Critical:
- Tool calls have real side effects (file writes, shell commands, searches)
- These happen silently after user thinks they've started fresh
- Streaming from old session leaks into new session
- Can cause confusion, data corruption, or unexpected system state
- User expects "New Session" to mean a clean slate
Acceptance Criteria
- Clicking "New Session" and confirming cancels any in-flight backend request
- Tool calls that haven't started yet are NOT executed
- Streaming from old request does NOT appear in new session
- Backend stops processing immediately when cancellation is triggered
- New session starts with completely clean state
- No silent side effects in background after new session starts
Out of Scope
- Stop button during generation (that's Story 13)
- Improving the confirmation dialog (already done in Story 20)
- Rolling back already-executed tools (partial work stays)
Implementation Approach
Backend
- Uses same
cancel_chatcommand as Story 13 - Same cancellation mechanism (tokio::select!, watch channel)
Frontend
- Call
invoke("cancel_chat")BEFORE clearing UI state inclearSession() - Wait for cancellation to complete before clearing messages
- Ensure old streaming events don't arrive after clear
Testing Strategy
-
Test Tool Call Prevention:
- Send message that will use tools (e.g., "search all TypeScript files")
- Click "New Session" while it's thinking
- Confirm in dialog
- Verify tool does NOT execute (check logs/filesystem)
- Verify new session is clean
-
Test Streaming Leak Prevention:
- Send message requesting long response
- While streaming, click "New Session" and confirm
- Verify old streaming stops immediately
- Verify NO tokens from old request appear in new session
- Type new message and verify only new response appears
-
Test File Write Prevention:
- Ask to write a file: "Create test.txt with current timestamp"
- Click "New Session" before tool executes
- Check filesystem: test.txt should NOT exist
- Verify no background file creation happens
Success Criteria
Before (BROKEN):
User: "Search files and write results.txt"
Backend: Starts streaming...
User: *clicks New Session, confirms*
Frontend: Clears UI ✓
Backend: Still running... executes search... writes file... ✗
Result: File written silently in background ✗
Old streaming tokens appear in new session ✗
After (FIXED):
User: "Search files and write results.txt"
Backend: Starts streaming...
User: *clicks New Session, confirms*
Frontend: Calls cancel_chat, waits, then clears UI ✓
Backend: Receives cancellation, stops immediately ✓
Backend: Tools NOT executed ✓
Result: Clean new session, no background activity ✓
Related Stories
- Story 13: Stop Button (shares same backend cancellation mechanism)
- Story 20: New Session confirmation dialog (UX for triggering this)
- Story 18: Streaming Responses (must not leak between sessions)