Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 18 additions & 5 deletions examples/calling-apis/chatbot/app/(langgraph)/lib/agent.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,31 @@
import { AIMessage, SystemMessage } from "@langchain/core/messages";
import { RunnableLike } from "@langchain/core/runnables";
import { END, InMemoryStore, MemorySaver, MessagesAnnotation, START, StateGraph } from "@langchain/langgraph";
import {
END,
InMemoryStore,
MemorySaver,
MessagesAnnotation,
START,
StateGraph,
} from "@langchain/langgraph";
import { ToolNode } from "@langchain/langgraph/prebuilt";
import { ChatOpenAI } from "@langchain/openai";

import { calendarCommunityTool, checkUsersCalendar, gmailCommunityTool, listChannels, listRepositories } from "./tools";
import {
checkUsersCalendar,
gmailCommunityTool,
listChannels,
listRepositories,
viewCalendarEvents,
} from "./tools";

const model = new ChatOpenAI({
model: "gpt-4o",
}).bindTools([
checkUsersCalendar,
listChannels,
listRepositories,
calendarCommunityTool,
viewCalendarEvents,
gmailCommunityTool,
]);

Expand Down Expand Up @@ -81,8 +94,8 @@ const stateGraph = new StateGraph(MessagesAnnotation)
listChannels,
// A tool with token vault access
listRepositories,
// A community tool with token vault access
calendarCommunityTool,
// A google calendar events tool with token vault access
viewCalendarEvents,
// A community tool with token vault access
gmailCommunityTool,
],
Expand Down
8 changes: 6 additions & 2 deletions examples/calling-apis/chatbot/app/(langgraph)/lib/auth0-ai.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Auth0AI } from "@auth0/ai-langchain";
const auth0AI = new Auth0AI({
auth0: {
domain: process.env.AUTH0_DOMAIN!,
clientId: process.env.RESOURCE_SERVER_CLIENT_ID!, // Resource server client ID for token exchange
clientId: process.env.AUTH0_CUSTOM_API_CLIENT_ID!, // Resource server client ID for token exchange
clientSecret: process.env.RESOURCE_SERVER_CLIENT_SECRET!, // Resource server client secret
},
});
Expand All @@ -21,7 +21,11 @@ const withAccessTokenForConnection = (connection: string, scopes: string[]) =>

export const withGoogleCalendar = withAccessTokenForConnection(
"google-oauth2",
["https://www.googleapis.com/auth/calendar.freebusy"]
[
"https://www.googleapis.com/auth/calendar.freebusy",
"https://www.googleapis.com/auth/calendar",
"https://www.googleapis.com/auth/calendar.events",
]
);

export const withGitHub = withAccessTokenForConnection("github", ["repo"]);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,83 @@
import { addHours, formatISO } from "date-fns";
import { GaxiosError } from "gaxios";
import { google } from "googleapis";
import { z } from "zod";

import { getAccessTokenFromTokenVault } from "@auth0/ai-langchain";
import { GoogleCalendarViewTool } from "@langchain/community/tools/google_calendar";
import { ChatOpenAI } from "@langchain/openai";
import { TokenVaultError } from "@auth0/ai/interrupts";
import { tool } from "@langchain/core/tools";

import { withGoogleCalendar } from "../auth0-ai";

export const viewCalendarEvents = withGoogleCalendar(
tool(
async ({ startDate, endDate, maxResults }) => {
try {
const accessToken = getAccessTokenFromTokenVault();

const calendar = google.calendar("v3");
const auth = new google.auth.OAuth2();

auth.setCredentials({
access_token: accessToken,
});

import { withGoogleCalendarCommunity } from "../../lib/auth0-ai";
const response = await calendar.events.list({
auth,
calendarId: "primary",
timeMin: formatISO(startDate),
timeMax: endDate
? formatISO(endDate)
: addHours(startDate, 24).toISOString(),
maxResults: maxResults || 10,
singleEvents: true,
orderBy: "startTime",
});

const model = new ChatOpenAI({
model: "gpt-4o-mini",
temperature: 0,
});
const events = response.data.items || [];

export const calendarCommunityTool = withGoogleCalendarCommunity(
new GoogleCalendarViewTool({
credentials: {
accessToken: async () => getAccessTokenFromTokenVault(),
calendarId: "primary",
return {
events: events.map((event) => ({
id: event.id,
summary: event.summary,
start: event.start?.dateTime || event.start?.date,
end: event.end?.dateTime || event.end?.date,
description: event.description,
location: event.location,
})),
totalEvents: events.length,
};
} catch (err) {
if (err instanceof GaxiosError && err.status === 401) {
throw new TokenVaultError(
`Authorization required to access the Token Vault`
);
}
throw err;
}
},
model,
})
{
name: "view_calendar_events",
description: "View calendar events for a specific date range",
schema: z.object({
startDate: z.coerce
.date()
.describe("The start date to view events from"),
endDate: z.coerce
.date()
.nullable()
.default(null)
.describe(
"The end date to view events until (optional, defaults to 24 hours from start)"
),
maxResults: z
.number()
.nullable()
.default(10)
.describe(
"Maximum number of events to return (optional, defaults to 10)"
),
}),
}
)
);