Skip to content

fix(chat): show "User has stopped generation" indicator when user cancels #7312

Merged
nmgarza5 merged 1 commit intomainfrom
nik/eng-3192-stop-generation-indicator
Jan 9, 2026
Merged

fix(chat): show "User has stopped generation" indicator when user cancels #7312
nmgarza5 merged 1 commit intomainfrom
nik/eng-3192-stop-generation-indicator

Conversation

@nmgarza5
Copy link
Copy Markdown
Contributor

@nmgarza5 nmgarza5 commented Jan 9, 2026

Description

Shows "User has stopped generation" indicator when user clicks the stop button during chat generation. The indicator persists when navigating away and back to the conversation.

Changes

  • Pass stopReason through message component rendering pipeline
  • Display indicator in MessageTextRenderer when generation was user-cancelled
  • Backend: detect user-stopped messages when loading saved conversations and set stop_reason in packets

How Has This Been Tested?

  • Stop generation during streaming → indicator appears
  • Stop during deep research → indicator appears
  • Navigate away and back → indicator persists
Screenshot 2026-01-09 at 9 43 58 AM

text below is italicized but that has been removed
2026-01-09 09 23 22

Additional Options

Closes https://linear.app/onyx-app/issue/ENG-3192/show-correct-killed-state-for-user-stopping-generation

  • [Optional] Override Linear Check

Summary by cubic

Show a clear “User has stopped generation” indicator when a user cancels a chat response, and persist it when returning to the conversation. Addresses ENG-3192.

  • Bug Fixes
    • Backend sets stop_reason=user_cancelled on OverallStop when loading saved conversations.
    • UI passes stopReason to renderers and shows “User has stopped generation” instead of the blinking dot when cancelled.
    • Indicator persists across navigation and during deep research streaming.

Written for commit 3624763. Summary will update on new commits.

@nmgarza5 nmgarza5 requested a review from a team as a code owner January 9, 2026 17:30
…cels

- Add stopReason prop to MessageRenderer type
- Pass stopReason through RendererComponent
- Display "User has stopped generation" text when user clicks stop button

Previously only a blinking dot was shown. Now users see clear feedback
that generation was stopped by their action.

Fixes ENG-3192
@nmgarza5 nmgarza5 force-pushed the nik/eng-3192-stop-generation-indicator branch from b975fe9 to 3624763 Compare January 9, 2026 17:31
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cubic analysis

No issues found across 6 files

Linked issue analysis

Linked issue: ENG-3192: Show correct killed state for user stopping generation

Status Acceptance criteria Notes
Show "User has stopped generation" indicator when user clicks stop during generation AIMessage renders Text when stopReason==USER_CANCELLED
Indicator persists when navigating away and back to the conversation (saved convo load) session_loading sets OverallStop with stop_reason for loaded messages
Pass stopReason through message component rendering pipeline MessageRenderer and RendererComponent accept and forward stopReason
Display indicator in MessageTextRenderer when generation was user-cancelled MessageTextRenderer appends 'User has stopped generation' when wasUserCancelled
Backend: detect user-stopped messages when loading saved conversations and set stop_reason in packets session_loading checks message text and sets stop_reason on OverallStop packet
Replace blinking dot with stopped text when cancelled and no display content AIMessage shows stopped Text when grouped/display content empty and stopped
Update generation-stopped message text so detection works when building saved messages process_message text changed to include 'Generation was stopped' phrase

Copy link
Copy Markdown
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Greptile Overview

Greptile Summary

This PR adds a "User has stopped generation" indicator that appears when users cancel AI message generation and persists when navigating away and back to the conversation.

Implementation approach:

Frontend (web/):

  • Threads stopReason through the component hierarchy from AIMessage → RendererComponent → MessageTextRenderer
  • Extracts stop_reason from Stop packets and stores it in component state
  • Conditionally renders "User has stopped generation" text when stopReason === StopReason.USER_CANCELLED
  • Shows indicator in multiple places: when no content exists, when display groups are empty, and at the end of message text

