OpenFn / OpenFn/lightning

AI assistant: send button becomes a stop button to cancel in-flight messages

Open
#4,783 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

AI feature enhancement ux/ui improvement
Dominant language
Elixir
Stars
296
Forks
86
Avg merge
1d 13h
Merged PRs (30d)
50

Description

What's missing

When a user sends a message to the AI assistant, there's no way to cancel the request before it completes. If the user changes their mind (wrong prompt, too slow, want to reword), they have to wait for the response or close the tab. The send button is just disabled during processing, with no escape hatch.

Why it's needed

Every consumer-grade AI chat tool today follows the same pattern: the send button transforms into a stop button while a response is in flight. Cancelling restores the input and lets the user type a corrected prompt without losing context. Adding it brings our AI assistant in line with the interaction model users already know from Claude Desktop, ChatGPT, Cursor, and others.

Real cases where this matters:

  • User realises mid-request they sent the wrong prompt.
  • Apollo is taking unusually long and the user wants to abandon.
  • User typed the prompt for the wrong job or session and wants to redirect.

What to build

Same-position button that swaps icon based on isLoading:

  • Idle: send icon (current behaviour). Click sends.
  • In-flight: stop icon. Click sends a new cancel_message channel event with the message id.

Server side:

  • AiAssistantChannel handles cancel_message, calls Oban.cancel_job/1 on the running Oban job, then AiAssistant.cancel_message/1 flips the row to :cancelled and broadcasts.
  • :cancelled status is already defined in the ChatMessage schema, so no migration needed.

Client side:

  • ChatInput reads isLoading to render the right icon, sends either new_message or cancel_message.
  • On :cancelled broadcast, the store clears isLoading, the cancelled user message stays visible in the transcript with a small "cancelled" tag.

Open questions

  • After cancelling, does the user's input get pre-populated with the cancelled prompt so they can edit and resend, or left empty?
  • Race: if Apollo has already finished generating but Lightning has not flushed the response to the client when the user cancels, do we discard the response or save it as :success? Discarding is simpler; saving is closer to what Claude Desktop does.
  • Keyboard shortcut: Esc to cancel? Conventional but might conflict with other editor shortcuts.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by tracing the AiAssistantChannel, ChatInput, ChatMessage schema, and AiAssistant.cancel_message/1 entry points, including the existing Oban job handling. Implement the loading-state button swap and cancellation flow, then verify that cancellation clears loading state, broadcasts the cancelled status, and keeps the cancelled message visible with its tag.

Written by the indexing model from the issue text.

Assessment

Tech stack
elixir
Domain
ai, backend, frontend
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.