-
Couldn't load subscription status.
- Fork 14
Updating AI #75
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Updating AI #75
Conversation
bcabe4f to
a3039f3
Compare
df48b60 to
3789029
Compare
e9b4c4b to
eecf84d
Compare
| <Frame> | ||
| <img | ||
| className="hidden dark:block" | ||
| src="/img/intro/web_applications_with_spa_diagram_dark.png" | ||
| alt="Token Vault using Access Tokens" | ||
| /> | ||
| <img | ||
| className="block dark:hidden" | ||
| src="/img/intro/web_applications_with_spa_diagram_light.png" | ||
| alt="Token Vault using Access Tokens" | ||
| /> | ||
| </Frame> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔥
| @@ -0,0 +1,139 @@ | |||
| --- | |||
| title: Calling third-party Party APIs | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"-party Party" 😸
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
seeing a lot of instances, please find/replace :)
| Clone <Icon icon="github" iconType="solid" /> <a href={`https://github.com/${repository}.git`} target="_blank" rel="noreferrer" className="link">{repository}</a> and navigate to <code>{folderPath}</code> directory. | ||
| </div> | ||
| ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should be able to reference the DownloadQuickstartButton now inside of here i imagine?
| export const DownloadQuickstartButton = ({ |
We have this feature recently added now w/ Download Sample button on these.
| - Integrate with an AI agent to call Google APIs. | ||
| </Card> | ||
|
|
||
| <Prerequisites /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
a lot of these Prerequisites have recently been adjusted, this one for example should pass these props:
docs-v2/auth4genai/snippets/get-started/langchain-next-js/call-others-api.mdx
Lines 5 to 11 in 3188f5f
| <Prerequisites | |
| createAuth0ApplicationStep={{ | |
| enableTokenVaultGrant: true, | |
| }} | |
| createAuth0ApiStep={{}} | |
| createResourceServerClientStep={{}} | |
| /> |
Lets double check them..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately these will also be conditional right now depending on framework selection, as our langchain-FastAPI / python example is using FCRT / embedded (precompiled) agent flow still.
docs-v2/auth4genai/snippets/get-started/langchain-fastapi-py/call-others-api.mdx
Lines 5 to 12 in 3188f5f
| <Prerequisites | |
| createAuth0ApplicationStep={{ | |
| applicationType: "Regular Web Applications", | |
| callbackUrl: "http://localhost:8000/api/auth/callback", | |
| logoutUrl: "http://localhost:5173", | |
| enableTokenVaultGrant: true, | |
| }} | |
| /> |
So i suppose suggestion here would be to keep the contents here and below within the LangChainNextjsCallOthersApi / FastApiCallOthersApi components respectively.
samples today:
https://auth0.com/ai/docs/get-started/call-others-apis-on-users-behalf#langgraph-js-%2B-next-js
https://auth0.com/ai/docs/get-started/call-others-apis-on-users-behalf#langgraph-%2B-fastapi
| # LANGGRAPH | ||
| LANGGRAPH_API_URL=http://localhost:54367 | ||
| LANGCHAIN_CALLBACKS_BACKGROUND=false | ||
| ``` | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this file is missing some important elements. Let's rebase it once more...e.g.:
AUTH0_CUSTOM_API_CLIENT_ID="{yourCustomApiClientId}"
AUTH0_CUSTOM_API_CLIENT_SECRET="{yourCustomApiClientSecret}"
| }, | ||
| }); | ||
| ## or Follow manual steps | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggest re-adding <Prerequisites ... /> in these files
| ...body, | ||
| config: { | ||
| configurable: { | ||
| _credentials: { | ||
| refreshToken: await getRefreshToken(), | ||
| }, | ||
| }, | ||
| }, | ||
| }; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lets re-add snippets to match existing please, e.g.:
export const { GET, POST, PUT, PATCH, DELETE, OPTIONS, runtime } =
initApiPassthrough({
apiUrl: process.env.LANGGRAPH_API_URL,
baseRoute: "chat/",
headers: async () => {
const accessToken = await getAccessToken();
return {
Authorization: `Bearer ${accessToken}`,
...
| if (!token) { | ||
| throw new HTTPException(401, { | ||
| message: | ||
| "Authorization header format must be of the form: Bearer <token>", | ||
| }); | ||
| } | ||
|
|
||
| if (token) { | ||
| try { | ||
| // Verify the JWT using Auth0 JWKS | ||
| const { payload } = await jwtVerify(token, JWKS, { | ||
| issuer: `https://${AUTH0_DOMAIN}/`, | ||
| audience: AUTH0_AUDIENCE, | ||
| }); | ||
| Add a new file, `src/components/auth0-ai/FederatedConnections/FederatedConnectionInterruptHandler.tsx`, with the following code: | ||
|
|
||
| console.log("✅ Auth0 JWT payload resolved!", payload); | ||
|
|
||
| // Return the verified payload - this becomes available in graph nodes | ||
| return { | ||
| identity: payload.sub!, | ||
| email: payload.email as string, | ||
| permissions: | ||
| typeof payload.scope === "string" ? payload.scope.split(" ") : [], | ||
| auth_type: "auth0", | ||
| // include the access token for use with Auth0 Token Vault exchanges by tools | ||
| getRawAccessToken: () => token, | ||
| // Add any other claims you need | ||
| ...payload, | ||
| }; | ||
| } catch (jwtError) { | ||
| console.log( | ||
| "Auth0 JWT validation failed:", | ||
| jwtError instanceof Error ? jwtError.message : "Unknown error" | ||
| ); | ||
| throw new HTTPException(401, { | ||
| message: "Invalid Authorization token provided.", | ||
| }); | ||
| } | ||
| } | ||
| }); | ||
|
|
||
| export { auth as authHandler }; | ||
| ``` | ||
| ### Use access token to call APIs from a tool | ||
| Once the user is authenticated, you can fetch an access token from Token Vault using the Auth0 AI SDK. In this example, we fetch an access token for a Google social connection. | ||
| Once you've obtained the access token for a connection, you can use it with an AI agent to fetch data during a tool call and provide contextual data in its response. | ||
| This example uses `GmailSearch` from the `@langchain/community` tools. This tool will use the access token provided by Token Vault to query for emails. | ||
| ```ts src/lib/tools/gmail-seatch.ts wrap lines highlight={10} | ||
| //... | ||
| import { getAccessTokenFromTokenVault } from "@auth0/ai-langchain"; | ||
| import { GmailSearch } from "@langchain/community/tools/gmail"; | ||
|
|
||
| import { withGmailSearch } from "../../lib/auth0-ai"; | ||
|
|
||
| export const gmailSearchTool = withGmailSearch( | ||
| new GmailSearch({ | ||
| credentials: { | ||
| accessToken: async () => getAccessTokenFromTokenVault(), | ||
| }, | ||
| }) | ||
| ); | ||
| ``` | ||
| Update your tool call to request an access token, as shown in the following example: | ||
| ```ts src/lib/agent.ts wrap lines highlight={2,10-13} | ||
| //... | ||
| import { gmailSearchTool } from './tools/gmail-search'; | ||
|
|
||
| //... existing code | ||
|
|
||
| const tools = [gmailSearchTool]; | ||
| //... existing code | ||
| export const agent = createReactAgent({ | ||
| llm, | ||
| tools: new ToolNode(tools, { | ||
| // Error handler must be disabled in order to trigger interruptions from within tools. | ||
| handleToolErrors: false, | ||
| }), | ||
| // Modify the stock prompt in the prebuilt agent. | ||
| prompt: AGENT_SYSTEM_TEMPLATE, | ||
| store, | ||
| checkpointer, | ||
| }); | ||
| ``` | ||
| ### Add step-up authorization | ||
| When you try to use the tool, the application requests any additional Google scopes that are required but not yet authorized. This process is called step-up authorization. | ||
| To implement, install the Auth0 AI Components for Next.js SDK to get the required UI components: | ||
| ```bash wrap lines | ||
| npx @auth0/ai-components add TokenVault | ||
| ``` | ||
| Add a new file, `src/components/auth0-ai/TokenVault/TokenVaultInterruptHandler.tsx`, with the following code: | ||
| ```tsx src/components/auth0-ai/TokenVault/TokenVaultInterruptHandler.tsx wrap lines | ||
| import { TokenVaultInterrupt } from "@auth0/ai/interrupts"; | ||
| import type { Interrupt } from "@langchain/langgraph-sdk"; | ||
|
|
||
| import { TokenVaultConsent } from "@/components/auth0-ai/TokenVault"; | ||
|
|
||
| interface TokenVaultInterruptHandlerProps { | ||
| interrupt: Interrupt | undefined | null; | ||
| onFinish: () => void; | ||
| } | ||
|
|
||
| export function TokenVaultInterruptHandler({ | ||
| interrupt, | ||
| onFinish, | ||
| }: TokenVaultInterruptHandlerProps) { | ||
| if ( | ||
| !interrupt || | ||
| !TokenVaultInterrupt.isInterrupt(interrupt.value) | ||
| ) { | ||
| return null; | ||
| } | ||
|
|
||
| return ( | ||
| <div key={interrupt.ns?.join("")} className="whitespace-pre-wrap"> | ||
| <TokenVaultConsent | ||
| mode="popup" | ||
| interrupt={interrupt.value} | ||
| onFinish={onFinish} | ||
| connectWidget={{ | ||
| title: "Authorization Required.", | ||
| description: interrupt.value.message, | ||
| action: { label: "Authorize" }, | ||
| }} | ||
| /> | ||
| </div> | ||
| ); | ||
| } | ||
| ``` | ||
| Now, update your chat window code to include the `TokenVaultInterruptHandler` component, for example: | ||
| ```tsx src/components/chat-window.tsx wrap lines highlight={2,3,8-19,36-38} | ||
| //... | ||
| import { TokenVaultInterruptHandler } from '@/components/auth0-ai/TokenVault/TokenVaultInterruptHandler'; | ||
|
|
||
| //... existing code | ||
| export function ChatWindow(props: { | ||
| //... existing code | ||
| }) { | ||
| const [threadId, setThreadId] = useQueryState('threadId'); | ||
| const [input, setInput] = useState(''); | ||
| const chat = useStream({ | ||
| apiUrl: props.endpoint, | ||
| assistantId: 'agent', | ||
| threadId, | ||
| onThreadId: setThreadId, | ||
| onError: (e: any) => { | ||
| console.error('Error: ', e); | ||
| toast.error(`Error while processing your request`, { description: e.message }); | ||
| }, | ||
| }); | ||
| //... existing code | ||
| return ( | ||
| <StickToBottom> | ||
| <StickyToBottomContent | ||
| className="absolute inset-0" | ||
| contentClassName="py-8 px-2" | ||
| content={ | ||
| chat.messages.length === 0 ? ( | ||
| <div>{props.emptyStateComponent}</div> | ||
| ) : ( | ||
| <> | ||
| <ChatMessages | ||
| aiEmoji={props.emoji} | ||
| messages={chat.messages} | ||
| emptyStateComponent={props.emptyStateComponent} | ||
| /> | ||
| <div className="flex flex-col max-w-[768px] mx-auto pb-12 w-full"> | ||
| <TokenVaultInterruptHandler interrupt={chat.interrupt} onFinish={() => chat.submit(null)} /> | ||
| </div> | ||
| </> | ||
| ) | ||
| } | ||
| {/* ... existing code */} | ||
| ></StickyToBottomContent> | ||
| </StickToBottom> | ||
| ); | ||
| } | ||
| ``` | ||
| Now when step-up authorization is required, the user will see a prompt in the chat window asking them to authorize. | ||
| ```tsx src/components/auth0-ai/FederatedConnections/FederatedConnectionInterruptHandler.tsx wrap lines | ||
| import { FederatedConnectionInterrupt } from "@auth0/ai/interrupts"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's do a quick find for all existing FederatedConnectionInterruptHandler / FederatedConnectionInterrupt refs plz 🙏 - these are all adjusted after naming update
| Start your application. If you are already logged in, make sure to log out and log back in using Google. Then, ask your AI agent to fetch emails from your Gmail account! | ||
|
|
||
| That's it! You successfully integrated third-party API access using Token Vault into your app. | ||
| </Step> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Largely, i think this file should just mimic existing template in main... w/ any new semantic elements you still need. Seems just needs a fresh rebase/re-review.
|
|
||
| Create a file at `app/core/auth0_ai.py` to instantiate the Auth0 AI SDK client: | ||
| ## or Follow manual steps | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggest adding Prerequisites within here (same advice w/ all get-started snippets)
| ) | ||
| ) | ||
|
|
||
| with_calendar_access = auth0_ai.with_federated_connection( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this one needs fresh rebase/update too... seeing with_federated_connection and a bunch of old refs.


By submitting a PR to this repository, you agree to the terms within the Auth0 Code of Conduct. Please see the contributing guidelines for how to create and submit a high-quality PR for this repo.
Description
References
Testing
Checklist