AI Agent: From Prototype to Production

Adding Approvals to Agent

Scott Moss

Scott Moss

Superfilter AI
AI Agent: From Prototype to Production

Check out a free preview of the full AI Agent: From Prototype to Production course

The "Adding Approvals to Agent" Lesson is part of the full, AI Agent: From Prototype to Production course featured in this preview video. Here's what you'd learn in this lesson:

Scott updates the agent by adding the approval flow. A condition is added to check if the tool call is the generateImage tool. If so, the execution is stopped, and the user's approval is requested.

Preview
Close

Transcript from the "Adding Approvals to Agent" Lesson

[00:00:00]
>> Scott Moss: We got to go tell our agent, about approvals now. So we're gonna create a function called handleImageApprovalFlow, and this is pretty much gonna do all this stuff for us, and then we just need to check for that before we start our loop. So I'll walk you through it, as we do it.

[00:00:13]
So, let's go to our agent, make a new function up here, it says handleApprovalFlow. Or what did I call it? It would be very specific what I had. Handle image approval flow. Let's do that.
>> Scott Moss: So we're gonna do that. And this function really just needs, all the messages so far, and the new user message, that's really it.

[00:00:50]
We need all the messages, and you'll see why. So, history is AI message, user message is a string.
>> Scott Moss: So we're gonna walk through this. So, the first thing is, we need to get the last message, which is the latest message. The last message in the database is the newest message.

[00:01:15]
It's the last message that the conversation left off on. This is how we can tell, if you're an approval state or not. So all I have to do is look at this last message, and we can see if it was a tool call. So if I say, cool, grab this last message from the history, which here's a neat trick.

[00:01:33]
I think you can just do, at negative one now, right? I think that's the same thing, so much better. So you could say, that'll give the last thing in the array. We check to see, hey, does that message have a tool calls array? And if so, grab the only tool that's in there.

[00:01:55]
And then, we check to see, if this is not a tool call, or if there is a tool call but its name is not the name of generating an image. We don't need an approval. We can just stop right now, right? We don't need to do anything. So, let's do that.

[00:02:11]
If this is not a tool call or, tool call dot, what that's tool call dot function, that's right, function dot name, does not equal, you've got to import the image generation name in here.
>> Scott Moss: Tools, there we go.
>> Scott Moss: Generate image tool definitions. So if it doesn't equal generate image to definition dot name, then, we can just stop right now.

[00:02:47]
We don't need an approval. Everything's good. It's either they're calling another function, or it's just not even a function call, just a regular thing. But if it is, a tool call, that's image generation. Let's make a loader. So we'll make a loader. We will then now process the user message to see if they approved it or disapproved it.

[00:03:12]
So we'll say, approved is await runApprovalCheck. And it just takes in the user message, like that. So this would be a Boolean true or false.
>> Scott Moss: And then from there, we can say, cool, if you did approve it, let's go ahead and just call our run tool function right here.

[00:03:34]
We can actually just call the generate image, we know that's the one you wanna call, but let's just call the run tool function for now, assuming that we might add more. Types of actions that need approval here. If you didn't, we'll save a new message, a new tool message, cuz we have to respond back with a tool message of saying, user did not approve that image generation at this time, or whatever you wanna tell the AI so it can stop.

[00:03:58]
But in this case, it'll just keep going. So, let's do that. If approved, let's update our loader to be, cool, I'm doing that now. And then, we just wanna run the tool with the tool call and the user message. So I'll say const to response, on time, equals await run tool with the tool call, and the user message like that.

[00:04:31]
So we get back our tool response, whatever that is. And then the last thing we want to do is, update our loader to let them know that we're done and then we have to save this response. So I'm gonna say, do that. And then I'm gonna say, wait, save tool response, tool response takes in the tool call ID, which should just be, tool called ID.

[00:05:02]
And then it takes in the response that you got back from running the tool, running the tool itself with the run tool call. So, this will be tool response.
>> Scott Moss: And then, else, if you didn't do this, then, we also, yeah, we still wanna save a tool response.

[00:05:22]
But the answer to this is, user did not approve it. You can put whatever message you want here. This doesn't matter. It's not gonna call the function. This is what calls the function. So, regardless, the function isn't called. This is just trying to help the AI out. It's probably gonna be confused.

[00:05:40]
Like, wait, why didn't you do the tool? That's not what I expect you to do. So you kinda wanna tell it, yeah, man, the user didn't approve this one, sorry.
>> Scott Moss: Okay, so we got that. Now, we just need to stop the loader and then, return true here.

[00:06:07]
>> Scott Moss: Loader dot stop, and then return true. If we got this far, that means, there was something that need to be approved. If we return false, that means, nothing needed to be approved. And we need to know that because depending on whether or not, something needs to be approved or not, we need to add this user message.

[00:06:34]
Because if there was an approval, we already added this message, because that message would have been a response to the tool call. If If there was not an approval, then, we need to proceed as usual and add the message here. So, that's why we have to return true or false.

