Video: Building an AI Inbox Agent | Duration: 4852s | Summary: Building an AI Inbox Agent
Transcript for "Building an AI Inbox Agent": Alright. Hello, everyone. Good morning, good evening, good afternoon from wherever you are joining. I am super excited for this workshop. I have been doing a lot of these things that I'm gonna present today, and I'm gonna help you with that today. But before I do that, I would love to know from where you all are joining in. I see a couple of messages. Sanjay says, hello. We got hail. I hope I'm pronouncing your name right. You're joining in from Zurich. We got some from Portugal, Netherlands. Awesome. I love it. We got folks from across Europe and India. That's fantastic. We got Switzerland, London again. That's fantastic. Alright. So let me start with sharing my screen. I am gonna try to figure out the controls for this. I have done this before and I should know it, but every time I am doing it, I'm like a bit confused. So I'm like trying to figure it out. Give me a second for that. I'm gonna try to see. I know. Over here it is. I'm gonna allow, and I am gonna share the entire screen. So now you all should be able to see the screen with my slides up over here. So what we are gonna do today, I don't know if you all got a chance to look at the announcements that we had last week. So last week, we had something called Agents Week, where we made tons and tons of announcements of the new projects, all the products that we launched from Cloudflare. One of them was email sending, and the community just loved it. I would be talking a little bit about it, but not get too much in-depth about it, because I want to, help you cover the basics of how you can build an agentic inbox. Now, before I do that, let me do a quick introduction about myself. My name is Herschel. That's a book that I wrote a while back. So if you are interested in, like, local building your own local LLM, powered Raspberry Pi assistant, you can go ahead and check that out. I work as a senior developer educator at Cloudflare. And when I am not doing that, I love to build. I have kind of four applications which are in production. And this workshop is also gonna be kind of a story of how I am trying to solve one of the problems that I have with managing four different projects. Alright. I tried a fun thing as well. So for everything that I am gonna share today, you can email on this particular email at slidesfastfly. Dev and get the slides in your inbox. It would take one or two minutes for the LLM to process your request. But once it does, you will get these slides as well as, the GitHub repo that we are gonna use for this workshop. So I'm gonna leave it over here for a couple of, minutes so that everyone has the slides up on their screen. And there is also a fun little element that I try to add to my slides. So there are a couple of emojis that you can see on the slides. You can interact with the slides live and kind of give me a live feedback. Right? So over here, go to this, slides. Open up your inbox and send an email to slidesfastfly. Dev, and you can get the slides and the GitHub repo for yourself. Alright. While I am gonna wait for you all to get yourself the resources, I'm gonna, you know, blabber around so that we don't get into the awkward silent situation. So I earlier, I mentioned that I have been building projects, and I am trying to solve one thing with all those projects. And that was handling customer support. It was it's just me who's building the projects right now, and I don't really have a team. I want to have a customer support so that people can reach out to me if they run into any kind of issues with my application. Now four different inboxes that I have to manage, which is still okay, but then I wanted to have, like, a premium experience where it would have, you know, a a TLD of my per product. So it should not be @therategmail.com, but I wanted to have something like @theratefastfly.dev, for example, over here. Right? So it's like, how do I do that? So that was my first thing. The other thing was, alright. I have this domain. I have this inbox. But how do I exactly automate a bunch of this so that I can actually, you know, be productive and ship things and not just handle customer support all the time? So that's what we're gonna look into how I am of doing this and how you can do this as well. I see someone asking, will this need the email sending beta, or is it already alive? So you should, the email sending is in public beta. So you would need a workers paid plan. If you want to use that for this workshop, as I mentioned, I'm not gonna dive into it. So you can do this without the email sending, beta as well. But I am gonna come to it, later on in the slides as well. So for now, you don't really need that. You can continue without that. But there might be a point where you would want to consider using email sending as well, and we're gonna come to that in, in the slides later on. Alright. I see someone giving a heart emoji. Thank you. Thank you so much. I am gonna assume that you or most of you have got the slides, and my, hopefully, my agent was doing his, the job right, and you have got the slides and the GitHub repo. Now I am gonna move forward, with my Moab job. But before I do that, I do have I would like to know a bit about you. I gave an introduction about myself. I know it would be impossible to get you all on here and get that introduction, but I have prepared a pool. So I am gonna try and, you know, ask you some questions from the pool as well. So can we have the pool up, please? Alright. So I forgot. So there is a pool step that you can go ahead and check, where you have the chat window. And over there, I have a pool, pop up now. And I would like to know how are you all handling support for your product. Do you have a chatbot which is built into the product? Do you have an email service which you're using to get, support requests from your users? Or do you have, like, a community forum of which can get it can be discovered as well, where, you know, you the people who are using your product join in and ask questions and, you know, to kind of building a community. So I'm, like, interested to know from you all what is your preference of, you know, handling support for your products. Pool not showing up. In the chat, you should have a pool tab which you can use to see the pool because it is visible to me. So I am assuming it should be visible to you all as well. But if it is not, it's completely fine. What we can do is we can interact with the slides. Right? So that's why we have this, little emojis on the slides which you can interact with. We can give each of these emojis like, answer. I'm seeing people already answering in the chat as well. That's fantastic. So that's great. Alright. I see email got some words, which is, which is quit. Alright. I see someone mentioned that they use a support system, which our clients submit tickets into using a form in our app connected by by API. Yeah. That's that's also another way, which I would touch upon. I would not get deeper into it. I see WhatsApp, being a support channel. That's interesting. I've I've tried to play around with DevOps API but never thought about that in those scenarios, so that's interesting. Someone is mentioning that they did not get the slides yet. Okay. If you did not get the slides yet, that's on me, or my agent. I'm gonna blame the agent. What I am gonna do is let me quickly get the links over here so that I can share it with you in the chat. So the link for the slides, in the chat now, and I am also gonna quickly get you the GitHub repo that we are gonna use. Alright. Thank you all for testing out this and letting me know it is broken because we tested it out internally. It was working fine. I think my agent is just being a bit lazy today. Anyways, let's move forward. You have the slides. Alright. Someone got the slides, which is fantastic. I love it. Someone got the slides, so that's great. I should have also told you all to prompt it nicely, like, send a nice email because my agent would appreciate if there's a nice email and not something that is just like, hey. Just give me the slides. Just, you know, add a please maybe and the agent would do it. Anyways, let's move forward. So the problem with again, this is gonna be in context of my experience, but you can put yourself in this place and think about it from your, experience as well. So I try to have, like, a support email from my products, but I very early on realized that email is a dead end because a message arrives and nothing kind of processes it. I have to manually do it. I want something to process it. The other thing was there's no persistence, which means that if, if a user comes back with a separate email, I don't really know what they told me in the previous email. Right? I have to go find that email myself, figure out what the message was, and then try to, you know, understand the next email and process things myself. This is very time consuming, and we are in the age of AI. Right? So why not automate this and make things faster and be more productive? So what we are going to build today is an AI inbox agent that will receive the email via Cloudflare email routing. It is going to understand the intent using an NLM. It maintains the conversation history across the threads. If you get a repeated e mail coming in from your users, the agent knows what the context is from the previous messages, and it can actively respond back. We'll try to look into if, if we have enough time on querying a built in SQLite database. We'll try to send proactive reminders and follow-up. Now the last two points are kind of a stretch goal for this workshop. But, hopefully, we should be able to cover the main things that I want to cover so that you can later on go back and try to build on top of this. Now, again, this is not gonna be like, you know, an autoresponder where you send a message and it automatically sends you a response. Right? It's not an autoresponder. It's gonna have some kind of intelligence based on the user response. It's gonna send the it's it's gonna reply and, do the particular action. So let's imagine we are building this company called FastFlare Services. This company does cleaning, plumbing, landscaping, and whatnot. This company is built in the post AI era because I realized AI took away my job. I need something else to do, and that's why I started FastFlash Services. Now, over here, I used to manage everything with a single Gmail inbox. And as I mentioned earlier, it gets chaotic. I get booking requests. I get inquiries for, you know, what's the status is for the previous request. And I had to also manage the follow ups and reschedules. And there might be some times where my clients would need an emergency where they're like, hey. This is broken. How do I fix this? It's an emergency. Can you please come over quickly? Right? We're gonna cover all of this, and we'll, at the end of the workshop again, have an AI agent that is gonna be running your inbox. There are five things that you should be thinking about when you think of building an AI agent powered inbox. The first is how it's gonna trigger the emails. The next is how is, how are you gonna, you know, understand the request from the user. How are you going to store things in the memory? Is it going to be persistent or not? What actions or what tools you want to give your AI agent? If your business case needs some kind of scheduling, it can be, you know, doing a follow-up email for the user. We have often seen the reminder emails. So if you have something left over in your cart and if you don't check out for, like, twenty four hours or forty eight hours, you get an automatic emails from the ecommerce sites. So something like, around those lines as well. Now we're gonna start slowly with the hands on part. We have kind of covered a bit of theoretic theory in here. What we're gonna need, a Cloudflare account. The free tier again works, but it will work if you have a registered account better because then you can have a TLD and you can set up email routing. For local development, it's fine if you don't have a registered domain. But if you want to deploy it and send an email to a particular email address, you would need a registered domain. You would need Node. Js. A code editor, I know most of us are now coding in our terminals. I mean, prompting in our terminals are not really coding, but having a code editor will be really good. And, of course, you need a terminal and a command line. So make sure you have all these things ready with you. If you have the, $5 workers paid plan, that's also fantastic. You can then set up email sending as well. Alright. So the first step we're gonna do is wanna clone the GitHub repository that I showed you, earlier or that I shared the link with you earlier. I'm gonna also copy this command and share it in the chat just in case you don't have the slides with you that you can, get started with me as well. Now, for each and every step, I am going to be working with you and explaining you what we are doing and why we are doing something. Right? So the first thing, I am going to again, let me do this. I'm going to create a new project, but I'm going to call it something else. I'm going to call it FastFlare Demo because I already have the FastFlare Agent repo in here. This is going to basically clone the GitHub repository that I have created for this particular workshop. It is going to install the dependencies for us and it might ask a few more questions, Something like whether do you need, to initialize the git repository? Do you need to deploy it to Cloudflare yet or not? Do you want agents. Md or not? Because we are assuming gonna use, you know, AI agents to code. We're gonna go yes. Now again, I'm not gonna use agents over here. I might a little bit, but not, throughout the workshop. But still having an agents. Md file is useful. I want it to be git version control, so I'm gonna say yes. And we don't want to deploy to Cloudflare yet, so I'm going to go no. Alright. Now let's go to the project repository and I'm going to open it in Versus Code. I should quickly change the theme so that it's consistent and open it up over here. The next thing we want to do is install a couple of packages. Now over here is OpenAI, as provider, but we are going to use what the Workers AI provider. So let me quickly show that as well. Workers AI provider. So we're gonna use Workers AI. If you don't know about Workers AI, it is, the AI inference on the Edge by CloudFlare, and I am using it now almost for everything that I do. We got, like, the latest model is the Kimi K 2.6, which was released, I think, two days back, and I've been enjoying using that through workers AI. There's, the SchemyK 2.5 that is, GLM Flash 4.7, which we are going to use, today, but you can use any of the models that you want. You can also check all the models that we have in the docs. You can see there's GPT OSs, there's the new Gemma four models, there are also image generation models, translation models. You can see there was also voice activity detection. By the way, we are doing a voice agent workshop tomorrow. So my colleague, Fayaz, who is at the backstage, is doing that. So make sure to check that out as well. So that adds a bunch of models that we have. And today, we are going to use the GLM 4.7 flash. Alright. So coming back to Workers AI Provider, this is what we want to use. So I'm gonna copy this command, come back to my terminal, and another one we want to use is postal mine. So what are we doing with these packages? Let me let me break it down. So workers.ai, again, we're gonna use workers.ai as our inference provider. We are gonna use the AI SDK to basically have basically create the agentic loop that we want. And we are using postal mime to extract the raw information from the emails so that it's more easy to use that in our code. Alright. Let's get back to the slides. So we have done the project setup, and I hope you all have also finished this step. So the project structure, once you have done this, would look something like this. We have an index or ts. A file, this is where we will be writing most of our code today. There is also a wrangler. Jsonc file. Now this is very, native to any Cloudflare Worker application that you build. Let me show you what it looks like and how you should think about it. So over here is my wrangler. Jsonc file. As you can see, it contains some meta information. It has the name of our project. It tells which file is the main file, which means it should execute. The compatibility data and the compatibility flags is something we can skip for now. Observability basically enables logs in our application. And as you can see, I have an AI binding. So this three lines of code allows me to easily access workers AI in my project. I don't have to sell any kind of credentials. I just have to add this binding and now I have workers AI accessible in my project. The next is the durable object bindings. This is crucial If you are building, an agent using the agents SDK, you need to have a durable object binding. We are building a support agent. So the class name is support agent. I'm going to name everything as support agent to have a consistent name across and a durable object binding also needs a migration. This basically allows you to have different versions as and when your, durable object grows or your agent grows and you make any changes to it. So this is what, is the durable object bindings look like. Again, you don't have to dive deeper into it. You can just get it from the docs. You can point your agents, to the docs or even the, the agent skills that we have. We have separate agent skills for the agent SDK that you can use for your projects. Let me quickly also show you our index. Ts file. This is the bare bones, and we're going to start building on top of this. This is the bare bones. We're going to start building on top of this. As you can see, we have a Support Agent class, which extends the Agent SDK class, and we have a simple Fetch handler over here. If I run this, it's not really going to do anything right now because we don't have we're not telling our agent to do anything right now over here. Alright, so the first thing we are going to start with is triggering emails to a persistent agent. Now, again, it's not going to be just a function. We're going to have actual intelligence built in to our agent when we start going on in the workshop. Now when you think about the agent's SDK, think about it as a DusableObject. And if you don't know about DusableObject, don't worry. All you have to know is that you'll have basically, names a name address. A durable object can hibernate, which means that it is not gonna run 20 fourseven, saves cost. It is only going to run when you want it to run or in this context when an, email is sent to a particular address, which means it wakes on demand, and it has it it has its own SQLite database. It is not gonna make a request to a database which is far away from the compute. The compute comes with a database itself. And that's the beauty of Durable Objects. When we start, using, the storage part, you will see that all the operations are basically sync operations, they are not async operations because, again, the compute lives on the storage. Sorry. The storage lives with the compute, and, basically, they live together. And, because we're durable objects, you write the code once, and you decide how you want to handle your agentic flow. Do you want to have one durable object instance per conversation? Or do you want to give one customer its own kind of agent? Or do you want to do it per project? Now it's it's hold on for a minute if that sounds a bit confusing. We're gonna look into it in a bit more better way to do it. So this is basically what you should know about durable objects. So you have a class, and you define what this class should be doing. Right? So, I'm not going to now use the word DurableObject, but I'm going to use the word Agents over here. So, when you're building an Agent, you define what that Agent should be doing. Once you define that agent, you once you define the business logic, you decide how you want to give your users access to that agent. Now you can have each user have their own kind of an agent. So let's just say Alice has its own agent, which is gonna be separate from the agent that Bob has, which means that the conversation that Alice is having with your support agent is not gonna have the same conversation that Bob is having, with its support agent. So if Alice tries to ask, hey, what conversation is Bob having? What issues Bob is is running into? By default, the agent is not gonna have that in its memory. It is never be, it is never gonna be able to, you know, look into what, issues Bob is, having. So it's not gonna leak any information of other users that we have on our application. The way you can do with context of email is in different ways. I'm going to skip this slide. This is what we I want to show you all here. So you can have basically a single inbox where everyone would send the email. But again, you can separate the concern where, you know, no person can ask the, information on what the other, user asked. You can also have a catch all email resolver which would be basically you know something like for now I had slidesfastfed.dev but if you if you send an email to maybe aiphastfed. Dev hellofastfed. Dev, all would reach the same inbox. So that's what, the catch all email resolver would do over here. And this is, in my opinion, the one you should always use is the secure reply email because it would basically add headers to the email so that whenever someone is replying back to that, it takes those headers to make sure that it is the same person that we send the email to so that we are not leaking any kind of, you know, conversation to a third party. And, of course, you can build your own custom resolvers. And on top of that, you can combine these, resolvers together. So you can have a create address based email resolver with the secure email resolver and combine them together. Now, today, we are going to use a custom resolver because these resolvers you can, you know, go check the docs and implement yourself. But I thought it would be a good, practice for us to try and build a custom resolver. So the way it should work is I want my custom resolver in a way that if Alice sends a message, it goes to a separate agent that is just for Alice, similar for Bob and for Charlie. Right? So each of them gets their own agent inbox. Alright. So before we do this, let's start writing some code and look how we can build this. So the way we are gonna work with this is if you check the Readme, the Readme contains all the information that we need to follow. So the project setup is in the Readme. That is the structure in there. And by default, you are gonna be on the first chapter for this particular readme for this particular project right now. And what we want to do is we wanna first set up the email, send email binding. This is going to help us with the routing. So this is what we are going to do first. So I'm going to copy this, come to my render. Jsonc file, and add the binding. I'm going to save this. If you see over here, there is a remote flag. This is crucial if you are using the email binding service. It will help you send the emails from your local running application. If you do remote through, you can access your remote resources from your local instance. Once we have configured this, the next thing is handling incoming emails now if you remember we already had installed the postal mime postal mime package we are going to start to make use of that so let's come over here and import that. And, and the one good thing that we get with the agent SDK is that it has a lot of built in method. I can do async on email. I think I am missing something. Let me check. Async on email should give me Okay. Yeah. Async. Email and it takes some parameters, which is this email and there is again the class is provided out of the box. So I can do email, agent email, so that it's, I have the type shifting here. And let's just do raw for now equals to await email or draw. Should be get draw. And I can also then pass this. Alright. I think at this point, I'm just gonna hit tab and get done with the workshop. No, I'm not going to do that. I'm just kidding. What we are doing over here is we are first getting the raw email from the actual email that we get from the user, and we are passing it using the postal mime package. This is going to allow us to get the subject for, let's just say, which is passed. Headers, and then you can pass on the subject. Subject now. Don't trust the agents. Yeah. Okay. We can also get the from so we can check who is the sender. You can do past. From. Now from is going to be an object. It is going to give you the email and the name. For now, I'm going to leave it as it is. You can also get the body over here and it can give you, like, the text or you can also get the HTML body. So I can do const HTML body, and this is the HTML. You can also do what it's called, the attachments. So one of my applications gets the attachments, because it's processing the invoices that is coming from the user, and I am using the attachment, API over here. For now, let's just log the response and save this. So that's kind of it. We have added the onEmail method, which is basically gonna allow our agent to handle incoming emails. But there is one more step that we need to do is actually handle it on a worker level. So what we are gonna do is we're gonna have async email. I am for some reason getting an error. I need to check. I need to quickly check the code over here. This is correct. I'm not sure why I am getting a TypeScript error someone is mentioning. Ah, right. Okay. There's a typo. Yes. Thank you. That's what I was trying to figure out. Thank you so much. Again, this is gonna take the parameters. I'm gonna quickly check again so that I am not making any mistakes. You know what? Just copy paste because it's never a good idea to live code during events. Awesome. So over here, it is giving me an error. Let's just resolve that and save this. So what we are gonna do or what is happening over here? So whenever your worker gets a request, what happens is the worker checks what are the, basically, the trigger over here. Is it an email or is it an HTTP call? If it is an email, it is gonna execute this part of the request. If it is an HTTP call, it is going to execute this part of the request. Now, because this is this is going to be an email, we're going to execute this part of the request. And now we want to send this email to our agent. Right? So we have, again, a built in method from the agent SDK, which is gonna route it to our agent. Now, earlier, I mentioned resolvers. This is where we you we use the resolvers. Now you could use the create, I forgot the name, the default resolvers that we had or you could create a custom resolver. What I have over here is a very simple custom resolver. Now one quick thing to note, don't use this resolver in production because if you see there is no, secure reply resolver that I am using, make sure if you want to use this in production, you also plug in the secure, reply resolver to make sure that it is adding those security headers whenever it sends a reply back and it receives a reply from your users. Now, coming back to our custom resolver, I'm passing in an agent name. So letting it know, hey, this agent, this is the agent that I want this email to fall into or go into. So it is going to go to my, support agent. And what it is gonna do now is it is, gonna create an agent ID for each of these, which means that it's gonna create a separate agent for each of my users. So let's just say Ally sends a message. She's gonna get her own kind of an agent, which is gonna receive and process the message. If Bob sends an email, Bob is gonna get a separate, agent with an ID bob@xyz.com, and that agent is gonna process only Bob's message now. Alright. I'm gonna take a pause over here because resolvers is something I feel or this concept I have something I feel people should understand better. So I'm gonna take a pause over here, see if there are any questions in the chat before we move on to the next part. Okay. I'm looking at the chat. Can you do email dot, from directly or is it a different You can you can do email dot from directly. So if I show you the interface, what type, the agent email, you have the from, you have the to, as well. You should have okay. These are the kind of the oh, yeah. You have the headers as well. You have the meta information, but also the from and to, so you can do that as well. But as you can see, it only gives me a string. If you want, to maybe, you know, get the name of the user as well as their email address, you would then have to use the past, function over here. Use my Toast. That's a good one. I I should probably use that. I guess we need to do email routing. Right? But if we select an existing domain, it tells me if DNS configured. Okay. Okay. Okay. Only one receiving setup per main domains okay I'm gonna come to that question because I want to show show that on the dashboard so I'm gonna come to that question in a minute before before we move forward. I want to make sure that I have the kind of the basics covered over here, especially with resolvers, so that everyone is on the same, page over here. Going once, going twice. Don't worry. If you have questions, keep posting them in the Q and A section specifically, and I'll come to them and answer them. The team is also, there at the backstage who can, you know, also answer the questions if I am, busy explaining things and not able to answer your questions. Okay. Now coming back to the dashboard, let me open up my dashboard over here. Now this is my, dashboard for my personal account. I'm going to zoom in over here. I have multiple domains. And to do the routing for production again, this is for production. For local development, you don't really need to do this. To do the routing for production, you can go to Compute, Email service, and then do Email routing. Once you do email routing, you get the option of setting up your own domain. So I can, you know, set up a new domain. Let me see which one I want to do. I already have set these up. Maybe I'm gonna do hershelf.app. I'm going to click on Done, and this is going to automatically configure the, the DNS records, for me. As you can see, it is syncing, which means it is setting up the DNS records for me. The other thing with the subdomain, you can do that as well. So let me show that. For this demo, we are going to use fastflow. Dev. I am going to use fastflow. Dev. What I can do is I can do routing rules. I can click on Create an address. And I can do a custom address. Alright, so I'm going to do hey, and then it can be fastware. Dev. Send to a worker, select a worker that I want to do. Let's just say I want to do this. Okay. I think we changed this for routing. I, I need to check this again. Should be create addresses. Okay. I think I think I know what I need to do. Let's do let's try this. Okay. So I think I need to check on the subdomain for, especially for routing. I had set it up for a previous project, but I'm not 100% sure how I did it. As you can see, for one of my projects, I have one subdomain set up over here. So I am let me try to figure that how I did that. Okay. That is something I think I need to figure out, again. Things might have changed since I did that. So I'll try to come back to it, or someone from my team is gonna try to look into it and hopefully answer that question. That's a good one. We're gonna come back to that. Okay. So once we set these things up, let's also test it out. So I am gonna copy this curl command, start up my development server with npm run dev. This is going to pop up an option for me. It may not do it for you, if you don't have multiple accounts. But but because I have multiple accounts, it is gonna ask me which account I want to use with this, application. I'm gonna select my personal account because that's where I have all my domains. So I'm gonna configure that. Once it, is configured, we have a local server running. So I can now let me do this. Open up a new terminal, make a call request, and hit Enter. I see a worker successfully processed the e mail. As you can see, we get the response logged out over here. So we see we received the email. So the subject is Help with my order. This is what we send in the call request. I had the from, I had the body, and the HTML body is undefined. Again, because we, did not send an HTML body, it was a simple text body in here. Right. So we got this working. The step one is complete. We can move on to the next steps. What we learned, we saw how you can build custom resolvers. With our custom resolver, we have one agent per customer. But you can also select whatever resolvers you want, or you can have your custom resolver based on your business logic. Now we're gonna move on to the next interesting bit of this, which is adding some kind of AI to this. Right? So I'm we're gonna add some intelligence and make our support agent a bit more intelligent. Now the question is, like, why we really want to do it? Well, the way we're gonna do it is our agent is gonna read the messages. It is gonna understand the intent. So we're not gonna do any kind of keyword matching. It is gonna actually understand the intent. It is gonna then, handle the scenarios without the code changes. Because if you just do keyword matching and if there is a new scenario coming in from your user, you would not be able to process that. Again, this is flexible. It gives you, you know, more power. It makes it a bit robust and intelligent at the same time. So what this new flow would look like? Well, you get it, you will pass the message that that we did. The next step we're gonna do is call an llm and pass the content to that llm. We're gonna then generate a response from that llm and send it back to our user. So we get the email. We pass the email, we call, DLLM, generate the response, and then send the response back to a user. So this is the system prompt we are gonna use. Again, you can, you know, customize it based on your business needs. For this demo, I'm just gonna go ahead and use that. Right? But before, I jump into it, let me show you how you can switch to another chapter. So before you switch, make sure you save your changes so you can do, g a, that is git add, and then commit those changes. I'm just gonna say chapter one, and then I can do git checkout chapter two. And this is gonna take me to do chapter two. But, I'm gonna continue building on this. Chapter two already will have the basic code that we have, and we can start building on top of that. So the first thing we want is the prompt for our agent. This is what we are going to pass to our agent. So I'm going to copy this prompt and paste it in my code. Now this is again, for the demo purposes, a very simple kind of prompt, not, you know, something very, lengthy. In in real world scenario, you would want to give more, instructions to your agent to make it give give it more information about your business, what kind of services it is it does, what kind of email responses should it respond to. Also, if you want, you can also, give your agent access to the tools, which is gonna basically read from your knowledge base. So you can have basically your own, FAQ, which the agent can access and answer to the user based on that knowledge base. So that's what we're gonna do over here. Once we have, this coming in, the next thing that we also want to make sure is prevent an agent loop. What does this mean? Let's just say you send up an email. Right? And the user had some kind of an autoresponder. Maybe it is like, hey. I'm out of office or whatever it is. Right? We don't wanna send an email back to the out of office email. We get again an out of office email. Our agent, again, keeps on sending an email. It kind of has that loop. Right? We don't want that, and that is what we are gonna try and avoid. So the is auto reply method over here is gonna help us do that. It checks for the headers. So whenever there is an auto reply email, there are headers with that email. So it is going to check for that headers. And based on that, it is going to skip or proceed, with the email processing. So I am going to paste that in here. Now this again, I need to import it. So let's go over here and import this as auto reply email. Save this and we have the blocker, to prevent the agent from going into the loop. Now that we have this, the next step is to actually use our agent. On add intelligence over here. I am going to do const ai. This is going to be workers ai, create workers ai, and this is going to take the binding, this. Env dot ai. Alright, let's see. Okay. Let me quickly check what it takes. Should be this dot ENVDotAI. And I'm going to quickly check my types to make sure I have that in my types. Yep. Alright. Okay. I'm going to try to I have done this and how to do this. Let's go to our GitHub repo and figure it out. We've got the code. You can go to chapter two, And the binding is what we need to pass to our agent. And there are a few more things that you can pass. Let me quickly show you that as well. All right. Now, you have the binding, but you can also pass a few more parameters. One of the parameters that I usually like to add to my AI applications is the AI Gateway. Now, I'm not going to dive much into AI Gateway, but a quick, summary. AI Gateway gives you logs. You can have caching with the AI Gateway, so you can basically check, you know, what your agent kind of responded by. Once you have that dataset, you can extract the dataset. And if you want to run you can run evals you can run those you can use that as well to also train or fine tune your models so that you know you have a better you give your users a better experience so you can also pass on that kind of parameters in here Now that I have const, so now I have the AI instance in here, I am going to use the AI SDK method. Now we're going to call it AI and let's import the generateText method. Now, if you have used AI SDK, there are multiple methods that you can use. There is one that is generate text. There is one that is stream text. You would use stream text if you are building a chat application. But this because this is more of a email application, you don't wanna, like, stream messages to your user. GenerateText fits well over here. We are selecting a model. Now again, I am using GLM 4.7 Flash. You can use, KimiK 2.5, KimiK 2.6, llama, or quena, whatever models you want. I'm passing on the system prompt, and then I am passing the content that is coming in from the user. Now with respect to, logging the email, we can also log the AI response, and we can also send the response back to a user. So let's just do a reply. Subject is from, to, and raw. So let's do a from, and we can do something like from Fastware Home Services. That's it. And the body is giving me an error because x has it generated in the last step. Right. Okay. Let's go back. Quickly check this over here. We are missing the email parameter and it should be reply to email. Right. Okay. That's what the mistake that I made. Let me do this again. Reply to email, and this is what we want. I'm gonna skip the subject. Let's give a from name, Fast Pair Home Services, and that's it. And I'm gonna save this. So what we're doing is we're getting the email from the user. We are processing it via an LLN, and then we're going to send back a response to the user. So let's test this quickly locally right now. So again, I'm going to come back to my terminal, do npm run dev. This is going to start up the server and I can make the same call request once the server is up and running. Right. Let's make the call request. Alright. And we saw the same, mess logs that we saw earlier, but now we have the AI response as well. Hello. Thanks for reaching out. I would be happy to help, etcetera, etcetera, the FastForward team. Right? So we have got the email as well, on auto response coming in from our agent. So this is something we had. We are sort of running out of time. So what I want to do quickly is show you how you can deploy it and configure it. So I'm going to close the server and do npm run deploy. So I'm going to deploy this to, my CloudFront account. This is gonna get deployed. And once it's deployed, we can, add the routing for our agent in here. Okay. While this is happening, I'm gonna come back to the slides and quickly talk about what we saw over here. So now what we're doing is we're creating we're giving each user kind of its own customer support agent. We're using Workers AI. Now you don't you are not tied to using Workers AI. I like to use Workers AI because there's also, like, a generous free tier for Workers AI, which fits well for my workload. But you can bring in, models from Entropic, OpenAI, Gemini, whatever you want to use. The next thing I want to start looking into is persistence. But before we do that, let's see if our app is deployed. It is. I'm going to quickly show you how you can configure it. I'm going to again go back to my Cloudflare dashboard. I'm going to select my FastFlare dev account in my email routing. I'm going to go to Routing Rules. I'm going to do Create Address. Now again, I can do a catch all, but I want to do specific for support. I'm going to do support at the fastflow. Dev, and the action I want to do is send it to a worker. So I'm going to send it to a worker, and I'm going to select FastFlare Agent Demo. This is the one that we deployed just now. I'm going to click on Save, and this is going to now be live. If you send an email to supportfastware. Dev, it should give you a response in a couple of minutes. The agent is going to do the processing and give you a response. You can also check the application. Over here is Fastware Agent Demo. We can look at the deployments that we had. We can also check the observability. Right now, we haven't got any request, and that is why there is no event found. But if someone sends an email, we will be able to see, that trigger over here as well. Alright. Now this is something which is crucial, but, unfortunately, we don't have enough time. So I'm gonna, talk over the next few things that we have in the slides. Now till now, if you see, we had the agent which would process an email once, but it would not have some memory. Think of it like the agent having amnesia. It does not really know what was told earlier or what was the user requesting earlier. For an example, if it says, hey, can you add the plumbing too? The agent is going to take it as a completely new request, and, sure, I'm going to do it and settle it for you. But it's not going to connect it to the previous request of the user. So the way to do this is create a SQLite table for this agents. And for that, we're going to use again the build in this. Sqlite method so that every agent has its own ccolite database and this is where we are going to store the messages from our user. Now there is another way there is this dot state. I like to keep them separate. So this dot state also allows you to, store data, which is gonna be persistent. But it has, for me, a different use case, which I am gonna talk with you in a minute. The next is when you create the tables, you want to create a table in the onStart hook, which is basically, you know, going to be executed whenever your agent, starts for the first time or is waking up from hibernation. The one good thing with this. Sql method is it use, tag template literals, and you will see the same text over you. So as you can see, the way you can use this is have, you know, this dot SQL and then basically use the template returns to write your SQL query. Over here, we are creating a messages table. So this is gonna create a messages table where we are gonna store the messages from the user as well as the agent. And we are also creating a jobs table so that we can, you know, store the jobs that the user has requested. Maybe the agent wants to, use this in the future for some kind of reference. One quick thing, make sure you use if not exist. Otherwise, you're gonna run into SQL queries. So the flow over here would look like an email arrives. We store the user's message in the table. We fetch maybe the last 10 messages. We send it to the agent. With this history, the agent processes this, generates the message, and then we store the agent's message as well in the table, and then we reply back to the customer. So now our agent has better context of what the conversation is about, what the user shared in the previous messages, and you have a proper loop going on for your support agent. Now this dot state, the way I could think about this dot state is use it for, you know, like storing information which is not going to change often as it can be like a simple string or a small JSON object. I would not store the messages in the SQL, in in this dot state. I would basically store it using SQL. Under the hood, this dot state uses SQL database, but it is not easy to query that. Alright. Moving quickly, we saw that the Agent SDK comes with a building SQL database. It has its own. It comes with also this. SQL, which allows us to, you know, run SQL queries, store messages, store job, and stuff like that. You can also use this. State to maybe store some kind of meta information about the customer. Maybe you want to store, you know, what kind of plan this customer is on so that you have your agent can understand things, more better. Now the next thing is the tools. Till now, we only had the agent, you know, responding to the user but not really doing anything. Again, coming back to Fast Fresh Services, we do plumbing, we do cleaning, and a bunch of services. The user may want to look up for the status of the service or they may want to book a new service. But the agent does not have the tools to do that. What we want to do is give the agent access to tools so that it can actually create appointment for this or schedule something or even add something to the job or look something from the database of the status of that particular request from the user. So you define the tool and the LLM automatically chooses which tool it should be using. The, the way you define the tools is going to be basically setting up parameters, giving it a description, and telling it, and the agent is going to infer from that context what it needs to do. When you are creating these tools, make sure you have granular tools. It's not like a very broad tool because then the agent is going to probably make mistake and not give you the desired output. This is what a tool would look like. Now I am using the I am using Zoho to define the schema. As you can see, it takes a description, which is create a new service job for the customer. If I get an email where a customer is asking for a new service, the agent reads a description of this tool and knows, alright, this is the tool that I need to use. Then it checks the schema of what are the parameters it needs to pass for that service. So it will pass these parameters and execute this particular code. So now, our agent has access to the tools, which means it is gonna do more than just replying back to a user. And then you can wire the tools by passing on a tool parameter and then, you know, have the tools in here. Now, again, this is not, native to the agent SDK. This is more native to to the AI SDK because that's what we are using to generate the text. So you if you are, you know, looking into more parameters for that, you should check out the AI SDK's, documentation for that. So quickly, we saw that tools make our agents, more powerful. It allows the agents to actually take some action. When you define tools, you define the description, you define the parameters that the agent need to pass, and the function that will be executed when this tool is invoked. And you don't have to tell the agent, that, hey, use this tool for this job. The agent is now smart enough to understand which tools to call. This is the last part of the workshop. I know the last three parts we have kind of rushed into because of the time, but this is something which I think is also useful over here, which is scheduling or being proactive. Let's think of a scenario where, you know, you, I'll just send an email, for scheduling a service. Now you want to send a reminder email, like, hey. Tomorrow, we're gonna come over, for the cleaning service just to, you know, remind Alice that, hey. She had an appointment, and we're gonna be coming over here. Right? So you can do that as well. So the agent SDK provides this dot schedule method, and the good part is it takes, like, three different ways to schedule it. So you can pass a specific date. This can be, I don't know, ten days in the future or, even like a year in the future, and the agent is gonna the schedule is gonna run, execute the function, and do its job. You can also kind of do a delay. So let's just say you want to have a delay of sixty seconds, ten seconds, hundred seconds to check a status, you can do that. And you can have a recurring as well using the Cron expression. Now, if you want to, you know, take an idea of how you would do this, so you want to do a confirmation reminder, maybe do it one day, before the appointment. If you wanna do a follow-up, this would be, you know, maybe a two day after the completion. And if you wanna do a reengagement, maybe, you know, like, everything went well, you want to probably get the feedback from the user, you know, check-in with them and see, like, hey. Is there something else that we can help you with? You can do, that as well. The schedule method, again, is in this, in the slides. I'm not gonna, you know, spend too much time into it, but you can basically create a wrapper method over here, and pass it to the agent so that the agent can schedule things dynamically if you want. And this is where it gets interesting. Now you're not replying back to the user. You are sending a separate email. And this is where you would need, access to the send email service that we made publicly, available last week. Right? So if you wanna do, an automated email to your user, you would you you would need the Send Email service for this. You cannot use the reply email over here because this is gonna be out of, the box for the agent. So, again, how do you think about reply to email and send email? So if you have a function that is, you know, if you have everything running inside the on email handler, that's where you would use the reply to email. Again, this is replying to the email of the user. This is not sending an email to the user. Again, it needs to live within the agent email object. We use the send email with the binding. Again, direct replies. I'm specifying this because I have been talking to folks, and folks get confused over here. Reply to email, direct replies, send email to send a new email to your user. Alright. So you can use schedule to schedule the emails, to delay the emails, and send new emails to your user. If you are scheduling emails, make sure you use send email because you won't be able to do reply to email. The other things are you can auto reschedule things. You can have also yeah. Schedule also survives hibernation. So if your agent, you know, processes the request, goes to sleep, it is still gonna wake up at the time it needs to do the thing when it's scheduled to do that and, you know, process it for you. A few things, to make sure when you are actually using this in production, You have a create secure reply email resolver. I specified this earlier. I haven't added it to my code right now because this was a demo, but if you are using it in production, make sure to use this. Also, do error handling. I mean, this is something that we all should be doing out of the box. But always a good thing to remember that you should be doing error handling, for this. And deployment checklist, make sure you have a domain setup, you have DNS recon records configured. The if you do it via the dashboard, it automatically configures the records. But if you run into issues, do let us know. I know someone over here is running into issue and Faraz has been kind enough to help. So do let us know. You can always reach out to us post the workshop if you run any kind of issues over here. Set up email routing rules. I made this mistake. I have done this a couple of times, but yesterday when I was trying it out, I configured things and I was just sending an email and I was not receiving anything, and I realized I did not set up the email routing rule. Make sure you do that. Also, when you are using the reply create reply resolver, you want to set up a secret. This is, this secret is going to be used to encode the encode the headers. Make sure you add that, test it locally, you can do that. You have a remote true flag that you can do, and then you can deploy with npm wrangler deploy. It's not going to cost you to do this verify. So send you an email to yourself, test it, and make sure it's working, and check the logs. Alright. So we started with triggering, our agent inbox. We then gave it some kind of intelligence by adding workers here. We then look into how you can give it a memory so that it remembers the conversation it is having with our customer. Then we look into how you can give it make it more powerful by giving it access to the tools and look into how you can schedule things to make it more proactive. Right? Now, again, I know we did not cover everything, by hand. That's why I have the slides. That's why I have the GitHub repo so that you can go ahead and try it out by yourself. And if, again, you run into issues, feel free to reach out to us. Always happy to help you out with this. The resources and the next steps, the agents as we get docs is the best place to learn how you can build agents on Cloudflare. Also, if you're using the email, services, look at the email API reference and the email agent the email service is docs as well. One I would take two quick notes. The first, we have the skills for almost all the Cloudflare services. You can search on the Internet for that, and you use those skills if you're using any kind of, agent to write the code for yourself. It's gonna help you, you know, ship things faster, but also make sure it is writing the right code. Next, we also have a documentation m c p server, which makes it easier for the agent to query the document and, you know, get the latest information of everything that we are shipping with the SDKs, with the APIs, and everything around that. So make sure you do that, check them out as well, and use them as well. Alright. With this, I wanna thank you all. I know we ran a bit too quickly and a bit over time but I wanted to make sure that you know I covered the basics it helps you understand the basic concept and how you should be thinking about email agents and again you can get the slides from this QR code if my email my workshop email did not work well you can get it from this QR code and one other thing that I would like to share is if you are building an email agent and this is something I have been doing myself. And one thing I kind of realized very early on is I don't have a lot of visibility into the emails coming in and the emails my agent is sending. So this is an open source, you know, project from Cloudflare. It uses email sending the agent's SDK. So, basically, it gives you a UI on top of your email agent right so you can use this out of the box you can you know fork this modified for your use case but I highly recommend you know having some kind of a UI so that you can see the incoming emails coming in from your customer and the emails the agent is generating and sending to your customers. That is super crucial, so make sure you do have some kind of visibility. So make sure you have a UI for that. Alright. I'm gonna stop talking. Thank you, Piyas, for sharing that, and I am gonna see if there are any questions from the folks. I know we are a bit overtime, but that's how kind of we also planned this workshop. We kind of, you know, kept a bit of time at the end of the workshop, and were not tied to just one hour so that we can, you know, cover the basics and also take questions. So, again, if you have any questions, feel free to ask them. I want to also, like, give a shout out in the meantime to Fayaz and Arian, who is at the backstage, you cannot see them. I can see them. They have been continuously, answering, making sure things are working really well. So I wanna give them a shout out and thank them for helping as well. Alright. Okay. I see someone is talking about a Java setup. I am also excited. And because you mentioned Java, like, if you can attend the workshop that Fiyage is doing tomorrow because it is a voice agent workshop. So kind of, you know, think of Jarvis, which you can talk with voice. So you're not writing code, or not writing emails, but just talking to your agent. I don't know if you're, having registrations open, but if you do, let's let's, you know, five hours or I can, like, share the link over here so that folks can also, you know, join the workshop if they want to. Also, you you know what you can do? You can also you can also then have your email agent configured with your voice agent so you or your customers can, you know, interact with the agent via voice, but also that same agent can be accessed via email as well. Right? So that would be something that I feel is gonna be interesting. So you have a single agent can be accessed via chat, can be accessed via email, or can be accessed via voice. So the single agent can have now context across all the different channels for the agent. So that's something that I am excited about, and now I want to build as well. But okay. Yeah. I I see, Fayaz has shared the link for, tomorrow's workshop. So do tune in. This is gonna be a great workshop. I've seen behind the scenes, everything around that. Alright. I'm gonna wait for a couple of, minutes as well. I want to make sure I cover, you know, any questions that folks have. So I'm gonna be over here and I am just gonna keep on blabbering so that if you don't have awkward silence because I I feel it's it's very weird if there is, like, a silence and no one is speaking, and you all are just, like, either looking at me or at the QR code, which is now, I think, hopefully, everyone have access to. So So I'm just gonna keep on blabbering, I think, random stuff. No. I'm just not gonna do that. I'm gonna talk something useful. Okay. One other thing. If you are developing this locally, let me let me do this. I'm going to start the development server npm in dev. It is going to start the development server and there is one new tiny but very useful feature that has been shipped. I don't know if you have noticed that, but there is like press e to open a local explorer. So if I do that, it opened it in another window. Let me bring it in here. It opens this local explorer, which means that while you are building locally, you're not now, you know, have to use anything else to view the data, but you can just view the data in here itself. So for my support agent, which is running locally, I can see that there is a durable object which is called Support Agent. I can click on that and I know there is an instance of it, which is named Alice because that's how we configure a resolver. I can open it in the studio and I can select a table and view the information in here. Now these tables are going to be empty for now because we are not actually storing anything. But if you are creating a messages table, you would be able to view this over here and also view the messages in here. If you are building locally, this is the best, I think, experience you can have now. You can also, you know, have if you're using a database, you can do that in here. If you're using KV, R2 workflows workflows, whatever services you are doing, whatever services you are trying out locally, you can view them now in the dashboard, I mean, the local explorer. Okay. That was, I think, the last step I had, and I think at this point, I don't have anything much to share. I think okay. I see someone sharing their LinkedIn. That's fantastic. Yeah. Let's let's connect on LinkedIn. You can find, my socials. Let me bring up my slide on horschel.dev. It's my website where you can find all my socials. So wherever you are active, you can, you know, just connect with me over there. See a message I saw. CF, v c f plug in also as explorer. Yes. That's fantastic. Right? So the Vite here plug in also is the explorer. So if you are not using, the native way of building application, but you're using Vite, it comes with the explorer as well, which, again, is just fantastic. Okay. If you are doing this maybe, I don't know, unlike a previous version of Vite or Wrangler, I would recommend updating this, updating your version so that you are able to access, you know, the Explorer on your application as well. Okay. I I'm gonna try to pronounce your name. I am gonna I'm sure I'm gonna butcher it out. I'm I apologize for that. It's a new name for me. It's Hale. I hope I'm pronouncing it right. Right. Love that. Yes. I was in Zurich last year. Hopefully, I'll be Zurich in this year. I'll make sure I I reach out and, you know, let's let's catch up. Let's, you know, talk, talk about Cloudflare and anything. I I'll I've had a good time in Zurich. So love to and always meet people and talk with them. Alright. Okay. I don't see any more questions coming in, so I think we're gonna end the workshop. I don't know. I don't want folks to just stay over here and listen to me blabbering. So thank you so much, for joining in. I hope this workshop helped you get the basics. You have the link to the slides. You have the link to the GitHub repository. Go on, try on new stuff. You know, it's okay to break things and use the skills. Use the DocsMCP server, and, you know, just keep on building. Again, if you run into any kind of issues, feel free to reach out. I am I am always happy to help, with anything that you are building. And, again, make sure you have a UI. Agentic inbox is just an example that you can use out of the box. If you want to build something of your own, you can do that as well. Alright. Thank you all so much. I think I'm gonna stop serving, and I'm gonna leave the stage so that I don't keep on blabbering appreciate you all thank you all I hope to see you all in the next upcoming session so stay tuned and enjoy the rest of your day