Backend (backend/):

  • During streaming: appends "Generation was stopped by the user." to the message when user cancels
  • When loading saved conversations: uses string matching ("Generation was stopped" in message) to detect previously cancelled messages and sets stop_reason="user_cancelled" in the OverallStop packet

Key architectural decision:
Rather than storing stop_reason in the database, the implementation infers it from message text when loading saved conversations. This works but is fragile - any change to the exact stop message text will break persistence.

The frontend changes are solid and properly handle all rendering scenarios. The backend detection logic is the main area of concern due to its reliance on string matching.

Confidence Score: 4/5

  • Safe to merge with minor technical debt in the persistence approach
  • The implementation correctly handles the user-cancelled state throughout the streaming and rendering pipeline. Frontend changes properly thread stopReason through components and display the indicator in all relevant scenarios. The main weakness is the backend's string-matching approach for detecting cancelled messages from the database, which is fragile but functional for the current use case. This is technical debt rather than a blocking bug.
  • backend/onyx/server/query_and_chat/session_loading.py - Consider adding a stop_reason field to the database schema for more robust persistence

Important Files Changed

File Analysis

Filename Score Overview
backend/onyx/chat/process_message.py 5/5 Minor text cleanup - changed "The generation was stopped by the user" to "Generation was stopped by the user" for consistency
backend/onyx/server/query_and_chat/session_loading.py 3/5 Added stop_reason detection using string matching on saved messages - fragile approach that depends on exact message text
web/src/app/chat/message/messageComponents/AIMessage.tsx 5/5 Added stopReason prop threading and conditional rendering for "User has stopped generation" indicator
web/src/app/chat/message/messageComponents/interfaces.ts 5/5 Added optional stopReason parameter to MessageRenderer interface
web/src/app/chat/message/messageComponents/renderMessageComponent.tsx 5/5 Thread stopReason through RendererComponent to child renderers
web/src/app/chat/message/messageComponents/renderers/MessageTextRenderer.tsx 5/5 Display "User has stopped generation" indicator when stopReason is USER_CANCELLED

Sequence Diagram

sequenceDiagram
    participant User
    participant Frontend
    participant Backend
    participant DB
    
    Note over User,DB: User Stops Generation During Streaming
    User->>Frontend: Clicks stop button
    Frontend->>Backend: Send stop signal
    Backend->>Backend: Set completed_normally=False
    Backend->>Backend: Append "Generation was stopped by the user."
    Backend->>DB: Save message with stop text
    Backend->>Frontend: Send OverallStop packet with stop_reason="user_cancelled"
    Frontend->>Frontend: setStopReason(USER_CANCELLED)
    Frontend->>Frontend: Render "User has stopped generation" indicator
    
    Note over User,DB: User Returns to Conversation Later
    User->>Frontend: Navigate to conversation
    Frontend->>Backend: Request conversation history
    Backend->>DB: Load chat messages
    DB->>Backend: Return messages
    Backend->>Backend: Check if "Generation was stopped" in message
    Backend->>Backend: Set stop_reason="user_cancelled" in OverallStop packet
    Backend->>Frontend: Send packets with stop_reason
    Frontend->>Frontend: Render "User has stopped generation" indicator
    Frontend->>User: Display persisted indicator
Loading

@nmgarza5 nmgarza5 requested a review from yuhongsun96 January 9, 2026 17:47
Copy link
Copy Markdown
Contributor

@yuhongsun96 yuhongsun96 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@nmgarza5 nmgarza5 added this pull request to the merge queue Jan 9, 2026
Merged via the queue into main with commit dac60d4 Jan 9, 2026
75 checks passed
@nmgarza5 nmgarza5 deleted the nik/eng-3192-stop-generation-indicator branch January 9, 2026 18:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants