Skip to content

Commit 36655b3

Browse files
AIDX-313 Add update for Cloudflare example docs
1 parent 356aac4 commit 36655b3

File tree

1 file changed

+163
-24
lines changed

1 file changed

+163
-24
lines changed

auth4genai/snippets/get-started/cloudflare-agents-js/call-your-api.mdx

Lines changed: 163 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,27 @@ npm install hono \
4242

4343
In the root directory of your project, copy the `.dev.vars.example` into `.dev.vars` file and configure the Auth0 and OpenAI variables.
4444

45+
```bash .dev.vars wrap lines
46+
# ...
47+
# You can use any provider of your choice supported by Vercel AI
48+
OPENAI_API_KEY="OPENAI API KEY"
49+
50+
SESSION_STORE=cloudflare-kv
51+
SESSION_STORE_NAMESPACE=Session
52+
53+
54+
#auth0
55+
AUTH0_DOMAIN="YOUR-ACCOUNT.us.auth0.com"
56+
AUTH0_CLIENT_ID="YOUR CLIENT ID"
57+
AUTH0_CLIENT_SECRET="YOUR CLIENT SECRET"
58+
AUTH0_SESSION_ENCRYPTION_KEY="RANDOM 32 CHARS"
59+
AUTH0_AUDIENCE="YOUR AUDIENCE"
60+
61+
BASE_URL="http://localhost:3000"
62+
```
63+
64+
If you use another provider for your LLM, adjust the variable name in `.dev.vars` accordingly.
65+
4566
### Define a tool to call your API
4667

4768
In this step, you'll create a Vercel AI tool to make the first-party API call to the Auth0 API. You will do the same for third-party APIs.
@@ -53,41 +74,159 @@ Since the Agent defined in the class Chat in `src/agent/chat.ts` uses the **Auth
5374
The tool we are defining here uses the same access token to call Auth0's [`/userinfo`](https://auth0.com/docs/api/authentication/user-profile/get-user-info) endpoint.
5475

