Skip to content

Add generic Stop and Queue UX for long-running chat turns #38

@chubes4

Description

@chubes4

Problem

@extrachill/chat currently disables the chat input while isLoading is true. That is safe for today’s synchronous backend contract, but it creates a poor UX for long-running agent turns: users cannot stop generation and cannot type the next instruction while the agent is working.

The backend contract gap is tracked in Automattic/agents-api#236. The WordPress REST adapter follow-up is Extra-Chill/frontend-agent-chat#47.

Current behavior

  • useChat.sendMessage() returns early when isLoading is true.
  • ChatInput is rendered with disabled={chat.isLoading}.
  • Message suggestions are disabled while loading.
  • There is no generic cancel or queue UI contract.

Desired behavior

Add optional, backend-agnostic UI hooks for two capabilities:

  1. Stop/cancel the active run.
  2. Queue a follow-up message while the active run is still running.

The package should not assume Agents API specifically; it should expose generic props/API hooks that adapters can wire up.

Proposed API direction

Possible additions to Chat / useChat:

type ChatRunCapabilities = {
  cancel?: boolean;
  queue?: boolean;
};

type ChatProps = {
  runCapabilities?: ChatRunCapabilities;
  onCancelRun?: (runId: string, sessionId: string) => Promise<void>;
  onQueueMessage?: (input: {
    sessionId: string;
    content: string;
    files?: File[];
  }) => Promise<void>;
};

Exact names can change, but the behavior should be:

  • If cancel is available and chat is loading, show a Stop/Cancel control.
  • If queue is available and chat is loading, keep the input usable and send through queue semantics.
  • If neither is available, preserve the current disabled-input behavior.

Acceptance criteria

  • Existing consumers keep current behavior by default.
  • Stop control appears only when cancellation support is supplied.
  • Input remains enabled during loading only when queue support is supplied.
  • Queued messages render optimistically with a queued/pending visual state, or otherwise clearly indicate they are queued.
  • The hook exposes active runId when supplied by the backend adapter.
  • The API is backend-neutral and does not hardcode WordPress or Agents API specifics.
  • Tests or story/demo coverage exists for:
    • no run-control support
    • cancel-only support
    • queue-only support
    • cancel + queue support

Upstream/downstream

AI assistance

  • AI assistance: Yes
  • Tool(s): OpenCode (GPT-5.5)
  • Used for: Drafting the issue from the observed disabled-input UX and upstream contract gap. Chris remains responsible for prioritization and implementation.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions