How to Use Open AI's GPT-4o in FlutterFlow - Part 2

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
in this second video in the series of how to integrate flutter flow with open ai's newest model GPT 40 we're going to structure the backend for storing the chat conversations design the page and then implement the logic for this demo we're going to use Firebase and I've already set that up I've left a link in the description if you need help setting that up all right the first step in building any backend schema that is what collections of data you need and what Fields you need in those collections is to list what entities what buckets of data you're going to need well we're building a chat app so we're going to need to store our chats that is each conversation so we'll need a collection of chats second we need to store the messages in those chats so we'll have a collection of messages now because these two collections are related to each other that is chats have messages we need to determine how to relate these two Collections and there are two options top level collections that you relate by a shared ID or reference or a top level collection and a subcollection either one would work fine so we're going to go with a sub collection next let's figure out what fields we need for each collection so we're going to need to know whose chat this is like which user so let's add a unique ID that references the user we're also going to need to order these chats when we display them so we can see the most recent chat first so let's add a timestamp finally we'll need need a title for each chat and that's good for our chats collection for our messages we'll need the messages themselves we also need to know whose message it is like is it the user or chat GPT and for that we'll use an enum enums are great when you have only a few values that you want available so for us it'll either be the user or chat GPT which we'll call assistant and then finally we'll need a timestamp and that's because when we display these messages we need to order them like a normal conversation okay great one quick tip on designing backend schema if you're struggling just go to chat GPT or Gemini tell it what you're building and what backend you're using and it'll give you a great model and if you're confused about something you can just ask a follow-up question beautiful our backend schema is ready to go let's go design the UI all right so we've got a blank page here and we want to build a simple chat UI with a text input on the bottom and the chat's coming in on the top okay so because these things are stacked on top of one another we can just throw in a column as our main architectural widget then we need one widget that will hold our messages and one widget for our text input so for the top one let's use a list view because that's good for performance when displaying a lot of data and we can put a text field in down here beautiful let's come up to our column right here and give it a little padding to push it off edges then we're going to come to our list View view right here and make it expanded so it fills the entire space and I've already got a style set up for our text field here in our widget style so I'm just going to apply that now now just so we can see what's going on inside this list view I've already built a component that we can use here so let's come over here to our components and grab in our chat now let's come back to our list View and you can see that we want to change this because we don't want the messages up here because typical in chat llm they come in from the bottom here so we can just click reverse we don't want it shrink wrap that can just affect performance next let's jump into this chat bubbles component to see how we built it now it's hard to see our text right here so you can just come up here and change the canvas color so you can see it better and that looks good now just note that this is not editing anything in this component and won't be shipped with your app this is simply the canvas for when you're working with it okay so how we built this component well you can see up here here that we've simply got one row right here that has two children the one on the left is a stack of two different icons and here we've just got some text that will be our message now we set up one parameter for this component that is what data is coming into this component and that is a messages document that is the documents coming in from the messages collection that we set up and this text right here is bound to the content property of that message's document and then over here we're conditioning showing and hiding one of these two icons depending on Whose message it is because remember we've got messages coming from chat PT called an assistant and messages coming from the user that's what you type in and when it's the user right here we want to show it so we're looking at the role property and we're seeing if it equals the RO user here and if it does it'll show the user icon that is that image of that gentleman right if not it'll show this star icon which is the icon for the GT assist we don't need to do that for our message right here because it'll always show whatever is in that content field okay that's all set up let's go back to the page let's just do some housekeeping here so in our text field down here we don't want it to say label here and we actually don't want a label just because of our style we've set up we want it as a hint that is you'll see it here and then it'll disappear when the user start typing the label will move up to the top here so we don't want that and in our hint text we'll just say ask me anything all right great this is done we're ready to implement the logic so let's get an overall picture of how this logic is going to work and there's a great question to ask when you're trying to figure out complex logic what data needs to be maintained for each session that is when the user is using this page doing whatever they do on this page and for us it's chatting what data do we need to make that happen well we're we're going to need some messages to display so that means we're going to need a variable to store those messages now the normal pattern in flutter flow is to store those messages in a variable and then update just that variable that's instead of directly updating the widgets from the response from an API call this gives us much more control and avoids a handful of potential problems now when you need to store this data in a variable you have two main options a page State variable or an App State variable and which you will use will depend on the design of your app we just need the data here so we're going to use a page State variable okay what other data needs to be maintained well we also need to keep track of which conversation it is that we're in so let's make a variable called chat ref which will store a reference to the chat we're in all right so let's set up this logic first let's bind those State variables on this page so we've got our messages variable which will be used to populate our messages here so let's come into our list view here and come over here to dynamically generating children and set that equal to our page State variable called messages beautiful we'll come in here and call this message item and save and then we want to pass each of those items into our chat bubbles here so let's come down and in here we want to pass this message item and confirm beautiful all right we're now ready to set up all that logic so how do we want this logic to start execution well the user is going to type something into this field right here and when they submit that that's when they want the logic to kick off so we can come here and let's give us some more space here in our action flow editor we're on the onsubmit trigger and let's add an action all right so what do we want to happen well we're starting a new conversation so we probably want to create a new chat document in our chat's collection but there's one other condition we have to consider and that is when the user is using this text field right here sometimes it'll be a new chat but sometimes it'll be continuing another chat like their second message or their 10th message so before we create a new chat conversation we have to check for a condition we have to check whether this is a new chat or an ongoing chat so we want to add a conditional action and what are we going to do here well remember we already set up a page State variable to track our chat data so we can add a condition here and the first condition will be that chat reference right here and we want to see if it is set and so if it is set then this would be true which means this would be an ongoing conversation if it's false over here this will be a new conversation so let's deal with the logic in our new conversation first so we come in here and we want to add another action and if it's a new chat then we we don't have any chat document yet so let's create one so we're going to come into firestore here and create a new document the new document will be chats and we want to set the fields of the unique ID and not the title we can handle that in another video so instead we're just going to set the timestamp so let's set that first and we just want to set that to the current time and the unique ID which is a document reference to our user so we just want the authenticated users user reference beautiful now I know that this logic is going to get quite complex and long so it's a good habit to get into naming your actions here so the naming convention that I like to do is to first set the type of action so here would be a database action and then what it's doing so here we're just creating a chat doc this is going to make it easier later when we see all of our actions to quickly understand what each node does finally let's name our output variable name and we need to do this because we're going to use this document in The Next Step because we're keeping track of which chat it is in that page State variable so if you know you're going to need the value coming out of this action then make sure you give it a name because that's how you'll make it available now you might think that we just want to call this chat doc or something like that but because we have this conditional action setup and each of these sides are going to have similar sets of logic a good pattern to use is to pend something in front here so you know what branch of logic you're in so I'm just going to call this new for a new chat and I'll append that to all of my action output variables so when I'm looking into those it's easy to quickly identify what it is okay so I've created this new chat document that chat document will be returned to me and will be placed into this variable right here so now we need to update that page State variable so we know what chat we're in remember that's this variable that we're right here so let's come in here let's add an action we can search for page and right there we've got update page state which one do we want we want our chat reference we want to set the value right here and the value we want is coming from an output down here so let's open that up and there it is new chat Doc and what do we want in here well we are looking for a document reference and so we want reference right there beautiful let's give this action a good name right here so what kind kind of thing it is it's state CU we're updating a page State variable and it is our chat doc finally down to this update typew rate now this is not a necessary step but it is good for optimization and by default whenever you change a state variable in flutter flow it will rebuild the current page that is the UI will be updated but you only want to update your UI when you need to update the UI that is when there's a change that you want the user to see but here this would be unnecessary and that's because there's nothing in the UI that is dependent upon this variable so the shorthand rule to memorize is if you need to see something rebuild if not don't all right what do we want to do next well the users submitted a message so let's write that message to fir store so let's come in here and add an action we want it to be fir store create document it's going to be our messages collection and because we have our messages set up as a sub collection we need to give a refence as to which chat this message is a child well we've just managed that over here so we can reference that so here's our page State and here's our chat reference beautiful so now it knows which chat which conversation it is that we want to relate these messages to and now we just need to set Fields so we have our timestamp here which we can just set to our Global property of current time let's close that up and our next field is rooll that is is this the user or chat P PT and we've got two options here and it's our user and it looks like this because we've defined this as enum and finally we have our content that is the message itself well we don't want a hardcode of value we want it from a variable and the variable is going to be from the widget itself this text field right here okay great now we will be using this later so let's give it a name we'll call it new chat cuz we're in this new chat Branch new message finally let's name this right here and what kind of thing this is a database action and it is a message and specifically it's our user beautiful now you may think that our next step is to send this off to open AI but actually there's a step that we want to do before that can you figure out what it is we want to update our UI with this message this will create a snappier app experience because that user's message will immediately show up in our messages list view we don't want to wait to show it until after chat GPT responds well how do we get it to show up well remember we're handling all of our messages UI through that messages State variable that's the only thing we're ever touching so we just need to update that so let's come into here and add another action it's another page State variable right there and we want to set our fields for this messages variable and what do we want to do well we want to add it to the list what value is it well this is a messages document so we've already got that document here which is coming from creating it in this step right here so we can just add that there let's give it a good name and here I'm not going to start this with State because the main thing that this is accomplishing is a UI update so I like to start UI updates with UI we can already see down here with the name of the action that it has to do with state so this provides a little bit more meaning to myself in the future when I'm trying to understand this logic and what am I updating in the UI well it's my messages great and then the update type is set correctly this time because you want the page to rebuild if there's something in the UI that need to be updated and of course there is because we want to see that users's message all right so now we're finally ready to send this off to open AI so here we're going to need an API call so search for API API call and then we can select what we want here that's our group call and create chat completion is the correct endpoint next let's set our variables and we only have one which is the prompt itself and if you remember what this prompt is is it's a list of Json and each of those Json objects is a different message in our chat history well this is a new chat so we only have one the one from the user of course if you want to add in a system prompt before then you could do that as well but we're not doing that here so we need to just pass in our message that we received so we can go into our action outputs right here and come into our new chat message and wait a second what's going on here cuz I want to pass in this whole thing but it only gives me like a reference and this created time thing well if you ever run into this problem scroll up to the top so you can see what type You're Expecting so here we're expecting a list of Json objects but here this is a document of type message so there's a type mismatch so let's go create a small function that will convert these documents into a list of Json let's close this out let's come into our custom code and we want a function and let's give it a function name and best way to name functions is to say exactly what it does so this is going to be a list of messages to a list of Jason that is the list of messages is that page State variable that only thing that we're ever interacting with for our messages and we want to convert it to a list of Json because that's what open ai's API is expecting then we can just set the return type the return type is a list Json right here so it's a list you typically don't want return type be nullable and this is going to be Jason right there the argument what we're putting in here is it's going to be messages and these will be documents they will be a list you typically do want your arguments to be nullable so you can handle that nullable case and this will be document type messages beautiful now I'm going to post some code here but then we'll walk through it and explain each line of course you can use our code co-pilot explain what it is you want in the function and generate it that way just make sure you have the name that's descriptive the return values and types and the argument set before then because all that gets passed into the bond okay so let's come back here and let's paste in this code and let me explain to you what this does so first we're doing a null check right here that is because this argument is nullable right here we want to make sure we handle that case and we're using a fallback assignment operator right here which just basically checks if this is null then set it equal to an empty list next we're going to skip over and come back to this in a second because it'll make sense after we look at this code right here here we're creating a list of Json objects in this Json list variable because that's what we're ultimately going to return down here and we're mapping over this reversed messages is what we created here and this reverse messages is simply reversing the list of messages and that's because when we add messages into this list it's in the opposite order that we need it to be because we need the oldest messages to be first that's what open AI wants so we're just reversing that messages list our page State variable messages list here then we're mapping we're going through each one of these each one of our messages and we're returning a new object with two properties a role object and a Content object of course this should look familiar from open AI documentation this is what it expects so we're going into each message we're going into the rooll and we're setting that value to this Ro prop this is just how you have to access enums and we're doing the same thing with our content that's the message that the user types in and then we're just calling it to list okay great so let's save this function let's check it for errors and we're good let's jump back to our action flow editor all right so we're making an API call and we needed to convert our messages to a list Jason right here so we wrote a custom function right down here to do that for us so let's grab that and let's dump in our page State variable so that we can convert it into what need there it is confirm and confirm beautiful let's give this action a name here we can just call it API and we only have one API call on here so I can leave the rest of that blank and let's give it a good name we're going to call this new chat fonse so that is the response from this API call will be dumped into this variable right here that we'll have access to later and what do we want to do next well we'll get the response back from open Ai and that's just a message so we want to write that message to our fir store so let's come in here let's add an action we've done this before fir store create document it's going to be a messages document once again we have to set chat reference which we're storing in our page state variable right there so that's easy we've done it before and we need to set our field again it created at the current time let's confirm that then we want to set a role and this time the role is going to be the assistant because it's chat gpt's message that we're recording right here let's close that up then we have the content of the message itself that's coming from a variable it's coming back from our API response and so here's our our new chat response and we can see API response and we've already defined a data type for our response so we want it parsed that way we want to get a data structured field out of there what is it well it comes back in our choices and it's just the first choice so we want item at index and it is the first index I know it's getting long and we want a data structured field out of there and what is it well it's our message and last ly data structured field and content so let's confirm that and let's give this a name we're going to be calling it new chat assistant doc let's give this a name up here this of course is going to be DB message and the assistant Okay so we've made a call we've received back chat gpt's response we've recorded it in our messages collection and now we want to show it to our user users well we know how to do that we update our page State variable but we don't exactly want to do it that way and while we could do it that way I want to make sure we're referencing the canonical source of truth that is our messages database so let's query that collection right here so let's add an action it's going to be a database action and we are going to query a collection The Collection is going to be our messages we of course have to reference which chat it is so this is going to be coming from a variable our page State variable chat reference right here and we want to grab all of the messages out of there next we want it ordered in a certain way and that is we want it ordered by when it's created just like a normal conversation and it will be decreasing then let's give this a name we're going to call this new chat all messages and let's give this action name right here and we can call this DB collection m mesages and finally now we're ready to update our UI so let's add an action right here back in database it's going to be updating page State variable it's going to be our messages and we want to set the value here we want it set to an action output and that is all those messages right there and confirm yes we want to rebuild the page because we're updating the UI so here we can say UI messages beautiful all right so that's a lot of logic but we're ready now to test this out so let's do it all right so here's our app and we can say hi can you help me with something all right great this is working but we see some problems first we need this text to be cleared after we send our message and second we need to deal with the whole other logic of continuing a conversation right now this is only working for new conversation so let's go do those two things so first let's let clear that text field so there's two questions we need to answer first is how do we clear that and we've got an action for that so if you just search for clear you can see we have this clear text fields or PIN codes if you're using that now flutter will automatically recognize your text fields and will populate them here we only have one and it's this poorly named text fieldcore one right here and this is what we want but let's go rename it so there's more clarity so I've got my text F selected right here and if you just go up here to text field let's just call this our prompt okay so now when we go back in and select this we can see that that's updated great the second question is when do we want this logic to execute well let's think about this to answer this we need to know when do we no longer need the information that's in that text field so that text field is the prompt so once we don't need that anymore then we can clear it so I just dropped it in here but that's not a good spot for it because that prompt the message that the user sent in is being used right here so if we open up this content right here we can see it's coming from that prompt so we can move it after here so we can just take this and do this down arrow so we move it down to here and one more time that's great now if the way that you set it up is that you're pulling in that prompt when you make your API call well then you're going to have to move this down even farther but we're not doing that cuz what we're doing right here is we're writing our messages to the page State variable and then passing that in so we're not accessing it so just make sure you don't need to access it after you clear it all right let's go test this out and make sure this is working all right beautiful next let's set up that other stream of logic so that we can have an ongoing conversation and what I'm talking about is this line of logic here so when the user submits from this text field we're checking our chck chat reference that it's set and remember that's that page State variable that we assign to a chat reference when we create one in firestore but the second time the user submits a message this will be already set because we already have an ongoing conversation so what we need to do is we need to duplicate most of this logic into this conditional execution but what we don't need is this logic these two nodes right here that are related to cre creating and storing our new chat document reference so we can just come down here and copy this and copy the action chain which will copy all of the logic from this onwards and then we can just paste it in here but what's going to happen is we're going to get tons of Errors over here and that's happening because in copying all the logic over here we're also copying all of the references so when we reference a different node in a subsequent node those are copied over here the problem is is that we don't have access to those because this is executed only under a different condition but all we need to do is walk through each node and make sure all of the references are correct and because we've done good naming with each of our actions right here we can quickly understand what this is doing and so here we're writing to our database our user message okay great we are writing to our messages collection and because that's a sub collection we need a reference right here and we're referencing our page state so that's nothing localized to one conditional Branch so nothing changed there and to fix all these you can just come up into our debugger here and you can see that all of these are just updating output variable names now because we have this good naming convention we can just switch these new chats to ongoing chats so this first one is what we're on right here so let's just come down here and change this to Ono chat message I'm going to copy this and that went away so let's just go to the next one and so where does that bring it to let's go down here this is our backend call where we're sending this stuff off to open Ai and so let's change this new chat response to ongoing chat response that get that let's go over here and we're mve down to this action right here and this is new this is ongoing and just a few more down here this should be ongoing and we're getting so close and this is actually up here and this is updating the UI specifically our messages and the problem is is that we're adding this new chat messages to the list which is not what we're going for we want ongoing chat new message so if we come into our action outputs right here we want ongoing chat new message right there and confirm and next here we're writing to our messages database and we're trying to write a new chat response here so it's probably in this content right here and that's the new chat response but we haven't changed that in our backend call right here so let's do that first so let's come in here and we're looking for that API response ongoing chat response that's beautiful and we're looking for the content so data type data structure field we're looking for the choices and the item and index the first one and a data structure field we are getting close close messages data structure field and finally content and just give this a default of message and confirm and one last one here let's click down in here and this is updating our UI messages which is probably down here this is our last UI update so after we receive back the response and write it we're going to print it here and we want ongoing chat all messages so we come in here and and we want ongoing chat all beautiful that's all good so let's go test it out all right let's say my dogs name is Hazel and let's ask a follow-up question what's my dog's name now there's going to be a problem here so I want you to watch for it and see if you can figure out what it is did you see that there's actually two problems here one is when we made our second message it just popped it to the top of our message is right here but then when it returned we got back this message but it's the same message as before so what's going on well let's go look at our logic so the second time we send a message we are writing that message as a document in our messages okay that seems all right then we clear that feel that seems normal and then we're updating our UI and we're doing that by adding this message to the list but there's our first problem we're just adding this message to the end of our list list as the last item in our list but we wanted to be ordered by the timestamp and before we ordered them way down here with our fir store query and we ordered it there but maybe there's a better place to order them that's our first problem but there's another problem because you can see that the response back from chat GPT is the same each time which leads me to believe that this isn't the same that it didn't just respond the same but it's actually just writing that first initial message twice so why is this happening well when we copied over this action chain right here you can see that down here in this conditional action we're checking for the new chat response which is the same one as over here so let's come in here and change this from new chat response to come down here and we want our ongoing chat response we want to check for the succeeded property and set that finally let's fix our ordering Pro now there's multiple ways we could do this one way is we could move all of the ordering of our list of messages up into our list view right here and so this message always gets sorted and this will probably be the best and easiest option to avoid duplication of logic but you would have to write a custom function to be able to sort according to those timestamps so I'm going to show you an easier way let's go back into our logic right here and what we can do is before we update this page state right here we can add in a query and so we are going to query a lection here and we are going to query our messages let's grab it from our current chat which is in our page state of course and we want to grab all of the documents and we want to order them by our created time and we want it to be decreasing let's give this a good name so we're going to call it ongoing chat user message and then we'll update our page State variable with that so come here and then ongoing chat user message right there and let's just search for it ongoing chat user message and confirm and so now we can come into our update page State variable and here we're not adding to the list but we're just going to rewrite it so we're going to set the value and we are going to set it to ongoing chat user and that's it right there yes we do want to rebuild the current page and let's go test that out my dogs name is Hazel and now we can say what is my dog's name beautiful now this is the basic setup for how to integrate with gp4 now of course there's a lot of other things you would want to do before you would actually launch this app for instance you could also add in loading animations when you're waiting for open AI to respond storing chat records storing individual chats building out the UI so that you can access past chats implement the streaming features so you don't have to wait for the API to completely respond and you can see it stream in word by word creating titles for each chat you would also want to set up all the logic for air handling for when open AI doesn't respond with a 200 success code if you're interested in seeing any of these features built out leave us a comment below and we'll see you in the next video
Info
Channel: FlutterFlow
Views: 7,487
Rating: undefined out of 5
Keywords: Flutter, FlutterFlow, No Code, No Code Tools, How To use FlutterFlow, Google Flutter, Dart, No Code App, FlutterFlow App Builder, No Code App Builder, firebase, open ai, gpt 4o
Id: L0pWtAX9jJ0
Channel Id: undefined
Length: 34min 21sec (2061 seconds)
Published: Mon Jun 17 2024
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.