[00:06:51]
And now we actually have to get the history at the top, whereas before, we're only getting the history here. We have to get the history here now, because the approval tool needs all the history. So, let's do that. We'll go down here, we'll say, history equals how you get messages, and then we say, is approval equals await, what I call this, handle, image, approval, flow.

[00:07:26]
That wants all of the history, and the user message. And then I can say, okay, well, if there was never an approval in the first place.
>> Scott Moss: Not if it was approved or not, but if it was even an approval request, a pending approval. Then I can say, we need to add this message because otherwise this message won't get added, right?

[00:07:50]
Like if we go up here, it returns false right here. So, I never added the user message, to the database. So it'll get here, It'll get the messages, it'll put them in here. And the last message it'll see, would be the message that it said, and not what the user said.

[00:08:08]
So we have to add this back, just like we had it before, but only if there wasn't an approval. If there was an approval, approved or not, we can't make a user message, right? This makes a role user message, because here we are in an appending approval state.

[00:08:24]
The message has to be a tool message. You have to respond back with a tool. So this is where it's, kinda confusing.
>> Student: In your check, you're checking if it's the wrong tool. I mean, would there be a case here where it would be still in an inconsistent state cuz you had a tool call just one?

[00:08:44]
It wasn't the image one?
>> Scott Moss: Well, I'm checking right here.
>> Student: It's gone.
>> Scott Moss: Yeah, so, we only proceed if it's not a tool call, or if the tool call is. We only proceed if it is a tool call and the tool call's name is generated.
>> Student: You're saying if it's.

[00:09:02]
Well. Mean, but if it's not that tool, then it's kinda immaterial.
>> Scott Moss: Right, yeah, if it's not that tool, it'll return, and then, it'll call this, and then.
>> Student: And it'll still be cuz if it is some other tool, you'd need to have that tool's response.
>> Scott Moss: I should just say, we would never be in a state, where the last message in the database, is a tool call if that tool didn't need an approval in the first place.

[00:09:33]
Unless your system broke for some reason and the last message it left off on was a tool call. At that point, you would probably wanna implement a self-healing thing, that checks, the last message in the database to make sure it's not ending on something that's broken like that and instead.

[00:09:49]
>> Student: This should be this one doesn't need an approval. Just go ahead and run it.
>> Scott Moss: Exactly.
>> Student: The response.
>> Scott Moss: Yeah, how the hell they being up in the state. I don't know, just run it. Yeah, Yeah. Cool, so, the other thing we need to do is stop the loop, when we see, we're in an approval state.

[00:10:09]
So all we have to do is go ahead into the tool call thing. We can be, hey, are you generating image? Cool, stop right now. Don't continue and return. That way it doesn't continue in the last message that we see is the tool call, so when we come back our handle approval, we'll see that it tool call and it'll kick off.

[00:10:26]
So, let's do that so in here we'll say, if tool call.or I'm sorry, no, that's right, tool call dot function, dot name, triple equals generate tool definition, dot, name. Then, let's do our loader, update loader, stop and then get messages. So we'll just do that, update our loader, like, Need user approval.

[00:10:55]
Stop the loader, so stop spinning, and then return which exits out this whole process, the while loop everything with just the messages. So we completely stop. Otherwise it's a regular tool, keep going. All right, let's give it a try and see what we broke. So, I'm going to go to my terminal.

[00:11:14]
I'm gonna say npm starts, and I'm gonna say it generates an image of a turtle.
>> Scott Moss: It's thinking, and it's, cool, yes, I need to call the generate image. But do you approve greeting or generating an image? So, we didn't add this part. So we're wondering where the hell did this came from?

[00:11:38]
Already did that here in this UI file. So, it checks to see if there's a tool call with this name, it'll, it'll put that for you. So you didn't have to do that, that's free. So now you can respond back with, something ambiguous. I actually ran something in here and it killed the terminal, and I was, I think I put yes with exclamation part, and, nothing happened.

[00:11:59]
So, I don't know, why that happens, but I'm not gonna do that, or something kindaa in between. I wanna see if it figures it out. Sure, [LAUGH] Yeah, I don't know. Let's see.
>> Student: With the question mark, it's gonna be, meh.
>> Scott Moss: It was, no. I said that's not it, that was not enough.

[00:12:18]
I think it's because if you really think about what I told it. Where did I put this.
>> Scott Moss: Yeah, it's in the LLM file, it's this one. I was, if you are not sure that it is not approved.
>> Student: What if you would have said, sure would not a question mark?

[00:12:40]
>> Scott Moss: Okay, let's try it again. Actually, let's check this out. Let's try that image. Let's try that turtle again. It should know that.
>> Scott Moss: Nice, and then I can say,
>> Scott Moss: Sure, nice, I did it. So, yeah, that question mark was the difference of it being like mmm.

[00:13:06]
You didn't seem too sure, it's always my head a gun to your head. So, I'm not gonna do that one, and now it's gonna generate us a turtle image, Blink twice. Yeah, blink twice if you are sure, [LAUGH] if you need help, I have a 911 tool, okay come here.

[00:13:23]
Let me click on this. Come here, thank you. Look, it's a turtle.
>> Student: So pretty.
>> Scott Moss: Nice, nice. So, cool.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now