Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix panic when removing a message in the history with 0 value #65

Closed
wants to merge 2 commits into from

Conversation

shigedangao
Copy link

Description

It appears that when calling the send_chat_messages_with_history_stream method. Theadd_message method will try to remove a message by finding an index. Which by default is set to 0.

messages.remove(index_to_remove);

For some unknown reason the index_to_remove variable can be equal to 0 and the fact that the messages vec can also be empty this means that the operation will panic

This PR aims to just to avoid panicking and only remove a message when the id is present

@starccy
Copy link

starccy commented Aug 30, 2024

Hi, thanks for your work! After a closer inspection, however, I am afraid that this PR did not fix the root issue.

The root problem I think is every time it tries to get the stored history, the history will be reassigned with a default value.

fn get_chat_messages_by_id(&mut self, history_id: impl ToString) -> Vec<ChatMessage> {
let mut binding = {
let new_history =
std::sync::Arc::new(std::sync::RwLock::new(MessagesHistory::default()));
self.messages_history = Some(new_history);
self.messages_history.clone().unwrap()
};
let chat_history = match self.messages_history.as_mut() {
Some(history) => history,
None => &mut binding,

Because of this, it not only caused the panic problem but the historical messages were not stored at all.

How about moving the binding statement into the match block?

    fn get_chat_messages_by_id(&mut self, history_id: impl ToString) -> Vec<ChatMessage> {
        let chat_history = match self.messages_history.as_mut() {
            Some(history) => history,
            None => {
                let new_history =
                    std::sync::Arc::new(std::sync::RwLock::new(MessagesHistory::default()));
                self.messages_history = Some(new_history.clone());
                self.messages_history.as_mut().unwrap()
            },
        };

Besides, give the MessagesHistory a default limits value to prevent array index overflow.

#[derive(Debug, Clone)]
pub struct MessagesHistory {
    pub(crate) messages_by_id: HashMap<String, Vec<ChatMessage>>,
    pub(crate) messages_number_limit: u16,
}

impl Default for MessagesHistory {
    fn default() -> Self {
        Self {
            messages_by_id: HashMap::new(),
            messages_number_limit: 30,
        }
    }
}

@starccy
Copy link

starccy commented Aug 30, 2024

Here's the diff, hoping it's helpful.

diff --git a/src/generation/chat/mod.rs b/src/generation/chat/mod.rs
index 7fdceb0..dbe8b86 100644
--- a/src/generation/chat/mod.rs
+++ b/src/generation/chat/mod.rs
@@ -196,15 +196,14 @@ impl Ollama {
     /// Without impact for existing history
     /// Used to prepare history for request
     fn get_chat_messages_by_id(&mut self, history_id: impl ToString) -> Vec<ChatMessage> {
-        let mut binding = {
-            let new_history =
-                std::sync::Arc::new(std::sync::RwLock::new(MessagesHistory::default()));
-            self.messages_history = Some(new_history);
-            self.messages_history.clone().unwrap()
-        };
         let chat_history = match self.messages_history.as_mut() {
             Some(history) => history,
-            None => &mut binding,
+            None => {
+                let new_history =
+                    std::sync::Arc::new(std::sync::RwLock::new(MessagesHistory::default()));
+                self.messages_history = Some(new_history.clone());
+                self.messages_history.as_mut().unwrap()
+            },
         };
         // Clone the current chat messages to avoid borrowing issues
         // And not to add message to the history if the request fails
diff --git a/src/history.rs b/src/history.rs
index 2fe3eea..a90924c 100644
--- a/src/history.rs
+++ b/src/history.rs
@@ -5,12 +5,21 @@ use crate::{
     Ollama,
 };
 
-#[derive(Debug, Clone, Default)]
+#[derive(Debug, Clone)]
 pub struct MessagesHistory {
     pub(crate) messages_by_id: HashMap<String, Vec<ChatMessage>>,
     pub(crate) messages_number_limit: u16,
 }
 
+impl Default for MessagesHistory {
+    fn default() -> Self {
+        Self {
+            messages_by_id: HashMap::new(),
+            messages_number_limit: 30,
+        }
+    }
+}
+
 pub type WrappedMessageHistory = std::sync::Arc<std::sync::RwLock<MessagesHistory>>;
 
 /// Store for messages history

@bredmond1019
Copy link

bredmond1019 commented Sep 1, 2024

Hey all. I just found the same issue and the same solution on local, then saw you had this change already. I'm not sure it
s necessary to set the default always to 30 like the diff above, but the rest checks out on my end.

In the send_chat_messages_with_history_stream function, the get_chat_messages_by_id is always called. Then the binding variable will always set the messages_history back to a new one, so whatever we set in the beginning won't matter.

@shigedangao
Copy link
Author

shigedangao commented Sep 1, 2024

Hey thanks for your feedback. I indeed haven't dig quite far into the code and it's good that you guys did as it'd have not fix the root cause issue. I'm not sure however if it's necessary to add a Default value, as when creating the Ollama instance the history limit would have been set e.g: with new_with_history.

Let me know if the fix works on your end @bredmond1019 @starccy

@shigedangao
Copy link
Author

Actually a similar PR seems to fix the issue. See here #60

@starccy
Copy link

starccy commented Sep 2, 2024

Oh yes, you are right, the default value is not necessary. And I realize there is already a PR to solve this problem indeed.

@shigedangao
Copy link
Author

@starccy closing this one as the previous PR will fix our issue

@shigedangao shigedangao closed this Sep 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants