Files
storkit/.living_spec/stories/archive/13_stop_button.md
Dave e1fb0e3d19 Story 13: Implement Stop button with backend cancellation
- 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
2025-12-27 18:32:15 +00:00

2.9 KiB

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
  • Story 14: New Session Cancellation (same backend mechanism, different trigger)
  • Story 18: Streaming Responses (Stop must work with streaming)