deep-chat
deep-chat copied to clipboard
how to update current bubble with a stream of characters and not use overwrite?
If I want to call a WebSocket stream and get a response back in chunks, the cheat way is to set overwrite=true. is there a way to correlate the request with the response for the current bubble so that the stream updates the current bubble only using your framework. I could just use a standard observable variable and tie it to the bubble, but not sure I have access to your internal code for that without changing it. thoughts? what am I missing?
Hi @MTCMarkFranco.
You can facilitate a steam-like experience when using sockets via the stream
property by assigning it a string that servers as an end-phrase. This is mentioned and documented in more detail in the following issue.
I can see that you are using a request handler which is not supported for the aforementioned solution. If you want to continue to use the handler - I have made a quick change in the the latest deep-chat-dev
and deep-chat-react-dev
packages version 9.0.144
which will allow you to do this. The only issue is that the dev packages have accrued quite a lot of changes for our next big release, hence whilst things will continue work, you might get quite a few warnings in the console to switch to the new properties. E.g. the request
property has been renamed to connect
and stream
has been moved to the connect
object. Here is a very quick example of how you would use the new connect
property:
connect = {
handler: (_, signals) => {
signals.onOpen();
setTimeout(() => {
signals.onResponse({text: '1'});
setTimeout(() => {
signals.onResponse({text: '2'});
setTimeout(() => {
signals.onResponse({text: '3'});
setTimeout(() => {
signals.onResponse({text: 'end'});
}, 500);
}, 500);
}, 500);
}, 500);
},
websocket: true,
stream: {simulation: 'end'},
}
Let me know if you have any questions. It is late where I currently live, hence I will be able to respond later tomorrow. Thanks!
Thank you, I've updated my component and packages, but it seems it is even worse now, that overwrite is not honoured anymore as well. here is my code: https://github.com/MTCMarkFranco/chatbot/blob/websockets/src/App.tsx
Line 68
any suggestion on how to modify my code? I really want the stream effect from the server via websockets.
Appreciate it :-)
Hey @MTCMarkFranco.
I just found out that the end-phrase did not work for html
messages, I have updated this in version 9.0.145
.
I have briefly looked at your code and have to say there is quite a lot of it, and the problem is I can't really reproduce it on my machine. Hence, the best thing I can recommend you is to temporarily remove/comment out code until you see where the problems start occurring. Then comment a simplified example so I can try to reproduce it locally on my machine.
I would best advise starting with this simple handler's signals example and incrementally moving up to your solution:
connect = {
websocket: true,
stream: {simulation: 'end'},
handler: (_, signals) => {
signals.onOpen();
setTimeout(() => {
signals.onResponse({html: '<div>div 1</div>'});
setTimeout(() => {
signals.onResponse({html: '<button>button 2</button>'});
setTimeout(() => {
signals.onResponse({html: '<span>span 3</span>'});
setTimeout(() => {
signals.onResponse({html: 'end'});
setTimeout(() => {
signals.onResponse({text: 'New message'});
}, 500);
}, 500);
}, 500);
}, 500);
}, 500);
},
};
This is as much as I can currently do unfortunately from my machine, but please let me know where can I assist as I am keen to help you solve your problem.
Thankyou!
Thank you!
My code structure follows your WebSocket skeleton code verbatim here: https://deepchat.dev/docs/connect/#Handler
// this handler is invoked when the component is loaded chatElementRef.request = { websocket: true, handler: (_, signals) => { try { const websocket = new WebSocket('custom-url'); websocket.onopen = () => { signals.onOpen(); // enables the user to send messages }; websocket.onmessage = (message) => { const response = JSON.parse(message.data); signals.onResponse(response); // displays a text message from the server }; websocket.onclose = () => { signals.onClose(); // stops the user from sending messages }; websocket.onerror = () => { // 'Connection error' is a special string that will also display in Deep Chat signals.onResponse({error: 'Connection error'}); }; // triggered when the user sends a message signals.newUserMessage.listener = (body) => { websocket.send(JSON.stringify(body)); }; } catch (e) { signals.onResponse({error: 'error'}); // displays an error message signals.onClose(); // stops the user from sending messages } }, };
further investigation: signals.onResponse() is thinking that every call should be a separate response hence it creates a new message in the messages list instead of updating the latest response message. Maybe for stream=true, you could set a condition to update instead of create a new message? I haven't looked at your internal code yet, but just an idea.
Apologies for the late reply @MTCMarkFranco.
That is quite interesting. I'm scratching my head as to why your signals.onResponse() call creates a new message bubble. In terms of debugging your code, I would recommend removing/commenting-out as much as possible to get to the cause of your issues.
If you use the configuration I pasted above, each call for signals.onResponse() should be incrementally adding to a message bubble, hence I am not sure as to why your case is creating a new message bubble every time. Perhaps I have misunderstood something.
Just to double check, which version of deep-chat-react-dev
are you using?
Any more info would be greatly appreciated!
Hi, the code discussed in this issue is now available in Deep Chat version 2.0.0
. The documentation for this has also been updated in the official documentation's stream
page.