OvidijusParsiunas / deep-chat

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

Proper way to "dynamically" configure connection and other information within Vue app? #149

Closed chirstius closed 1 month ago

chirstius commented 3 months ago

Hello!

I would like to make the deep-chat component dynamically configurable i.e.

deep-chat-settings

I am binding the component as:

:request="{
  url: sseEndpointConfig.request.url,
  method: sseEndpointConfig.request.method,
}"
:requestBodyLimits="{
  maxMessages: sseEndpointConfig.requestBodyLimits.maxMessages,
}"
:stream="sseEndpointConfig.stream"

Bound to:

data() {
  return {
    sseEndpointConfig: {
      request: {
        url: "http://localhost:8082/streaming?tokenize=false",
        method: "POST",
      },
      requestBodyLimits: {
        maxMessages: 20,
      },
      systemPrompt: "You are a helpful assistant named Max",
      stream: true,
    },
  };
},

And the settings for inputs are all bound as well. The client connects with the initial values set within sseEndpointConfig, and I can see the values being updated via the settings form, but when I make a subsequent call (after changing the URL for example) it's clearly not picking up the changes to the URL - it always calls the "initial" URL.

Is there a different/better way to handle something like this?

If I do something like:

this.$refs.chat.request = {
  url: "http://differenthost:8081/streaming?tokenize=false",
  method: "POST",
};

in mounted() - it DOES work, it takes the change. But doing it with the reactive binding things don't seem to work.

Any help would be great! Thank you!

OvidijusParsiunas commented 3 months ago

Hi @chirstius.

This is definitely interesting, I will look at this in closer detail and see if I can find a working solution for you.

As I mentioned in the other issue, I don't have much time today and unfortunately will look at it tomorrow. My apologies. I will update you on the latest progress!

Thank you!

chirstius commented 3 months ago

Thank you!

OvidijusParsiunas commented 3 months ago

I have looked at your issue in closer detail. The problem appears to be stemming from the Vue engine Deep Chat is not being completely re-rendered even though the other sibling elements are. Fortunately, the fix for this is actually quite simple. You can use a :key property on the <deep-chat element and increment its value - which will force a re-render:

<deep-chat
  :key="componentKey"
  :request="{
    url: sseEndpointConfig.request.url,
    method: sseEndpointConfig.request.method,
  }"
/>

And in the component logic, you can have something like the following:

export default {
  data() {
    return {
      sseEndpointConfig: {
        request: {
          url: "http://localhost:8082/streaming?tokenize=false",
          method: "POST",
        }
      },
      componentKey: 0,
    };
  },
  methods: {
    forceRerender() {
      this.sseEndpointConfig.request.url = "http://localhost:8084";
      this.componentKey += 1;
    },
  }
};

The forceRender method can be invoked after the configuration has been updated.

Please note that if your system allows users to dynamically change the configuration of the chat system - the re-renders will cause the chat history to disappear every time the configuration/re-render takes place. For this I advise you to track the messages in some form of outer state via onNewMessage and use the initialMessages property to initialise the history. You are more than welcome to raise another issue if you need further assistance with this (as long as it's related to Deep Chat ofcourse).

Let me know if the above solution works. Thanks!

chirstius commented 3 months ago

Thank you! I will look into implementing this over the next day or so and let you know how it goes.

chirstius commented 3 months ago

Actually was able to quickly test the :key trick and it seems to work! Excellent "hack" :D

I will work on implementing message retention as that needs to be a little different depending on which setting you change, though I had noticed that even bringing up the settings dialog was clearing chat history already - likely due to some form of forced/unexpected re-render from Vue - at least now I have a possible explanation for that. If you change the endpoint issue, I actually WANT to clear the chat anyway. If you're changing something like the model or streaming or anything for the same endpoint it makes sense to retain the messages - which just means I need to retain them in all cases but just determine when and where to put them back.

Do you have any thoughts on how it might be possible to hold onto the messages when the dialog pops though? or persist them through a re-render or whatever is going on? Then it would be as simple as calling clearMessages() or whatever it is when an actual endpoint param was changed and not needing to store everything. But I think it's a viable workaround for the moment - I'll just need to hook and restore everything when the settings dialog is closed. but the :key trick works great

OvidijusParsiunas commented 3 months ago

Glad to hear the solution worked.

In regards to persisting messages, there are many ways of doing it; via the use of libraries, external dbs etc. The Deep Chat Playground is actually using localStorage to persist messages and selected configuration. You can check the code here. Another solution is the use of sessionStorage, which works for short-term storage. If you have any other questions (Deep Chat specifically) you can open another issue where we can deal with them there. Thanks!

chirstius commented 3 months ago

Sorry that was intended as "is there a way in deep chat to persist them" - I can implement it however needed, was thinking more if you saw value in making "saving chat state through re-renders" the "default" behavior - sorry to be unclear

OvidijusParsiunas commented 3 months ago

Not at the moment. The process of persisting messages is very much dependent on the client and their preferences, hence it is difficult to standardise. It gets even more complicated if there are multiple chats within the same window or if their order changes.

We are currently preparing for a big release of the next Deep Chat version, hence I cannot consider taking on new features. Nevertheless I can add it to the list of new features to explore.

OvidijusParsiunas commented 1 month ago

Hi, I have added the proposed enhancements to my list and will be closing this issue as the original matter has been resolved. Thanks!