5576
```tsx src/agent/tools.ts wrap lines
56-
const getUserInfoTool = tool({
57-
description: "Get information about the current logged in user.",
58-
parameters: z.object({}),
59-
execute: async () => {
60-
const { agent } = getCurrentAgent<Chat>();
61-
const tokenSet = agent?.getCredentials();
62-
if (!tokenSet) {
63-
return "There is no user logged in.";
77+
/**
78+
* Tool definitions for the AI chat agent
79+
* Tools can either require human confirmation or execute automatically
80+
*/
81+
import { tool } from "ai";
82+
import { z } from "zod";
83+
84+
import { getCurrentAgent } from "agents";
85+
import { unstable_scheduleSchema } from "agents/schedule";
86+
import { format, toZonedTime } from "date-fns-tz";
87+
import { buyStock } from "./auth0-ai-sample-tools/buy-stock";
88+
import { checkUsersCalendar } from "./auth0-ai-sample-tools/check-user-calendar";
89+
90+
/**
91+
* Weather information tool that requires human confirmation
92+
* When invoked, this will present a confirmation dialog to the user
93+
* The actual implementation is in the executions object below
94+
*/
95+
const getWeatherInformation = tool({
96+
description: "show the weather in a given city to the user",
97+
inputSchema: z.object({ city: z.string() }),
98+
});
99+
100+
/**
101+
* Local time tool that executes automatically
102+
* Since it includes an execute function, it will run without user confirmation
103+
* This is suitable for low-risk operations that don't need oversight
104+
*/
105+
const getLocalTime = tool({
106+
description: "get the local time for a specified location",
107+
inputSchema: z.object({
108+
timeZone: z.string().describe("IANA time zone name"),
109+
}),
110+
execute: async ({ timeZone: location }) => {
111+
const now = new Date();
112+
const zonedDate = toZonedTime(now, location);
113+
const output = format(zonedDate, "yyyy-MM-dd HH:mm:ssXXX", {
114+
timeZone: location,
115+
});
116+
return output;
117+
},
118+
});
119+
120+
const scheduleTask = tool({
121+
description: "A tool to schedule a task to be executed at a later time",
122+
inputSchema: unstable_scheduleSchema,
123+
execute: async ({ when, description }) => {
124+
const { agent } = getCurrentAgent();
125+
126+
function throwError(msg: string): string {
127+
throw new Error(msg);
128+
}
129+
if (when.type === "no-schedule") {
130+
return "Not a valid schedule input";
131+
}
132+
const input =
133+
when.type === "scheduled"
134+
? when.date // scheduled
135+
: when.type === "delayed"
136+
? when.delayInSeconds // delayed
137+
: when.type === "cron"
138+
? when.cron // cron
139+
: throwError("not a valid schedule input");
140+
try {
141+
agent!.schedule(input!, "executeTask" as keyof typeof agent, description);
142+
} catch (error) {
143+
console.error("error scheduling task", error);
144+
return `Error scheduling task: ${error}`;
64145
}
146+
return `Task scheduled for type "${when.type}" : ${input}`;
147+
},
148+
});
65149

66-
const response = await fetch(
67-
`https://${process.env.AUTH0_DOMAIN}/userinfo`,
68-
{
69-
headers: {
70-
Authorization: `Bearer ${tokenSet.access_token}`,
71-
},
72-
}
73-
);
150+
/**
151+
* Tool to list all scheduled tasks
152+
* This executes automatically without requiring human confirmation
153+
*/
154+
const getScheduledTasks = tool({
155+
description: "List all tasks that have been scheduled",
156+
inputSchema: z.object({}),
157+
execute: async () => {
158+
const { agent } = getCurrentAgent();
74159

75-
if (response.ok) {
76-
return { result: await response.json() };
160+
try {
161+
const tasks = agent!.getSchedules();
162+
if (!tasks || tasks.length === 0) {
163+
return "No scheduled tasks found.";
164+
}
165+
return tasks;
166+
} catch (error) {
167+
console.error("Error listing scheduled tasks", error);
168+
return `Error listing scheduled tasks: ${error}`;
77169
}
170+
},
171+
});
78172

79-
return "I couldn't verify your identity";
173+
/**
174+
* Tool to cancel a scheduled task by its ID
175+
* This executes automatically without requiring human confirmation
176+
*/
177+
const cancelScheduledTask = tool({
178+
description: "Cancel a scheduled task using its ID",
179+
inputSchema: z.object({
180+
taskId: z.string().describe("The ID of the task to cancel"),
181+
}),
182+
execute: async ({ taskId }) => {
183+
const { agent } = getCurrentAgent();
184+
try {
185+
await agent!.cancelSchedule(taskId);
186+
return `Task ${taskId} has been successfully canceled.`;
187+
} catch (error) {
188+
console.error("Error canceling scheduled task", error);
189+
return `Error canceling task ${taskId}: ${error}`;
190+
}
80191
},
81192
});
193+
194+
/**
195+
* Export all available tools
196+
* These will be provided to the AI model to describe available capabilities
197+
*/
198+
export const tools = {
199+
getWeatherInformation,
200+
getLocalTime,
201+
scheduleTask,
202+
getScheduledTasks,
203+
cancelScheduledTask,
204+
checkUsersCalendar,
205+
buyStock,
206+
};
207+
208+
/**
209+
* Implementation of confirmation-required tools
210+
* This object contains the actual logic for tools that need human approval
211+
* Each function here corresponds to a tool above that doesn't have an execute function
212+
*/
213+
export const executions = {
214+
getWeatherInformation: async ({ city }: { city: string }) => {
215+
console.log(`Getting weather information for ${city}`);
216+
return `The weather in ${city} is sunny`;
217+
},
218+
};
82219
```
83220

84-
Then in the `tools` export of the `src/agent/chat.ts` file, add the `getUserInfoTool` to the tools array:
221+
Then in the `tools` export of the `src/agent/chat.ts` file, add the `tools` to the `allTools` array:
85222

86223
```tsx src/agent/chat.ts wrap lines
87-
export const tools = {
88-
// Your other tools...
89-
getUserInfoTool,
90-
};
224+
async onChatMessage() {
225+
const allTools = {
226+
...tools,
227+
...(this.mcp?.getAITools?.() ?? {}),
228+
};
229+
... // The rest of the code
91230
```
92231
93232
### Test your application

0 commit comments

Comments
 (0)