handleBotUtterance()

in src/components/Widget/index.js [278:332]


  handleBotUtterance(botUtterance) {
    const { dispatch, isChatOpen } = this.props;
    this.clearCustomStyle();
    this.eventListenerCleaner();
    dispatch(clearMetadata());

    // Handle is_final parameter for bot processing state
    // If is_final is explicitly set to false, keep WIP active
    // If is_final is explicitly set to true or missing, hide WIP after message is shown
    const isFinal = botUtterance.metadata?.is_final ?? botUtterance.is_final ?? true;

    logger.debug('handleBotUtterance:', {
      text: botUtterance.text?.substring(0, 50),
      isFinal,
      isChatOpen
    });

    // Store last is_final value to check in newMessageTimeout
    this.lastIsFinal = isFinal;

    // If chat is not open, message is displayed immediately without delay
    // So we can set isBotProcessing based on is_final immediately
    // If chat is open, message will have delay, so keep WIP active until message is shown
    if (!isChatOpen) {
      dispatch(setBotProcessing(!isFinal));
      if (isFinal) {
        // Clear timeout when receiving final message
        clearBotProcessingTimeout();
      } else {
        // Start timeout when receiving non-final message
        startBotProcessingTimeout(dispatch);
      }
    } else if (!isFinal) {
      // If not final and chat is open, keep showing WIP
      dispatch(setBotProcessing(true));
      // Start timeout when receiving non-final message
      startBotProcessingTimeout(dispatch);
    } else {
      // If final and chat is open, clear the timeout (WIP will be hidden after message delay)
      clearBotProcessingTimeout();
    }
    // If isFinal and chat is open, WIP will be hidden after message delay in newMessageTimeout

    if (botUtterance.metadata) this.propagateMetadata(botUtterance.metadata);

    // Fix: Convert \n to hard breaks (2 spaces + \n) for proper Markdown rendering
    // This ensures single line breaks are preserved in the output
    const fixedText = String(botUtterance.text).replace(/\n/g, '  \n');

    const newMessage = { ...botUtterance, text: fixedText };
    if (botUtterance.metadata && botUtterance.metadata.customCss) {
      newMessage.customCss = botUtterance.metadata.customCss;
    }
    this.handleMessageReceived(newMessage);
  }