OvidijusParsiunas / deep-chat

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

Is DeepChat's population of chat history only restricted to direct connections and NOT for custom services? #206

Open avibathula opened 1 month ago

avibathula commented 1 month ago

Using the playground feature of DeepChat, I see that chat history is maintained and sent to services. If I ask the service what was my previous question, it was able to tell me. And I think I also checked for them in browser dev-tools' network traces.

I looked into OpenAI wrappers and it looks like you are calling OpenAI's API of List messages.

I wasn't able to figure out how are you doing it for Cohere (I am not much skills at JS/TS).

But when I connect to my own RAG implemented as using FatsAPI, the "messages" list always has one element, the latest message. Why is that?

chat.requestInterceptor = (originalRequest) => {
                const messages = originalRequest.body.messages;                

                // Separate chat history and the current question/message
                const chatHistory = messages.slice(0, -1); // All messages except the last one
                const question = messages[messages.length - 1]; // The last message

                // Update the chat history
                chatHistory = chatHistory.concat(chatHistoryEntries);

                // Create the new payload
                const modifiedPayload = {
                    chat_history: chatHistory,
                    question: question.text,
                };

                // Update the request body with the new payload
                originalRequest.body = modifiedPayload;

                return originalRequest;
            };

Is everyone connecting to customer service expected to "manage + maintain" chat history by themselves?

Is there any way to tap to base implementation of chat history management?

avibathula commented 1 month ago

I ended up writing my own chat-history maintaining logic.

Firstly, not sure how warranted this is. Secondly, I am no JS dev, so not sure if there is any better way to doing this. Looking forwards for any comments from folks with more expertise in this area.

    <script type="module">
        import 'https://unpkg.com/deep-chat@1.4.11/dist/deepChat.bundle.js';

        // Declare a global variable to store chat history and the last message
        let chatHistory = [];

        // Storing the most recent message/question from the user to AI in a separate variable, as we cannot add it to
        // chatHistory global variable in chat.requestInterceptor to prevent the message getting used in the chat-history
        //  as well.
        let lastMessage = null;

        document.addEventListener('DOMContentLoaded', () => {
            const chat = document.getElementById('chat');

            console.log('DOMContentLoaded event fired');

            if (!chat) {
                console.error('DeepChat element not found');
                return;
            }

            // Add initial messages to chat history
            const initialMessages = JSON.parse(chat.getAttribute('initialMessages'));
            if (Array.isArray(initialMessages)) {
                chatHistory = chatHistory.concat(initialMessages);
                console.log('Added initial messages to chat history:', chatHistory);
            } else {
                console.error('Invalid initialMessages format:', initialMessages);
            }

            chat.requestInterceptor = (originalRequest) => {
                // We have always seen that the messages array has only one element
                if (originalRequest.body.messages.length !== 1) {
                    console.error('Invalid message format:', originalRequest.body.messages);
                    return originalRequest;
                }

                // If there's a last message, add it to the chat history
                if (lastMessage !== null) {
                    chatHistory.push(lastMessage);
                }

                const newMessage = originalRequest.body.messages[0]; // Get the new message

                // Validate the structure of the new message
                if (newMessage === null || newMessage.role !== 'user' || typeof newMessage.text !== 'string') {
                    console.error('Invalid message format:', newMessage);
                    return originalRequest;
                }

                // Create the new payload with the updated chat history
                const modifiedPayload = {
                    chat_history: chatHistory,
                    question: newMessage.text,
                };

                // Update the request body with the new payload
                originalRequest.body = modifiedPayload;

                // Store the new message as the last message for the next request
                lastMessage = newMessage;

                console.log('Intercepting request with updated chat history:', originalRequest);

                return originalRequest;
            };

            chat.responseInterceptor = (response) => {
                // Validate the structure of the AI response
                if (response === null || response.role !== 'ai' || typeof response.text !== 'string') {
                    console.error('Invalid AI response format:', response);
                    return response;
                }

                // Add the AI response to the chat history
                chatHistory.push(response);

                console.log('Intercepting response with AI message:', response);

                return response;
            };

            console.log('DeepChat element loaded successfully');
        });
    </script>
OvidijusParsiunas commented 3 weeks ago

Hi @avibathula. Apologies for the late reply as I've been very busy. If you want to control how many messages are sent to the target server - you can use the maxMessages property in the requestBodyLimits object.

This is automatically set to -1 in certain directConnection services.