Skip to content

Composer input not cleared immediately when streaming starts #167

@JerryPeace

Description

@JerryPeace

Description

When using streaming mode, the composer textarea is not cleared immediately after the user submits a message. The input only gets cleared after the entire stream completes, which creates a confusing UX where users see their message still in the input box while waiting for the AI response.

Expected Behavior

The composer input should be cleared immediately when the message is sent (or when the stream starts), similar to how batch mode works.

Current Behavior

In streaming mode, the input remains visible until observer.complete() is called, which can take several seconds depending on the response length.

Root Cause Analysis

Looking at the source code in packages/js/core/src/sections/chat/chatRoom/actions/submitPrompt.ts:

Batch mode (line ~108):

result.observable.on('aiMessageReceived', (aiMessage) => {
    // ...
    resetComposer(true);  // ✅ Clears input immediately
});

Streaming mode (line ~111-152):

result.observable.on('aiMessageStreamStarted', (aiMessageStream) => {
    conversation.addChatItem(segmentId, aiMessageStream);
    setComposerAsWaiting();  // ❌ Only sets status, doesn't clear input
    context.emit('messageStreamStarted', {uid: aiMessageStream.uid});
});

// ...

result.observable.on('complete', () => {
    conversation.completeChatSegment(segmentId);
    resetComposer(false);  // ❌ Passes false, so input is not cleared
});

The resetComposer function in chatRoom.model.ts (line ~365-380) only clears the input when resetTextInput is true:

private resetComposer(resetTextInput: boolean = false, focusOnReset: boolean = false) {
    // ...
    if (resetTextInput) {
        newProps.message = '';  // Only clears when resetTextInput=true
    }
    // ...
}

Suggested Fix

Change line ~113 in submitPrompt.ts from:

setComposerAsWaiting();

to:

resetComposer(true);

This will clear the input immediately when the stream starts, providing a better user experience.

Workaround

Currently using DOM manipulation as a workaround:

const handleMessageSent = useCallback<MessageSentCallback>(() => {
    const textarea = document.querySelector('.nlux-comp-composer textarea') as HTMLTextAreaElement;
    if (textarea) {
        textarea.value = '';
    }
}, []);

<AiChat 
    events={{ messageSent: handleMessageSent }}
    // ...
/>

Environment

  • @nlux/react: ^2.17.1
  • React: ^19.1.1
  • Browser: Chrome/Edge

Additional Context

This is a UX issue that affects all streaming implementations. Users expect the input to be cleared once they submit, not after the response completes.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions