Format this text as a blog, make a title, break it into paragraphs, subheadings.
"Dive into the cutting edge realm of artificial intelligence with this comprehensive video course on Google's AI model, Gemini. Guided by Anya Kubo, this course will teach you how to use the Gemini API and how to build an AI chatbot powered by Gemini. If you are new to the world of AI, this is the perfect video for you. My name is <PRESIDIO_ANONYMIZED_PERSON> and I'm a software developer as well as course creator here on Free Code Camp as well as on my own channel. In this video course, we will be learning about AI as developers through the use of Google's AI model Gemini. Now, as some of you may or may not know, we can use AI chatbots in order to ask questions about the world, generate images or even have full on chat using information we've heard in before. But how does this even happen? And how can I build my own AI chatbot? Well, this is exactly what we'll be covering today. In fact, here is a full list of what we will be looking at throughout this video. We will start off with this introduction and then move on to have a look at what Gemini actually is, followed by looking at AI so that we actually understand it. Next, we will look at LLMs or large language models, followed by getting our API key in prep for making our final project. We will then quickly cover tokenization before moving on to some of the models that we can access with Gemini. And then of course, we're gonna build out our AI code buddy. So what are we waiting for? Let's do it. What is Gemini? In the least amount of words, Gemini is a series of multimodal generative AI models developed by Google. Gemini models can accept text and image in prompts, depending on what model variation you choose, and output text responses. What this means is that we can feed in text prompts such as what day of the week is it today and we can receive responses back such as it is Wednesday and not only that we can feed in images as prompts too. So I can feed in a picture of a cat in a hat and we can ask what is in the photo and we should receive back a text response. Pretty cool right? We can do this by interacting with the Gemini app previously known as BART. We can do so pretty easily by typing the prompt here and we can then even see a history of all our previous chats. So here I am writing a prompt in text and receiving the text back as well as continuing a whole chat that takes into account the previous messages I sent. Or here I am uploading images and asking questions about them. Or if you actually want to use this cool technology to build your own apps, you can also interact with the Gemini API. By interacting with the API or application programming interface, we can do exactly what the Gemini app UI does. So for example, putting in text inputs and receiving a text input back by using the Gemini Pro model and the generate content method from it. And we can also use the generate content method from the Gemini Pro vision model in order to prompt with text and or images and receive text back as well as build multi time conversations with the Gemini Pro model using the generate content method as well as some extra configuration. We will also look at creating embeddings using the embedding 001 model with the embed content method but for that we need to understand what embeddings actually are first. We will go into these models and the methods they come with and how to use them individually later on. Just for now, know that these are the most popular at the time of recording and a few more do exist, but we will not be covering them in this particular course. Okay, so we got it? To recap, Gemini is a series of multimodal generative AI models developed by Google that you can interact with via an API or via the app of the same name of Gemini. What is AI? AI or artificial intelligence is the simulation of human intelligence processes by machines. I say simulation as artificial intelligence is not sentient, at least not yet anyways, meaning it cannot think for itself as much as it may seem it does. Often when we say AI, we most of the time are referring to a term called machine learning. Machine learning works by using large amounts of training data that is then analysed for correlations and patterns. These patterns are then used to predict outcomes based on the training data provided. So, for example, if I was to feed this training data, basically summarizing what each paragraph is about, so for example, that we are feeding data saying that a paragraph that looks like this should be categorized as finance, the second paragraph should be put in the category of fashion, and so on. With some code, we should be able to train our AI model to correctly guess what future paragraphs are about. And that's it. So if we were to get a paragraph that says Bad Bunny had some black Adidas sneakers that were from fall 2020 too, this was a great something something, then thanks to our training data, the AI model should guess with some percentage of accuracy that the topic for this paragraph should be fashion. Of course, that is a super, super basic example, and we will need way more data than these five paragraphs right here, but you get the idea. As of now, rapidly improving generative AI techniques can create realistic text responses and even images, music and other media thanks to the huge amounts of training data and talented developers working on it today. Large Language Models Large language models or LLMs are machine learning models sometimes referred to as AI models that can comprehend and generate human language text. So, in fact, we already had a look at a super super basic example of one. It was when we fed training data into our AI model so that it could accurately predict what category a paragraph would belong to. At their most basic level, large language models are like sophisticated autocomplete applications. Just like guessing a category that a paragraph can belong to, we can train models to take an input of text, such as you can lead a horse to water, and have the LLM output text statistically return, but you can't make it drink, as the following text suggestion based on patterns learned from the training data. In fact, you can use this basic property of LLMs for various applications. You can use it to generate poetry, short stories, metaphors, blog posts, and other creative copy, or convert structured data to freeform text, or even extract and summarize information from freeform text, generate code, translate translate or build a chatbot like we're doing today. So now some of you may ask is there a randomness in LLM responses or are they deterministic? The short answer is yes to both. When you prompt an NLM its text response is generated in two stages. In the first stage the LLM process of the input prompt and generates a probability distribution over possible tokens or words that are likely to come next. For example, if you prompt with the input text, the dog jumped over the dot dot dot, the LLM will produce an array of probable next words. So as you can see here, the word fence has the highest probability score as opposed to ledge or blanket. This process is deterministic. An LLM will produce the same distribution every time it's input the same prompt text. In the second stage, the LLM converts these distributions into actual text responses through one of several decoding strategies a simple decoding strategy might select the most likely token at every time step this process would always be deterministic however you couldn't set choose to generate a response by randomly sampling over the distribution returned by the model this process would be random you can control the degree of randomness allowed in this decoding process by setting the temperature. A temperature of zero means only the most likely tokens are selected and there's no randomness. Conversely, a high temperature injects a high degree of randomness into the tokens selected by the model, leading to more unexpected, surprising model responses. Okay, so now that we've understood that, let's work on actually getting our API key to work with Gemini. Just like most APIs, the Gemini API uses API keys for authentication. In this section, I'm going to show you how to get your own API key for when it comes to communicating with the API from the applications that we will be building today. Remember, make sure not to share or upload your API key anywhere public. If you do, someone might take it, use it in their own project, and use up all of your free tokens or rack up a huge credit card bill if you have a card attached. This also includes exposing it in any client-side code. By this I mean building an app without a backend and deploying it onto the internet. The code in this case will be visible simply by inspecting it like so. Someone will then be able to go and take it from here for their own use. To use this key safely, requests must be routed through your own backend server where your API key can be securely loaded from an environment variable or key management service. Okay, so let's do it. Let's get our API key. Okay, so first, we're just going to start off on this URL. Currently at the time of recording, this is what it is. Our going to choose to build with Gemini, which is stickers here, and then we're going to click on AI google.dev. Now you might be required to sign in. Or because I am using Google Chrome, I could just go ahead and get API key in Google AI studio. So I'm just going to click here. And ta da, once you are here, so essentially, you can write prompts here, if you would like, such as what day is it, and hit enter, and the chat will work, you can actually select the model from a drop down here. And you can also select the temperature. The temperature is something that we covered in the previous section. And essentially, as we know, allows us to be more deterministic with our answers. So that is something that you can set, you can be more deterministic or less deterministic. Okay, so we get the response back. Great. Now to get your API key, all you're going to do is click here. So I'm going to go ahead and select that. And we're going to create an API key. So go ahead and select create API key. And I'm just going to search for generative language client. It's actually the only Google Cloud project that we have. And go ahead and select Create API key an existing project. So now we have our API key, make sure to copy this and of course keep it safe. And do not share it or put it in any code that can be visible to anyone on the internet. Okay, cool. That is just because you could use up all your credits. Or if you have a credit card attached, it could, of course, take up all your pennies from your credit card. Amazing. And of course, you can delete API keys and create new ones if you want. So for example, if one is compromised, and that's it. I hope that was easy to understand. Great. Now that we have our API keys, let's get to looking at the available models to our disposal after learning about tokenization. When using long prompts, it might be useful to count tokens before sending any content to the model. If you want to be specific about it, you can use one of the models at our disposal. It is the Gemino Probe model we touched on previously along with the countTokens method. You can get it with this car command. I will show you how to do this in a bit, however, as a general rule of thumb for Gemini models, a token is equivalent to about 4 characters. 100 tokens are about 60-80 English words. Okay, so let's do it. Okay, so all I'm going to do in order to get a template for the code is head over to the REST API. And then I'm going to just go to count tokens. And this will tell me the method that we're going to use from the model, the Gemini Pro model. So we're going to use this in order to write Gemini Pro model. So we're going to use this in order to write our own curl command. So let's go ahead and get our terminal. I'm going to write curl just like so as the header content type, we're going to have application JSON. And then as the content, we're going to have this object, which takes an array of another object, and then the text that we want to essentially find out how many tokens make it up. So as the text, I'm just gonna write, let's go ahead and go up there. Let's do write a story about a magic backpack. And then we're gonna have to put in our API key. So making sure that this is the same. So generative language, google apis.com, for such view on beta models, Gemini Pro, and then the method count tokens. And then we're going to put in our API key here that we just saved. So go ahead and just whack in your own like so and hit enter. And amazing. So we now know that this string, this string takes up eight tokens. Great. And that's it. Models. As we know, we can interact with the Gemini API. By interacting with the API, we get access to all the Gemini generative AI models and their methods, including these popular four right here. As a recap, we can have text only input and use the generate content method to generate a response from the Gemini Pro model given an input message. And we can also use the generate content method from the Gemini Pro vision model in order to prompt with text and or images and receive text back as well as build multi-turn conversations with the Gemini Pro model using the generate content method as well as some extra configuration. We will also look at creating embeddings using the embedding 001 model with the embed content method but for that we need to understand what embeddings actually are first. So let's have a look at how these four work. For this course we will be using Node.js. Make sure to have Node.js version 18 and above installed and npm installed. First off we will need to initialize the generative AI model. We would need to do this for all the scenarios. In order for this to work, you will need to install the SDK package right here. Okay, so here's the code we will be using to initialize the generative model. If you want to have a look at it this time, we're going to be going to Node.js as we're going to start building out in Node.js app. So let's go ahead and do it. We're going to initialize the generative model after of course, installing this package. So let's get up our code editors of choice, I'm just going to create a new project, I'm just going to call this scratch pad. Okay, so just like that, and create it. So here we are has an empty project. And I'm just going to get out my terminal. So I'm going to click here, making sure that we are in the scratch pad. And I'm just going to initialize this. So npm init for this to essentially spin a package JSON file with the correct configuration. So let's go ahead and choose package name default version one description, I'm going to keep empty, I'm just going to literally go through all of these and choose the defaults. Is this okay? And yes, and my package JSON file should be in here now. Great. Now let's go ahead and install that dependency. So I'm just going to go back in here. Let's copy that. And I'm going to do npm install Google generative AI. So please be aware of the version of this package that we will be using for this tutorial. If you are using this in the future, and something isn't working, it could be down to the version you are using, in which case you'll have to revert back to this. So for example, if it's here, let's go back to this and then run npm i again to install this package. But of course, we don't need to do that because this is the version that we want to use for this project. Great. Now while we are here, I'm just also going to write a start script. So start and node, we're going to listen out to changes on an index.js file that is fine. If we want to listen out to constant changes, we can use nodemon. In which case we need to install the package nodemon too. And once that is done, we should be able to use a start script. So this is the script I just wrote to essentially run an index.js file and listen out to changes on it. So let's go ahead and create that index.js file. So it's a JavaScript file, I'm going to call it index.js just like so. Wonderful. So this is looking good. I'm happy with all of this. Let's just shut this down now. Okay, I'm going to make this a little bit bigger for you. So now I can use npm run start. And this will start off listening out to the index.js file that is good. And now we're going to essentially initialize the generative model. So let's go ahead and do this const. And we're going to get Google generative AI from Google generative AI. Okay, so that's how you need to write it. And maybe let's just minimize these for now. So great. Once you have that we're going to get Google generative AI, we're going to pass your API key into it. Okay, so we're going to pass it through so that we can use Google generative AI. For the purpose of this tutorial, I'm just going to pass in the API key like so. And now we have all of its method and properties to our disposal. So let's save them as something I want to save them as a gen AI. Great. Now, if you do want to be super safe, and you don't kind of even want to leave your API key even in here for demo purposes, you can create a ENV file. So you would just go ahead and create a new file, call it dot env. And this is essentially for secrets. So I'm going to call this API key and just paste in my API key in order to access this. So this value by its property. I can now just use process use process. Env and then API key. Okay, however, we do need a package for this. So let's go ahead and do that. I'm just going to open up again, making sure that we are in scratch pad. And we need to install a package called dot env. So that we can use dot env. Okay, in this project, and of course, we need to also require it. So require dot env config. Great. So let's get rid of that for now. And this is still running. Wonderful. So that is now doing its thing. We've initialized the generative model, so that we can now like I said, get all the methods and properties from it. They're all stored under Gen AI. So I grabbed an AI. And for example, I can use get generative model. And we can pick which model we want. So for example, I could go ahead and put model, and then we would put Gemini Pro or anything like that. Okay, so we're going to put in the string of Gemini Pro. And then let's also save this to the const model as that is the model we will be using for this tutorial. Wonderful. So that is it. Of course, if you need to change the model, please go ahead and change the text here, making sure that it is spelled exactly the same as in the documentation, meaning that if you want Gemini Pro vision, it has to be spelled like this. Or if there's any more in the future that you want to use, just again, refer to the documentation to get that spelling correct. Wonderful. Let's move on. This is the final code. Okay, so just to make sure this works, I'm just going to console log out the model. And great. Everything looks as if it's working well. Okay, so now let's move on and work on the generating text from text only input. When the prompt input includes only text, okay, we just want text, we want a text prompt, and we want some text return back to us from the model. For that we need to use the Gemini pro model with the generate context method. Okay, so that's what we're going to do next, I'm going to show you how to do it. So this I would say is the most basic one, I would, of course, need to initialize the model. So let's go back to where we left off. So here we are where we left off, I'm just going to get rid of this console log. Once again, this is me initializing the model so I can use it. And once we have done that, perhaps let's go ahead and write a function for this. So I'm going to make this an async function. Let's call it run just like so. And in this function is actually where I'm going to define what model we want to use. So I'm just going to work that in there like so the model is going to be Gemini Pro. As we said, the next thing we need to do is define a prompt. is going to be Gemini Pro. As we said, the next thing we need to do is define a prompt. So that prompt again, maybe let's keep it the same. So write a story about a magic backpack. And now let's get the result. So we essentially need to send over that prompt, right. So we're going to get this prompt, and we're going to put it in to the generate content method. And it lives on the Gemini Pro model. So let's grab that model. And let's get the generate content method from it. And I'm just going to pass through the prompt. And we're gonna have to await this as this is an async methods, we're gonna have to wait for that to come back to us. And once we have that result, we're going to get the response from it. But this is also async. So we need to await it. And let's save the return of this as something I'm going to save it as response. And once we have that response, I'm going to get the text from it and call it like so and just save this under text. Okay, so that we go. So let's just console log this text out so we can see what is going on. And I'm just going to call this function. So just like that, let's hit save. And great. So this is the text that comes back. So we've prompted the text of write a story about a magic backpack. And we get a story about a magic backpack, we get the text coming back to us. So in the quaint little town of willow creek amidst rolling hills and whispering willows there's a curious young girl named and yeah no way that is me little did she know that the ordinary backpack held a secret that would change her life forever so this is pretty cool i don't know if that's kind of creepily meant to be based on me or if that is a complete coincidence but I'm really into this. I will read the story when I have time. Wonderful. I'm really happy with this. Once again, this is the full code that you will need in order to create text prompts. Okay, so now let's look at generating text from text and image input. So this is multimodal. Gemini actually provides a multimodal model called Gemini Pro Vision. So not Gemini Pro, it's Gemini Pro Vision. And we can input both text and images if we want. So let's go ahead and do it. I'm going to show you a super basic example so you can build out your node.js out with it. Once again, we're going to be inputting both text and images using the Gemini provision model with the generate content method from it to generate text input. Okay, great. So this time what I'm going to do, well, let's go ahead and go back to where we started. So let's just going to move this out here and delete this whole function. So here is where we started off last time, we did say we want the model to be Gemini Pro vision. So I'm just going to replace that. And now we're going to also require another package that's going to allow us to essentially work with image files a little bit better. It's the package called FS. So FS require FS, which means we need to install it. So once again, I'm going to do npm ifs. In order to install that dependency, you will see it show up in the package JSON. So if you look in here, this is the version of FS that we are using. So just keep that in mind. And once again, revert back to this if you're viewing this in the future, and something doesn't seem to be working. Great. Let's move on. Now we're going to first have to convert local file information to a Google generative AI part object. And in order to do this, I'm going to write a function. So the function here, I'm going to call it file to Jen narrative narrative part, I'm going to pass through two things, a path, and a mime type. Okay, and then we're just going to return an object and write in line data. And this is also going to be an object, we're going to pass through some data to it, which essentially we're going to buffer from FS read path. And then we are going to get all of this and append to string base 64. And we're also going to pass through the mime type. Okay, so whatever we pass through into this function, we're going to put here and here. So that essentially will create a generative part to our files. Now let's go ahead and write our async function again, that will run this thing. So async function, run, just like so, once again, we're going to get that model. So define our model in here. And then let's also define our prompt. So const prompt. What's different between these pictures. So just like that, and then let's get both our images. So image parts, we're gonna have two, I'm going to use the function we just wrote, and we're going to pass through the file. Okay, so I'm just going to put the files, I'm going to put two in, I'm going to put a picture of a cat. So I'm just going to put it on the same level as the index.js. So we can just write the file name. So there we go, there is I'm just going to type out so cat dot jpg. And this is an image jpg. And then let's do the other one. So this time, I'm just going to drag in another picture, this one is going to be of Rick and Morty's, we have this one, and then we have this one too. Okay, so now I'm also going to write the path to the Rick and Morty's we have this one, and then we have this one too. Okay. So now I'm also going to write the path to the Rick and Morty file. This is a JPEG file image JPEG. Okay, again, we can just put through the file names as these files live on the same level as the index.js file. Great. So those are the two images we will be comparing. Now once again, let's work on getting the result. So const result equals we're going to await the model, we are using the generate content methods, and we're going to pass through an array. So we're going to pass through the prompt and the image parts. Okay, this generate content method lives on a different model this time it lives on the Gemini provision model. So we can pass through two images along with the prompt. And now once we have that, let's get the response. So rest, once equals result, but we're going to have to await it. And we're going to get the response. And then we're going to get the text. So let's define that text. And we're going to get the response. And we're going to get the text from it like so and just console log out the text. So great. Now let's run this. So just like so. And ta-da, the first picture is of a cat and the second picture is of a character from the anime series, one punch man. I don't know if that's true. I'm pretty sure it's Rick and Morty. So I don't really know what one punch man is. But hey, that's close enough. Okay, so great. That is how you would essentially use the generate content method from the Gemini provision model. Let's move on. So I'm just going to clean this up in the next one. Let's get out this model, I'm just going to put everything back to where it was. And I'm going to delete everything in here. So we can start with this and we don't need that one either anymore. Now let's look at building a multi time conversation chatbot. So using Gemini, we can also essentially create chatbots that will essentially take all the history of your chat previously, in order to take into context your next questions. To build a multi time conversation. So like a chat, we're going to use the Gemini Pro model and initialize the chat by calling start chat and then you send message to send a news and message which will also append the message and the response to the chat history. Okay, so there are two possible options for roles associated with this, we're going to have the user and this is the role which provides the prompt. And we're also going to have the model which is essentially the role which provides the response. This role can be used when calling start chat with existing history. So let's go ahead and do it. Let's go back to our code. So once again, this is the start point that we have started at throughout this course, I'm going to change the model to be Gemini Pro. So that is now our model. So let's go ahead and write our function. So I'm going to write an async function, let's call it run. So just like so. And now what we're going to do, well, I'm just going to stick that in here, like we have been doing previously. And let's go ahead and essentially start the chat. So I'm going to get the model. And it comes with a method called start chat. So start chat is the method that we're going to use. And we're essentially going to pass through an object. Let's go ahead and also store this as something. So I'm going to save this as the const chat just like so. And in here, well, we're going to pass through the history, it's going to save this as the const chat just like so. And in here, well, we're going to pass through the history, it's going to be an array, this is going to be multiple objects in here. The first object is going to be of the role user. So let's pretend this is a previous question that we asked. So I'm going to say that as the user I asked, Hello, I have two dogs in my house. So less of a question and more of a statement. And then let's also say that the model responded with great to meet you, what would you like to know? know. Okay, so that is the history essentially. Now let's also define our message. So let's define our message here. And we let's say we want to ask a follow up question of how many pools are in my house. Okay, so that is a good message. So that is really it, we've got the history, we've got the new question we want to ask. So let's go ahead and get the result, right. So results equals, we're going to await chat. Okay, because that's what we've defined here. And we're going to send message. that's another method that comes with it, we're just pass through the new message like so. So once we have all of that, so the history and our new message, I'm going to get the response, I'm going to await the results, response. And once we have that, we can need to text from it to text, response, text, I'm just going to console log out the text. Don't forget to call this as well. And now let's run this function and call it. And great. If you have two dogs, and each dog have four paws, then there are eight paws in your house. Amazing. So this is what we're going to be using in order to build our own chatbot coming up soon for the final project. Let's just look at one last thing and that is creating embeddings next. So once again, I'm just going to get rid of all this, let's move out the model. And let's start with this code so we can start fresh. Now finally, I want to talk a little bit about creating embedding. This is a bit more on the advanced side. And betting is a technique used to represent information as a list of floating points, essentially. So floating point numbers in an array. With Gemini, you can represent text words, sentences and blocks of text in a vectorized form, making it easier to compare and contrast embeddings. So for example, two texts that share a similar subject matter or sentiment should have similar embeddings, which can be identified through mathematical comparison techniques such as cosine similarity. So that is what an embedding looks like. Essentially this array of all these numbers represents a word or a sentence. And this is how we essentially look for terms with similar meaning. So similar semantic meaning. If you want to learn more about embeddings, please do check out this amazing video that I have on free code camp, there'll be a deep dive into this subject. For now, however, I'm going to show you how to make your own embeddings. So let's go ahead and do that. So this is going to use the batch embed content method, or the embed content method that lives on the embed 001 model. So let's go ahead and change it up. So we're not going to use this model anymore, we're going to use embedding to 01. Okay, and let's go ahead and define our function again. So async function run. Let's move the model into here like so. Let's get the text. The quick round Fox jumps over the lazy dog. Now let's get the results. Await model. And bad content is that is the method we're going to use, I'm going to pass through that text. Okay, and now let's get the result and get the embedding from it. And I'm going to save this under the const embedding just like so. And let's just console log out the embedding. Okay, and if I run this, you will see that this piece of text, the quick brown fox jumped over the lazy dog is represented by this vector. So this array full of all these numbers, okay, all of these right here, this is the embedding, it's got 668 more items. And if you were to perhaps change this to the quick brown fox jumped over the lazy cat and run this, this embedding that is created will be more similar. So this one right here will have more similarity in numbers to this one, then perhaps the quick brown fox jumped over the lazy helicopter, okay, because cat and dog are relatively similar, as opposed to a helicopter. So that is a quick crash course in embeddings and how essentially they're used in order to find words of similar meaning. So I hope that was really interesting. Once again, do check out that vector embeddings video if you do find this interesting, I would like you take your knowledge to the next level. Otherwise, let's move on. Let's actually get to using one of these to build out our project coming up soon. Okay, so let's do it. I'm just going to go ahead and create a new project. So let's go ahead and select new project. And this is going to be a react app. So this will essentially spin up a react app for me thanks to the MPX create react app command. So let's go ahead and call this something I'm just going to call this Gemini app. Maybe let's stick react to the front. Okay, so this is essentially going to be stored in my webstorm project directory on my computer. I'm just going to click Create and wait for that to spin up the app along with all the pre configured files that we need. So this is wonderful. This is going to save us a bunch of time. Let's just wait for that to do its thing. In the meantime, I'm just going to go to the Gemini documentation. So here we are, here's the URL if you need it. And we're just going to work on getting our API key. So let's go ahead and build with Gemini. And let's click on this link right here, AI Google Dev. And it should take us to our dashboard. Of course, please do make sure that you are signed in. So I'm just going to go ahead and sign in here. And I'm just signing in with my Google account. So please go ahead and do the same. And now we are free to get our API key. So that is something we're going to do. As a reminder, I'm just going to go to the API docs here, what we're going to be doing is creating an app that uses the Gemini Pro model. And now we're going to just go to node.js as we are going to be building in node.js for this project. And we're going to build a multi turn conversation chat. So if you click on here, here is build multi time conversation chat, we're going to use the Gemini Pro model for this allows to do so. And essentially, we're going to be taking this code from here. So if you get stuck, please refer to the documentation. For now, however, we also need to get our API key. So let's go ahead and do it. You scroll down here and click on get an API key, just click on here and it should get a key for you so that you can communicate with the API. However, make sure to keep this safe. You don't want someone stealing your key and racking up loads and loads on your credit card if you choose to attach a credit card to this eventually. So let's go ahead and do this. I'm going to head over to Google AI studio. Get API key in Google AI studio. And you should be able to get the API key. Now if you can't, it could be because it is not available in your region. So just keep that in mind. Great. not available in your region. So just keep that in mind. Great. Okay, let's go back to our app. So once this is done, you will see all the node modules that you need, as well as the source directory of all the files that have been added, as well as a package JSON, along with all the dependencies that we will be using so far. So these are the latest dependencies and the versions of them that we are using for this far. So these are the latest dependencies and the versions of them that we are using for this project. Please make sure to always keep the dependencies the same version. Okay, just in case you're doing this in the future. And you know, something's changed, and you want to still build this app, just revert back to these versions that you see here, as well as the versions that we will be installing. So first off, however, I'm just going to clean this up a little bit. So on the index.js file, I'm just going to delete the report web vitals from here as we will not be doing that. We also won't be doing any testing and I'm going to get rid of the semicolon just because that is my personal preference. So that is all that should be in the index.js file. Just save that. Like I said, I'm just going to delete these three files right here. So the logo, the report where vitals and the setup tests. So just do the same delete anyway. Now in the index CSS, we're going to start from scratch, I'm going to delete everything from this file, the app test.js is also going to be deleted as I don't want to do any tests. So notice for you today, let's also get rid of the app CSS files. This is a small app. So I'm just going to keep all the styling in the index CSS file. And now the app j s file once again, I'm just going to essentially delete all of this from it. And it's delete all of that so we can start fresh. So that should be in here, I'm going to make this a functional expression as well, just because that is my preference. Okay, great. So all you should have in the source directory is this app JS file that looks like this, the index CSS file that is empty and the index JS file which should look like this. Wonderful. Let's move on. Now let's go ahead and store our secret somewhere. So I'm going to create a new file to dot env file. And we're going to add our API key in here. So our Google generative AI key. So let's go ahead and call this Google gen AI key, you can call it whatever you wish. And I'm just going to paste in my unique key like so. Great. And that's it. So now we are ready to continue, we essentially can start building, I'm just going to build out a simple front and forth so we can get started with the media stuff soon. So let's go ahead and do it. Let's go ahead and create a simple chat. So in here, what I'm going to do is let's create a wrapping div, let's give it a class name up. Let's also have a section in here, this is going to be the search section. So I'm let's give it a class name app. Let's also have a section in here, this is going to be the search section. So I'm going to give it the class name of you guessed it search section. It's going to minimize that for now. And I'm just gonna have a paragraph element. What do you want to know? Okay, and then let's have a button that says surprise me in case we you know, want to be surprised with something. So sir, fries me just like that. Let's maybe also give this a class name, I'm going to give the class name of Sir prize. And in fact, what I'm going to do is actually put this in the paragraph element, you will see why. So in fact, maybe let's run this, I'm going to get up my terminal. And I'm just going to do npm run start. And in fact, because we're going to have a front end a banner backend, I'm going to get that script, I'm just going to define it as the front end script. And we're also going to have a backend script. Okay, so backend, and this is going to be no demon. So that's a package that we're gonna have to install to listen up a constant changes on the server JS file, which we are yet to write, that's going to hold our whole back end. So maybe let's go ahead and create that file new file, it's a JavaScript file, I'm going to call it server j s. Okay, cool. And let's continue. So before we forget, let's actually install that package. So maybe let's go ahead and do that now NPM I know the one and that will essentially install it. So it will just add to these dependencies right here. No, the one has just been added along with its version. So okay, let's start off front end, I'm going to do npm run start front end, again, making sure you're just in the app. And tada, it's spun up our front end along with the elements that we've essentially added, I'm just gonna inspect this so we can work with it a little bit better. Great. This is looking good. Let's move on. So let's just minimize that for now. And let's continue adding elements. So we've got that P element. Next, I'm going to have a div. And let's continue adding elements. So we've got that P element. Next I'm going to have a div. And this is actually going to be a container. So I'm going to wrap, let's call this the input container as this container is going to wrap an input element. So here is my input element. And as all inputs, it's going to have a value at the moment, I'm just gonna leave it like so. Let's also have a placeholder for it. Maybe let's have something like when is Christmas? Okay, very simple question. We'll have an on change, which will essentially change the value for us and save it in the state of this app. But for now, I'm just going to keep it empty. Of course, we haven't written that function yet. Cool. I'm also going to do something and I'm going to have a button here. It's going to say ask me and then another button. So we're gonna have two buttons, but we're going to show them conditionally. So ask me or clear. So at the moment, you can see both buttons, but I want to be able to only show the ask me button. If there's no error, then show this button. So if this is true, show this element. However, if there is an error, then we show this button, which means we need to save that error. And I'm going to save it to state. So we might as well just go ahead and import use state from the ads, we're not going to be using use effects. So let's get rid of that. And now I can set the error. So that is the syntax for saving state to the app. Okay, at the moment, there is no error, we can actually just keep this as null for now. Or in fact, this is going to be a string. So I'm going to just save it as that. At the moment, this has been assigned to the value of error. And if we want to change it, we use set error. So if there is an error at the moment that isn't, we should see this because there is no error, right. So let's have a look. And the Ask Me button is showing. However, if I change this to some thing when is wrong, save it, then it will say clear because an error does exist. Okay, so hopefully that makes sense. So we have those two buttons. And now outside of this div, let's also show the error if one exists. So if an error does exist, I'm going to show this P element that shows the error. Otherwise, if it doesn't exist, this won't show at all. Cool. Now we're also going to have a div. And this is actually going to show the search results. So you know, whatever comes back from the API, but of course, there's gonna be multiple, it's going to be a history. So it's gonna be multiple chance. So class name, search result, I will call it. And here, we're going to essentially map items onto something, it's going to be a div. And this div is going to hold a p element, that is just going to be the answer. So let's go ahead and give this the class name of answer. Okay, and this div will have a key because when you map onto things, you need a key. So I'm just going to leave that blank for now. Great. And that really is it. Okay, hopefully that was painless. Of course, it doesn't look very nice for now. The magic of styling will literally transform this. So let's go ahead and do it. I'm just going to go ahead and get my index CS file. So let's get into the source, let's get an index CSS file. And now all I'm going to do is going to say that all the fonts or font family is going to be sans serif, no backup, okay, sans serif, being really basic here really kind of streamline this project, margin zero, padding is going to be zero, let's make the whole width of this 100 of the viewport width, the height of this 100 of the viewport height, And then the background color is just going to be like this off white that I picked out earlier. And then the text color again, it's not going to be black, it's going to be a gray. So that's the shorthand for writing 77767. Display, flex, we're going to initialize flex box, just so we can make sure that everything is in the center from left to left. Great. All P elements in here, again, I'm just going to change the font weight to be 200. And I'm going to change the font size as well. So I want the font size of all the elements, the P elements to be exactly 14 pixels. Now the app itself, so the element with the class name of app, so this one right here, I'm going to go ahead and make sure that it's with a smaller, okay, at viewport width, and I'm actually going to give it a margin of 10 viewport width again to make up for to that 100. And the height is going to be at viewport height. Okay, great. And that's going to contain everything in it. I think what shall we do? Let's have the search section. So that is the first element in there. I'm just going to make sure that it's 100% of the element with the class name of app, the height of it is again going to be 100%. Let's use this place flex and direction column to make sure everything goes from top to bottom. And that's really it. Okay, so that section essentially is the same as the app. So perhaps we can even go out and just give this the class name of app and just make this a div. So I'm just going to delete that for now. Okay, we're really streamlining things here. So there we go. And this just means that I can, let's go ahead and add this like that and get rid of this search section completely. Great. Now let's go ahead and get the search results. So the search results is here, it lives inside the app. results is here it lives inside the app. So maybe format this a little bit better. So I'm just going to use webstorm to code a format code. And that is much better. So these search results. Singular, make sure that is singular. I'm going to do margin top to space it out from the element above 10 pixels. And I'm going to do overflow scroll. So we can scroll through all the results, we don't have to scroll the actual page. Okay, great. Now let's pick out the little things. So I'm going to pick out this button by the class name of surprise. So dot surprise, let's give it a background color, I'm going to go ahead and use another color that I have pre picked out EC e c f1. I'm also going to change the color of the text to be black. And then let's get a border radius of five pixels to round it off. This should be that. And let's also add a font weight to this text. Let's go ahead with 600. And the padding, four pixels on the top and bottom and 12 pixels on the left and right. The margin of this again, this I'm going zero at the top zero on the right two pixels on the bottom, and five pixels on the left. And the border of this is going to be none. Okay, so if you're interested in how this is looking so far, here we go. This is looking good. Let's carry on. So now I'm going to style the input container. So I'm going to find the element with a class name of a container, the width of this is going to be 100%. And now I'm going to add a border to this, it's going to be a solid border 0.5 pixels and width and again, ca ca ca is the color I have picked out for it. The box sizing of this is going to be border box so that the board is actually on the inside. And let's round it off. So border radius, maybe let's make it six pixel this time and the box shadow I'm going to give it is going to be RGB a for transparency 0082 with 0.15 opacity okay and once again we're going to be a blur a spread and great now inside the input container, I want to grab the input that lives in it, I'm just going to get rid of the border, the padding for this. Let's go ahead with 13 pixels on the top and bottom and 14 pixels on the left and right. Once again, box sizing, I'm going to go with border box. The font size, I'm going to go with 15 pixels. Outline none, this will just get rid of the blue outline when you interact with the input. And the width of this is going to be 90% of the parent with a font weight of this being 200. Okay, so now the input looks like this, I'm going to use display flex on this input container so that each item is kind of next to each other the rather than stacked. And there we go. Let's do the button next. So in fact, maybe let's also work on the placeholder text. So I can do this by grabbing the input that lives inside the input holder. And then if I want to get the placeholder text, I can change it like so. Yeah, let's go with this color. And let's just make this a little bit like that. So there we go much better, in my opinion. Okay, now let's do the button that lives inside the input container. So any button that is inside the input container is going to have this styling, I'm going to give it a min width of 10% border, of course, it's going to be none. And let's also just add a border on the left side, okay, to differentiate from the input. Let's give it one pixel solid. And yeah, I'm happy with that gray. Let's also make sure the background color is white and the text color is going to be this one that I used before the font weight, I'm going to go with bold and cursor, I'm going to add a cursor that is a pointer just for fun. Okay, just make sure that that is like that. And let's see what it looks like. So I love this so much. Let's move on. I think maybe let's add overflow hidden to the input. So once again, let's go maybe to the input container this time. I'm just going to go with overflow hidden, just so that this is a bit more rounded off at the edges. Wonderful. Okay, that's nearly finished. So I'm also going to add some styling to any button that lives inside the input container. And if it's active, so this is how you grab an active button that lives inside the input container. And if it's active, so this is how you grab an active button that lives inside the input container, make sure that space is there. I'm going to just change the background color to be ca ca ca. So kind of grayed out when it's active. And finally, let's also style anything with the class of answer. And for us that is these P elements. So I'm just going to go ahead and add a padding to each one of 13 pixels at the top and bottom 14 pixels on the left and right. Let's also add a border of solid 0.5 pixels, ca ca ca. Okay, so kind of similar styling repeating. I'm also going to give them a background color. Let's make it white. So hash FF F, a margin of five pixels, a font size of 15 pixels, a font weight of 200 and a border radius of six. So wonderful. I'm really happy with how this is looking so far. Okay, let's work on linking up the surprise me button first. So let's get rid of this for now. And up here, I essentially want to get a random value to work with. So we've saved errors. Another thing I want to save is the value and the value is simply going to be the text that we are writing in here. We also want to generate some randomly. So this is super simple to do. All I'm going to do is define our surprise options like so and it is going to be an array. So that is good for us to use. And I'm just going to put in some random options. So who won the latest? No bell? Peace? Prize can be one question. We can also have where does pizza come from? That's a great question. And how do you make a BLT sandwich? And clearly very hungry because these are all very food focused pretty much apart from the first one. So once we have a surprise options, I'm just going to write a super simple function, const, surprise, and all it's going to do is get a random value from this array. So in order to get a random value, yes, thank you, tab nine, we get the surprise options, we open up the array, we then get math floor, which will round down we open up the array, we then get math floor, which will round down to the nearest integer. And we simply get the surprise options length and multiply it by math random. And math random will return back a number from zero to just under one. So if you multiply it by the length, it will always be just under three, and we round it down. So it could be either zero, one or two. And we pass through zero into the array, we'll get about this, if you pass through one, we'll get this. And if you pass through two, we will get that. So that is how we get a random value. And then I'm going to get random value, I'm going to pass it through to set value. So we're essentially at the beginning setting value to be this. However, if we call this function, we will get a random value from here, and reset this value using set value to be one of these three. So now where should we do this? Well, I think if we press the surprise button, right, so on click of this, I just want to call that function. Okay, wonderful. So maybe we should also add an option to disable this. And I think this should be disabled if a chat history already exists, right? So maybe let's set const chat history, set chat history. And this will be an empty array. So now if chat history exists, we want this to be disabled. But for now, of course, it's not. And the other thing we want to pass through here is the value. So we can actually see it in the input. So on change, we also need to set value of this, I'm going to pass through the E target value of whatever we type into the input itself, of course, we need to make this a function like so and pass through E. So now this value, so this value here can be changed in two ways, right? Either if we click here on surprise me, or if we start typing in here. So let's try it out. Maybe as chat history, you know, is an empty array up here, we should probably change it to something. If no chat history exists, then we can do it. There we go. So this is looking good, we're getting a random value each time, or we can type in our own question like so. And that will be saved to the value here. So we can send it over to our API. So let's do it. So let's go ahead and write a function here, I'm going to call it get response as that is essentially what we want to do, we were going to get a response from the API, just make sure to spell response correctly. This is going to be an async function. So let's just go ahead and work that in here. First off, however, if no value exists, and we essentially click on the Ask Me button, right, so if you click on here, and no value exists, and we essentially click on the Ask Me button, right? So if you look on here, and no value exists, we want an error to show up essentially. So I'm going to set an error. And it's just going to say error. Please ask a question. Okay, and we can of course show that too. So maybe let's go ahead and put that here we already have so that will show up if there is an error. And we're just going to return out of this. Great. Now we're going to try some things. So try and catch we're going to use the try and catch blocks. We'll try something and if it doesn't work, we're just going to catch any error with a console error, the error and we're also going to set the error. So we're not going to use what comes back to us, I'm just writing a super basic error that doesn't really give us much insight into what went wrong. But if you want to take this a step further, please do you can use this error to write some custom error messages. Cool. So that's what we're going to do. And now what we're going to send over to the back end. Well, I think we're going to space this out a bit. We're going to define our options first. Okay, and this is going to be a post method, we are also going to be sending over the whole chat history. So I'm going to use Jason stringify, I'm going to create an object. And in that object, we're going to send over all the chat history. Okay. And we're also going to send over a message message which is the latest text that we want to send through. So essentially, we're sending over whatever we type in here. And if there is a chat history of previous questions, we're going to send that over as well. Great. Let's also set our headers. So we're going to choose content type JSON for that that is correct. And now as the response, we're going to await fetch, and we can set our own endpoint. So let's say that we want our backend to be on port 8000. And I'm just going to make the endpoint Gemini, and we're going to send through all these options with it. So that is our response. And of course, once that comes back to us, we're going to get text from it like so and save this as something we're going to await it though, as it isn't asynchronous method. So we need to await that and then let's save it as data. And I'm just going to console log the data for now. So we can see what's coming back. Great. So now let's actually work on our backend. So in here, like I said, we're going to define the port, I did say this would be port 8000. So that's all I have done, we are going to have to import a few packages or dependencies to help us here. So let's just go ahead and open up a new tab, making sure you're still in react Gemini app. And I'm going to install Express, which is going to help us with the routing cores, which is going to help us get rid of those pesky blocks by calls messages, when you're sending stuff from the front end to the back end, and so on. We're also going to use the dot env package to store secrets in our env file, as you just saw, and we are also going to need Google generative AI. So let's go ahead and import that too. So great. That is the packages that we're going to need for this project. So let's just wait for that to do its thing. And let's continue. So of course, we're going to need Express require Express. And we're going to wait for all of this wonderfulness from the package to come back. And we're going to save it as express. And once we have it, we're going to release it. So this will essentially release methods and properties that come with express. And if we save it under a constant, for example, app, we can now use app to get any methods. So for example, the use method from it. So great, we're going to do that we're also going to require a course of const. course, require cause again, this is to get past those pesky blocked by cause messages when sending stuff from the front end to the back end, and so on. And we're also going to also pass JSON from the front end. So hence, we need to use Express JSON here. Great. So let's just minimize that for now. We also are going to require and we did import the dot tmv package so that we can essentially work with secrets like our Google API API key. Cool. The other thing we're going to do is get Google generative AI from choir. And then the package at Google generative AI. Okay, so there we go, we've got everything nearly set up. The other thing we're actually going to do is get that API key that we stored in our back end. So I'm going to use Google generative AI. And I'm just going to pause through that API key. Okay, I'm going to pause it through here. So we can just go process, env. And then whatever we called our API key in a dot env file, which was Google gen AI key. So I'm just going to paste it in like so. Okay, wonderful. Let's move on. I'm also just going to listen out to check that everything is working as it should pass me the port as the first parameter. And as the second parameter is a callback function, I'm just going to do console log listening on port and then our port number. Cool. So now if we run this, so for example, here in the package, Jason, we did write our script to listen out for anything on the server j s file. So now I can do npm run, start back end and it should start back end listening on port 1000. Everything is working as it should. Cool. So now let's write our route, we wrote a post request to the endpoint Gemini, as you saw here. So now what do we want to send over to this back end to this endpoint? Well, it's essentially all of this, right. So let's actually do that. And you can send stuff over and you can get it by going to rec body. And then that should bring back this whole body right here. And if you want to get the history from it, I can simply do dot history. So maybe let's actually console log this so we can see what is going on. And I'm also going to console log the rec body message as that is another thing that we are sending over. So let's just see this works for now I'm just going to get up here my back end so we can see what's being sent. So now if I go ahead and send some text, when is Christmas for example. And now let's hook up the Ask Me button. So let's actually get this whole get response function and attach it to the Ask Me button. So on click of this, we want to get a response. So let's go ahead and do it, ask me. And let's go back in here and look in the server js file in the terminal, we get two things being console that we get the history, which yes, is an empty array, as we set that up here. And we also get the value which is when is Christmas. So we save the value up here. But then we also said the value should be the message. So great, we are sending stuff over we're sending over the chat history and the value, because we are going into the request body history and into the request body message. So request body history request body message, we're sending that over now let's send it over to Google. So let's go ahead and do it. Okay, all I'm going to do is get gen AI. Once again, this is just from the documentation that I showed you earlier, we're going to do get generative model. And we're going to pass through the model that we discussed. So let's define the model here. It is the Gemini Pro model. And I'm just going to save this as model. So we've just defined it. This should be Gen AI as we defined here. And now let's define the chat. The chat Well, we're going to get the model and we're going to use the method start chat that comes with it. I'm going to create an object. And we're just going to pass through the history, which again, we already have it's this request. Body history. Cool. And now let's also define a message. So we define our chat. And now the message is just simply going to be request body message. So that's a lot simpler. Okay, so I'm just going to delete that for now as we don't really need it. The next thing we need to do is actually get the result of what comes back. So const result equals, I'm going to await, we're going to get the chat. So what we defined here, we're going to send a message, I'm going to send through this message to the chat as well. So along with the history, we're sending through the message to, and now we're going to get the result. And we're going to get the response from it. And as this is a going to get the response from it. And as this is a asynchronous function, we need to await it. And let's save this as the response. So just like so. And then we get the response, we need to get its text. Okay, and let's save this as text. So just like that. Okay. And now I'm just going to do res send the text to send it back to our front end, make sure this is send message. And once we get it back here, we're at the moment we're just console logging out. So now all I need to do is essentially map them onto here, we need to save the history. So I'm going to set chat history. However, when working with arrays, we need to essentially set the old state which I'm going to choose to call all chat history, we need to release it back into the array. And then the data. Well, I'm going to actually create a new object that is in line with the data that already exists. So the way that Google modeled it, so we're going to have a user and the user essentially asked this question, which is our value. And then we're also going to have another object. And this role is going to be the model. And it's going to be what comes back to us. So this is what the model said, or essentially the AI said, and it's going to be the data that comes back. So the piece of text, great. And once we have done that, we can set the value to be an empty string again. Wonderful. So now that we have that chat history, I'm just going to scroll down here, and we're going to map it onto this. So let's get the chat history. And we're going to map, we're going to map it onto this whole div just like so. And what we're going to do is map let's open up our parentheses once more. And we're going to map each chat item. As well as the index, I'm going to pass through the index as the key, it's not really used, hence I use this. And now for each chat item, I'm essentially going to put it in here, I'm going to get the chat item role. So it's either going to be user or model. And then I'm just going to get the chat item parts. And wonderful. I'm really happy with this. And maybe let's format this file once more. The last thing I want to do is just clear the history, the value and the error if we want to clear everything. So I'm going to do so on the clear button. So on click of this, I want to clear right. So let's define this function. Let's just do so here. So const clear. And I'm just going to set the value to be null set error to be null and set the chat history to be an empty array again. Great. And that's it. So let's try it out. I'm just going to type in when is Christmas. And if you hit ask me, it should come back with two messages. That was my message. So when is Christmas and then whatever the model responded with, which is December 25. Now I can go ahead and ask a follow up question to this conversation, meaning it's taking into context the previous messages. So I can simply write Are you sure? Obviously, are you sure by itself won't mean much but with the context we know we're talking about Christmas. So if I type in Are you sure the model will come back with Yes, I am sure that Christmas on December 25th. Okay, and then you can continue with other questions. So it will continue the multi chat conversation. Amazing. So this is working as it should. I love it. Let me know what you think below."