[ beginner issue ReactJs ] how i can avoid regenerating the thread.id

Hello,
This is my first message here. Been trying to solve this issue over the week-end but couldn’t although it’s very simple.
In the following code when a new message is submitted, it triggers the handleSubmit that generate the thread.id. I would like to avoid thread.id to be regenerated every time so tried to use const [thread, setThread] = useState(null);
Unfortunately i coudn’t get it to work properly.
would be grateful for any help, thanks you. Here is my code:

import { OpenAI,Configuration } from "openai";
import { useState, useEffect } from "react";
import AIWriter from "react-aiwriter";

const ChatbotApp = (props) => {
    const Dorio = props.dorio;

	const openai = new OpenAI({ apiKey: process.env.REACT_APP_OPENAI_API_KEY, dangerouslyAllowBrowser: true  });
    const [conversation, setConversation] = useState([]);
    const [prompt, setPrompt] = useState("");
    const [loading, setLoading] = useState(false);
    const [showDefaultMessage, setShowDefaultMessage] = useState(false);
    const [thread, setThread] = useState(null);

    useEffect(() => {
        const timer = setTimeout(() => {
            setShowDefaultMessage(true);
        }, 1000);

        return () => clearTimeout(timer);
    }, []);


	
    const handleSubmit = async (e) => {
        e.preventDefault();
        setLoading(true);
        try {

			  const thread = await openai.beta.threads.create(

			  );
			  
			  const message = await openai.beta.threads.messages.create(
				  
			  thread.id,
			  {
			    role: "user",
			    content: prompt
			  }
			);
			console.log(thread);
			console.log(message);
			const threadMessages = await openai.beta.threads.messages.create(
				thread.id,
				{ 
					role: "user", 
					content: prompt }
				);
				
			
			let run = await openai.beta.threads.runs.createAndPoll(
			  thread.id,
			  { 
			    assistant_id: "asst_KxpkPyj7qUXaPbZAZ2Qgqn9K",
			  }
			);
			if (run.status === 'completed') {
				const messages = await openai.beta.threads.messages.list(
				run.thread_id
		  );
		  for (const message of messages.data.reverse()) {
		    console.log('Message structure:', message);
		
		    const role = message.role;
		    const content = message.content[0]?.text?.value;
		
		    if (role && content) {
		        console.log(`${role} > ${content}`);
		        setConversation(prevConversation => [
		            ...prevConversation,
		            { speaker: role, message: content }
		        ]);
		    } else {
		        console.error('Invalid message format', message);
		    }
		}

		} else {
		  console.log(run.status);
		}

        } catch (e) {
            console.error("Error fetching OpenAI completion:", e);
            setConversation([...conversation, { speaker: 'user', message: prompt }, { speaker: 'AI', message: "Something went wrong, Please try again." }]);
        }
        setLoading(false);
        setPrompt('');
    };

    const handleChange = (e) => {
        setPrompt(e.target.value);
    };

    return (
        <div>
            <div className="chatGPT">
                <div>
                    <div className="conversation">
                        {conversation.slice(0).reverse().map((item, index) => (
                            <AIWriter key={index}>
                                <div className={`message ${item.speaker}`}>
                                    <strong>{item.speaker}: </strong>
                                    <p>{item.message}</p>
                                </div>
                            </AIWriter>
                        ))}
                        {showDefaultMessage && (
                            <AIWriter key="default">
                                <div className={`message ai`}>
                                    <strong>AI: </strong>
                                    <p>Hi <strong>{Dorio}</strong> I am an AI assistant, how can I help you today?</p>
                                </div>
                            </AIWriter>
                        )}
                    </div>
                    
                <form onSubmit={handleSubmit}>
                    <input
                        type="text"
                        value={prompt}
                        placeholder="You can ask any question."
                        onChange={handleChange}
                    />
                    <button
                        className="pt-md mySubmit-btn btn btn-small btn-dark float-end"
                        disabled={loading || prompt.length === 0}
                        type="submit"
                    >
                        {loading ? "Thinking..." : "Ask Me"}
                    </button>
                </form>
                </div>
            </div>
        </div>
    );
};

export default ChatbotApp;

use zustand to persist your state variable.

appstore.js

import { create } from 'zustand'
import { persist, createJSONStorage } from 'zustand/middleware'

