Action Agent (Personal Assistant)
This section describes how to build your own personal assistant Agent with Upstreet and the Google Calendar API, using custom React Hooks.
In this guide, we build an Action Agent capable of scheduling events on our Google Calendar for us, using the Google Calendar API. We use custom React Hooks in this example - We want to use nice, clean coding practices.
We define an Action Agent as an Agent which can take actions on behalf of you.
The source code for this example is available on GitHub.
Guide
Step 1: Setup usdk
Follow Setup the SDK to set up NodeJS and usdk
.
Step 2: Initialize your agent
Create a new agent:
This will directly scaffold an agent for you in <your-agent-directory>
. Learn more
Your agent directory now contains the Node application and git
repository for your agent, should you choose to use git
.
The -y
flag means to skip the Agent Interview process, which we don't need here.
You can also omit the agent directory. In that case, a directory will be created for you.
Step 3: Create a PersonalAssistant
Component
Why manage our calendar manually when an AI agent can handle the task for us? We can easily build an Upstreet Agent to handle Calendar management, reducing scheduling conflicts and saving time.
This example, however, will be very simple. We want our Agent to be able to schedule a Google Calendar Event for us.
The PersonalAssistant
component is just an empty wrapper component for now - it will later utilize a GoogleCalenderManager
class to interact with the Google Calendar API, allowing users to create Calendar events programmatically.
Step 4: Using custom Hooks and better practices
In agent-renderer.tsx
file, inside the AgentRenderer
class, we can make a custom Hook called useCalendarKeysJson
:
In the same file there is AppContextValue
mention. Make the below modification in your code.
Now make some changes in app-value-context.tsx
file's AppContextValue
class .
In the same file add useCalendarKeysJson
custom hooks
Now add useCalendarKeysJson
in hooks.ts
file.
You can now use useCalendarKeysJson
as a Hook in your PersonalAssistant Component.
Step 5: Integrating the Google Calendar API
Let's build our GoogleCalendarManager
, which will leverage a service account for authentication and handling token generation, event creation, and error handling.
Ensure you have your Google Calendar API credentials, including:
GOOGLE_CALENDAR_ID
, GOOGLE_API_KEY
, GOOGLE_SERVICE_ACCOUNT_EMAIL
, GOOGLE_PRIVATE_KEY
This tutorial will not cover how to obtain these credentials. For more information, you can refer to the Google Calendar API's documentation.
After obtaining the keys, add them to the wrangler.toml
file.
Here's how it might look like:
Let's get back to the code.
This code provides an integration with the Google Calendar API by implementing a class called GoogleCalenderManager
.
Breakdown summary of the GoogleCalenderManager
Class and its functions
- Constructor: Initializes the GoogleCalenderManager with Google API credentials (GOOGLE_Calender_ID, GOOGLE_API_KEY, GOOGLE_SERVICE_ACCOUNT_EMAIL, GOOGLE_PRIVATE_KEY).
- getAccessToken: Generates an OAuth2 access token using a JWT for authorizing Google Calendar API requests.
- signJwt: Signs a JSON Web Token (JWT) using the private key for secure authorization.
- base64StringToArrayBuffer: Converts a base64-encoded string into an ArrayBuffer, which is used for cryptographic operations.
- setCalenderEvent: Posts a new event to the specified Google Calendar using the access token and provided event details.
Step 6: Initialize the GoogleCalenderManager instance
Now let's modify the PersonalAssistant
component.
In the code snippet, the credentials are being fetched using useCalendarKeysJson()
and are used to initialize the GoogleCalenderManager instance.
Now we'll use the <Action>
tag to define how the Agent should respond to the default text perception.
Breakdown summary of this <Action>
Component
- Purpose of the
<Action>
Component
<Action>
components define specific actions that your agent can perform in response to user inputs. Learn more
This component is used to define a specific action that can be triggered, in this case, setting an event in Google Calendar.
-
Defining Action Properties
Each
<Action>
is structured with the following properties:name
: A unique identifier for the action. Example:'setCalenderEvent'
.description
: Explains what the action does. In this case, it sets a new event in the user's Google Calendar.schema
: Specifies the input structure for the action, defined using azod
schema. The schema expects the event's summary (summary
), start date and time (startDateTime
), end date and time (endDateTime
), and a description (description
), all of which must be strings.examples
: Provides sample inputs to guide the agentโs behavior. Example:{ summary: 'Meeting with John Doe', startDateTime: '2023-06-15T10:00:00-07:00', endDateTime: '2023-06-15T11:00:00-07:00', description: 'Discuss project timeline and requirements.' }
.
-
handler
: The Action's Core LogicThe handler function is the core of the action. This function contains the logic that will be executed when the action is triggered. In this case, the action is to create a new event in the user's Google Calendar. Here's a breakdown:
- PendingActionEvent: The handler receives an event object of type PendingActionEvent, which contains all the data and context for the action being triggered. This event object has a data field, which holds the
message.args
. The args will contain the arguments passed when the action was triggered. - Destructuring: Inside the handler, the event data (e.data.message.args) is destructured into the specific fields:
summary
,description
,startDateTime
, andendDateTime
. These correspond to the values passed when the action was triggered. - Event Creation: Once the necessary data is extracted, an event object is created.
This object is structured according to the Google Calendar API's expected format:
- Calling googleCalenderManager.setCalenderEvent: The googleCalenderManager.setCalenderEvent(event) method is then called to create the event in Google Calendar. This method is asynchronous, so the await keyword is used to ensure that the event is created before proceeding.
- PendingActionEvent: The handler receives an event object of type PendingActionEvent, which contains all the data and context for the action being triggered. This event object has a data field, which holds the
Step 7: Test out your PersonalAssistant Agent!
You can run usdk chat
to test it out. Learn more
You can ask it questions like:
Schedule my meeting with Steve on 15 November at 10 PM.
The source code for this example is available on GitHub.
Share its response in our Discord community; we'd love to know what it responds to you.