OvidijusParsiunas / deep-chat

Fully customizable AI chatbot component for your website
https://deepchat.dev
MIT License
1.26k stars 170 forks source link

Asynchronous responseInterceptor Interfering with Streaming Data Transmission May Cause Rendering Abnormalities #153

Closed buzhou9 closed 3 months ago

buzhou9 commented 3 months ago

If a 'responseInterceptor' is provided as an asynchronous function and the server streams data in segments, if the execution time of the 'responseInterceptor' exceeds the interval between each segment of the streaming data process, due to the event loop execution mechanism of JavaScript, it can result in abnormal message rendering.

Reproduction method

Modify the parameters for streaming data examples in this file

// file url deep-chat/example-servers/nextjs/pages/index.tsx
<DeepChat
  style={{borderRadius: '10px'}}
  introMessage={{text: 'Send a streamed chat message to an example server.'}}
  request={{url: '/api/custom/chat-stream'}}
  stream={true}
  responseInterceptor={async (response: any) => {
    console.log(response);
    await new Promise(resolve => setTimeout(() => resolve(true), 500))
    console.log('return', response)
    return response;
  }}
/>

The complete content of this message is "This is a response from a NextJS server. Thank you for your message!"

demo

OvidijusParsiunas commented 3 months ago

Hi @buzhou9. My apologies for the late response.

What you are seeing is expected behaviour. The responseInterceptor provides an async modifier to allow developers to perform other asynchronous operations before returning the result. Whilst this works perfectly for normal requests, if developers intentionally delay some results - the message bubble will undoubtably also be populated with a delayed output.

The behaviour you expect is not easy to implement and would need an overhaul of the stream functionality. However given that the unwanted behaviour is caused by the developer code, they should be the ones that should make sure the events are being returned in the order that they expect.

Because the responseInterceptor functionality operates the way it needs to, I will be closing this issue. However, if you need any further advice, feel free to comment below.

buzhou9 commented 2 months ago

Thank you, I encountered this issue because the data returned from each stream has a special formatted string that needs to be parsed through an asynchronous function to render correctly. Of course, I have now resolved this issue by transferring the logic of this code to the server's code before streaming back.