Having trouble with my assistant's memory

Hello! I’m working on an agent framework and I’ve recently run into some strange issues. Even though the thread id is unchanged, the assistant is not remembering conversations that we previously had. And sometimes it gets fairly “mixed up” and doesn’t answer my actual question.

Here’s an example of one of my threads which was created using my interactive python script:

When I have the same conversation in the Open AI playground with the same agent, it recalls my word 100% of the time.

Here’s some of the most important functions in my code:

    def interact(self, message):
        
        # Let the assistant do its thing.
        run = self.run_openai(self.thread_id, self.assistant_id, message)

        # Fetch all of the messages
        messages = self.client.beta.threads.messages.list(thread_id=self.thread_id)

        logging.info(f"messages: \n\n {messages}")

        # Find the most recent response from the assistant and return it
        for message in messages.data:
            if message.role == 'assistant':
                return message.content[0].text.value
                break

    def run_openai(self, thread_id, assistant_id, instructions=None):

        run = self.client.beta.threads.runs.create(
            thread_id=thread_id,
            assistant_id=assistant_id,
            instructions=instructions
        )

        while True:

            run = self.client.beta.threads.runs.retrieve(thread_id=thread_id, run_id=run.id)

            print(f"Run {run.id}, thread_id: {thread_id}, status: {run.status}")

            if run.status == 'completed':
                print("Run completed.")
                break
            elif run.status == 'requires_action':
                print('Requires action')

                tool_calls = run.required_action.submit_tool_outputs.tool_calls
                logging.info(f"tool_calls: {tool_calls}")

                tool_outputs = self.call_tools(tool_calls)
                logging.info(f"tool_outputs: {tool_outputs}")

                self.client.beta.threads.runs.submit_tool_outputs(
                    thread_id=thread_id,
                    run_id=run.id,
                    tool_outputs=tool_outputs
                )

            elif run.status == 'error':
                break

            time.sleep(1.0)

        return run


    def call_tools(self, tool_calls):
        tool_outputs = []
        for tool_call in tool_calls:
            tool_name = tool_call.function.name
            try:
                tool_class = self.tools.get_tool_class(tool_name)  # Use Tools instance to get the tool class
                tool_instance = tool_class(json.loads(tool_call.function.arguments))

                # Run the tool and collect the response
                function_response = tool_instance.run()
            except Exception as e:
                # Handle exceptions
                error_message = str(e)
                function_response = {"status": "error", "message": error_message}

            # Prepare and append the output
            tool_output = {"tool_call_id": tool_call.id, "output": json.dumps(function_response)}
            tool_outputs.append(tool_output)

        return tool_outputs

And finally, some of the output from my run:

Hello! How can I assist you today? If you have any questions or need help with something, feel free to ask.
Enter your question (or 'exit' to quit): Can you remember the word "foo" for me?
Run run_aQKfBQ0RPOYNrfo73U8CT2LA, thread_id: thread_jqOJof28ow7BPLZwpK1AoIqg, status: in_progress
Run run_aQKfBQ0RPOYNrfo73U8CT2LA, thread_id: thread_jqOJof28ow7BPLZwpK1AoIqg, status: in_progress
Run run_aQKfBQ0RPOYNrfo73U8CT2LA, thread_id: thread_jqOJof28ow7BPLZwpK1AoIqg, status: completed
Run completed.
I have stored the word "foo" for you. How else may I assist you today?
Enter your question (or 'exit' to quit): Thanks!  What was that word again?
Run run_A7rafqfaTKR0JhWSFaab4uob, thread_id: thread_jqOJof28ow7BPLZwpK1AoIqg, status: in_progress
Run run_A7rafqfaTKR0JhWSFaab4uob, thread_id: thread_jqOJof28ow7BPLZwpK1AoIqg, status: in_progress
Run run_A7rafqfaTKR0JhWSFaab4uob, thread_id: thread_jqOJof28ow7BPLZwpK1AoIqg, status: in_progress
Run run_A7rafqfaTKR0JhWSFaab4uob, thread_id: thread_jqOJof28ow7BPLZwpK1AoIqg, status: in_progress
Run run_A7rafqfaTKR0JhWSFaab4uob, thread_id: thread_jqOJof28ow7BPLZwpK1AoIqg, status: in_progress
Run run_A7rafqfaTKR0JhWSFaab4uob, thread_id: thread_jqOJof28ow7BPLZwpK1AoIqg, status: in_progress
Run run_A7rafqfaTKR0JhWSFaab4uob, thread_id: thread_jqOJof28ow7BPLZwpK1AoIqg, status: in_progress
Run run_A7rafqfaTKR0JhWSFaab4uob, thread_id: thread_jqOJof28ow7BPLZwpK1AoIqg, status: in_progress
Run run_A7rafqfaTKR0JhWSFaab4uob, thread_id: thread_jqOJof28ow7BPLZwpK1AoIqg, status: completed
Run completed.
I'm sorry, but as an AI developed by OpenAI, I don't have the ability to remember past interactions or store information between sessions. Each interaction with me is stateless and independent. If you tell me the context or give me a clue, I might be able to help you with the word you are looking for.
Enter your question (or 'exit' to quit): exit

I’m having real trouble tracking this down, and any help would be much appreciated. The only thing I can imagine is that my computer’s timezone isn’t matching the Threads log, but that seems like it shouldn’t matter.

Cheers,
Bret

Never mind! I figured it out. I was passing in the user input through the “instructions” parameter. Instead I had to add the message to the thread before starting the run.

The corrected code looks like this:

    def run_openai(self, thread_id, assistant_id, thread_user_message, instructions=None):

        self.client.beta.threads.messages.create(
            thread_id=thread_id,
            role="user",
            content=thread_user_message
        )

        run = self.client.beta.threads.runs.create(
            thread_id=thread_id,
            assistant_id=assistant_id,
            instructions=instructions
        )