 Okay, we're back with the next part of our AI podcast chatbot tutorial and if you've been following along in the last episode we were able to create an LLM that uses a vector store and embeddings from our chosen podcast and allows us to run queries against a static, currently static query, which is what is this podcast about. So we don't want a static query, we want the user to be able to specify whatever they want in terms of a question and in order to do that we're going to need to create a form on the front end of the website where they can type that query in, submit it to the backend, the backend will execute that against the retriever on the LLM and retrieve a response and we'll return that back to the front end and display it on the screen. So that's what we're going to try and accomplish here and to do that let's start back in our React code and I'm going to just go ahead and say we'll follow this convention here and we'll say import query form, query, query form and then we'll add results as well, display those. So this is our query form and query results. So that's what's going to look like within our app. We're going to throw some error because those things don't exist yet but they will. So in components make a new folder for query, we'll make new files, queryform.js, what did I call it? Query results. And let's just go ahead and copy this form code into here and find podcast form and change it to query form. Don't think it will need any parameters and let's just go ahead and go through and update this stuff. So on submit handle query search doesn't need a method because we're going to specify the method and then we're going to make a text field that says question. I've been using query so let's just go ahead and call query here on change, set query, query, set query. Look at us go, what else do we need? It seems good for that and for query results. Copy that code and rename it to query results. I'm just shooting from the hip here but I'm assuming it's going to be something like results handle set results. We're going to say if there's some results, we're expecting probably an array and if that array has stuff in it, let's display something on the screen and it won't be a form. Let's just do that for now. It's going to be some sort of list or text container or something like that. We can go ahead and expect that this is going to be called query results container. We've got a whole bunch of unused dependencies. We'll clean those up later. Let's see query results is expecting results and a handle set results function and actually let's be a little more specific parameters for passing. So here let's include them which means we need those functions. I don't think this is going to be a list. It's going to be probably just a single block of text but just a follow, whoops, follow convention. Let's do that here to avoid the name collision. Results list set query results. There we go. All right. That should be enough to keep us out of trouble. Let's see what our front end is looking like. Okay. Yeah. So we've got it on screen and we're not hiding it yet. Let me make sure this error goes away. Yep. So the user is going to be able to ask a question. It probably won't be an input field. It'll be a text field. Just leave that for now. So when they submit this, it's going to do a thing and that thing is handle query search. So again, we can borrow some code. Podcast form is doing some stuff. That is similar. So we're going to prevent default. We're going to log just to make sure what our query is. And then we're going to fetch a user query endpoint, pass it the query and get a response. And let's just log that data. Sure. Yeah. Let's just log the data. Start. So now on the back end, we need to create this endpoint. Have to post API, perform user query. Yes. And on the back end, let's also just console.log that query. Okay. Let's see where we're at. Let's get to check in frequently as you're making these changes just to figure out what you've messed up. Okay. So we wired that together. And we can see on the back end, we're getting whatever the user submitted. So that works. Obviously, we don't want to be able to do this until our LLM is ready, which involves all that stuff that comes before it, which is searching for your podcast, picking an episode, transcribing the episode, and setting up the LLM. And I'm realizing that to display this form conditionally, we are going to need to follow a conditional display, sort of like what's happening in podcast results. So let's copy that convention and we'll say, if LLM ready, display this, actually we could say LLM ready and what I do. Okay. So now it wants that as a parameter, LLM ready, which means we're going to pass that down from the app, which means we've got to store it in state. React and the thing that is going to pass whether or not the LLM ready is whatever we used to submit the episode. So we need to give that to episode results. Let's go in there. So we were just logging the data on the transcribe episode, but we're going to do some condition and then say, set LLM ready. All right. So that's going to call back to the main app. And the reason we're putting it here is because that's going to just hold a sort of app state in the absence of using an actual store, which would be the right thing to do. We'll keep it all at the top level of the app. And we don't want an array. We want a Boolean. Okay. So it's going to be informed from the episode results that the LLM is ready. It's going to set state. It's going to pass that state whenever it changes down to the query form. The query form is going to say, if LLM is ready, display me. Okay. So now we want to see what's happening on the back end. When we establish this LLM, we are currently running the static query. We don't want to do that anymore. We just want to pass back the message that everything is ready to the front end. So we're going to return response status 200. And we'll just say LLM ready. True. There's probably some error handling and things like that we need to do here. But we're not going to do it right now. The other thing I realize is that chain is not going to be accessible to whatever next method we have. So I'm actually going to copy this and declare it as a global variable here. Just say let chain. Okay. Hopefully that'll work. So this is being sent to as a response to episode results. So the data that we receive is going to be LLM ready. So we're going to say, if data.LLM ready, set LLM ready to true. Actually realizing that this is, this should be handle set LLM ready. We're using the actual state function and we shouldn't do that. So handle set LLM ready true. So that's our condition. And that is coming from app. So app needs a handle set LLM ready. There we go. So now it's got what it needs. And it needs to pass that to the form. Is the LLM ready? Yes or no? If it is, display me. Let's see where we're at. Our MP3 file is being created, which means we've passed that properly. There's the transcription. And on the front end, we've now shown that question form, which means we got this data as we can see that the LLM is ready. And that also means that we're passing state properly through our React app. And you know, we probably should hide all this other stuff too, but we'll, we'll get to all of that. So now what we need to do is take that static query that we had here and actually execute it in this endpoint. We'll paste that there. You know, it's working. So we don't need to log it. Chain.call query query. And we'll log the chain response. There's a response and it's accurately giving an answer about the podcast. So we just need to return that response, the status 200, just assume everything's going to work perfectly and not bother with any error handling whatsoever. That's a good idea. So back to the form. Forget data. And let's say this chain response.text. And now since query results is the component that's going to need that, we're going to need a function call backup to the app and over to query results. So now we need to take that data.text and pass it back up to the app and over to the query results component. And I think we have a function that's already doing that. We do, we're just passing it to the wrong component. It actually needs to go to the query form. And all the query results does is it takes the actual results. So let's put that here. And let's say handle set query results data.text. Now query results does not have that parameter. And it's just going to be a string. So let's see if we can get away with this here. One last hopeful round through this. There we go. We got the response on the back end. We passed it the front end. And it's very sloppily being displayed on the front end. So we've done a lot here. So I think we'll call that success for this episode. And in the next one, we will stop using our static podcast file and we'll go back to that podcast index, really test it out, see if it's working, see if we can reliably grab MP3 files, transcribe them and be able to ask questions and get good responses back. We'll also handle a lot of that user experience, displaying loaders, displaying messages, things like that. See you in the next episode.