export const useAppStore = create(
  persist(
    (set, get) => ({
      thread: '',
      setThread: (id) => set({ thread: id }),
    }),
    {
      name: 'app-storage', // name of the item in the storage (must be unique)
      storage: createJSONStorage(() => sessionStorage), // (optional) by default, 'localStorage' is used
    },
  ),
)

then editing your code:

import { OpenAI,Configuration } from "openai";
import { useState, useEffect } from "react";
import AIWriter from "react-aiwriter";
import { useAppStore } from '/where/your/store/at/appstore.js'

const ChatbotApp = (props) => {
    const Dorio = props.dorio;

	const openai = new OpenAI({ apiKey: process.env.REACT_APP_OPENAI_API_KEY, dangerouslyAllowBrowser: true  });
    const [conversation, setConversation] = useState([]);
    const [prompt, setPrompt] = useState("");
    const [loading, setLoading] = useState(false);
    const [showDefaultMessage, setShowDefaultMessage] = useState(false);
    //const [thread, setThread] = useState(null);
const thread = useAppStore((state) => state.thread)
const setThread = useAppStore((state) => state.setThread)

    useEffect(() => {
        const timer = setTimeout(() => {
            setShowDefaultMessage(true);
        }, 1000);

        return () => clearTimeout(timer);
    }, []);


	
    const handleSubmit = async (e) => {
        e.preventDefault();
        setLoading(true);
        try {

			  const thread = await openai.beta.threads.create(

			  );
			  
			  const message = await openai.beta.threads.messages.create(
				  
			  thread.id,
			  {
			    role: "user",
			    content: prompt
			  }
			);
			console.log(thread);
			console.log(message);
			const threadMessages = await openai.beta.threads.messages.create(
				thread.id,
				{ 
					role: "user", 
					content: prompt }
				);
				
			
			let run = await openai.beta.threads.runs.createAndPoll(
			  thread.id,
			  { 
			    assistant_id: "asst_KxpkPyj7qUXaPbZAZ2Qgqn9K",
			  }
			);
			if (run.status === 'completed') {
				const messages = await openai.beta.threads.messages.list(
				run.thread_id
		  );
		  for (const message of messages.data.reverse()) {
		    console.log('Message structure:', message);
		
		    const role = message.role;
		    const content = message.content[0]?.text?.value;
		
		    if (role && content) {
		        console.log(`${role} > ${content}`);
		        setConversation(prevConversation => [
		            ...prevConversation,
		            { speaker: role, message: content }
		        ]);
		    } else {
		        console.error('Invalid message format', message);
		    }
		}

		} else {
		  console.log(run.status);
		}

        } catch (e) {
            console.error("Error fetching OpenAI completion:", e);
            setConversation([...conversation, { speaker: 'user', message: prompt }, { speaker: 'AI', message: "Something went wrong, Please try again." }]);
        }
        setLoading(false);
        setPrompt('');
    };

    const handleChange = (e) => {
        setPrompt(e.target.value);
    };

    return (
        <div>
            <div className="chatGPT">
                <div>
                    <div className="conversation">
                        {conversation.slice(0).reverse().map((item, index) => (
                            <AIWriter key={index}>
                                <div className={`message ${item.speaker}`}>
                                    <strong>{item.speaker}: </strong>
                                    <p>{item.message}</p>
                                </div>
                            </AIWriter>
                        ))}
                        {showDefaultMessage && (
                            <AIWriter key="default">
                                <div className={`message ai`}>
                                    <strong>AI: </strong>
                                    <p>Hi <strong>{Dorio}</strong> I am an AI assistant, how can I help you today?</p>
                                </div>
                            </AIWriter>
                        )}
                    </div>
                    
                <form onSubmit={handleSubmit}>
                    <input
                        type="text"
                        value={prompt}
                        placeholder="You can ask any question."
                        onChange={handleChange}
                    />
                    <button
                        className="pt-md mySubmit-btn btn btn-small btn-dark float-end"
                        disabled={loading || prompt.length === 0}
                        type="submit"
                    >
                        {loading ? "Thinking..." : "Ask Me"}
                    </button>
                </form>
                </div>
            </div>
        </div>
    );
};

export default ChatbotApp;
1 Like

THank you very much I managed to get it work this way ! :grinning:

1 Like

We’ve got a great community here. Hope you stick around and learn more. :slight_smile:

1 Like