Skip to content

Commit 074eba2

Browse files
chore(examples): improve llama-index calling apis example (#33)
* chore(examples): improve llama-index calling apis example * chore(readme): improve llamaindex example readme and .env.example file
1 parent 836a6bd commit 074eba2

File tree

18 files changed

+960
-225
lines changed

18 files changed

+960
-225
lines changed

.vscode/settings.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
{
22
"poetryMonorepo.appendExtraPaths": true,
33
"python.analysis.extraPaths": [
4+
"examples/calling-apis/langchain-examples",
5+
"examples/calling-apis/llama-index-examples",
46
"examples/async-user-confirmation/langchain-examples/src",
57
"examples/async-user-confirmation/llama-index-examples/src",
68
"examples/async-user-confirmation/sample-api",
79
"examples/authorization-for-rag/langchain-examples/langchain_rag",
810
"examples/authorization-for-rag/llama-index-examples/llama_index_rag",
911
"examples/authorization-for-tools/langchain-examples/src",
1012
"examples/authorization-for-tools/llama-index-examples/src",
11-
"examples/calling-apis/langchain-examples/src",
12-
"examples/calling-apis/llama-index-examples/src",
1313
"packages/auth0-ai/auth0_ai/auth0_ai",
1414
"packages/auth0-ai-langchain/auth0_ai_langchain/auth0_ai_langchain",
1515
"packages/auth0-ai-llamaindex/auth0_ai_llamaindex/auth0_ai_llamaindex"

examples/calling-apis/llama-index-examples/.env.example

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
AUTH0_DOMAIN="<auth0-domain>"
33
AUTH0_CLIENT_ID="<auth0-client-id>"
44
AUTH0_CLIENT_SECRET="<auth0-client-secret>"
5+
APP_BASE_URL="http://localhost:3000"
6+
APP_SECRET_KEY="<use [openssl rand -hex 32] to generate a 32 bytes value>"
57

68
# OpenAI
79
OPENAI_API_KEY="<openai-api-key>"

examples/calling-apis/llama-index-examples/README.md

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,23 +6,30 @@
66

77
- An OpenAI account and API key create one [here](https://platform.openai.com).
88
- [Use this page for instructions on how to find your OpenAI API key](https://help.openai.com/en/articles/4936850-where-do-i-find-my-openai-api-key).
9-
- A [Google OAuth 2.0 Client](https://console.cloud.google.com/apis/credentials) configured with access to the `https://www.googleapis.com/auth/calendar.freebusy` scope (Google Calendar API).
10-
- An [Auth0](https://manage.auth0.com/) account with the following configuration:
11-
- **Google connection** set up with:
12-
- The client ID and secret from the previously created Google client.
13-
- The following settings:
14-
- **Offline access** enabled.
15-
- **https://www.googleapis.com/auth/calendar.freebusy** scope granted.
16-
- **Token Vault** enabled.
17-
- **Regular Web Application** set up with:
18-
- **Allowed Callback URLs**: `http://localhost:3000/login/callback`
19-
- **Allowed Logout URLs**: `http://localhost:3000/`
20-
- **Connections**: The previously created **Google connection**.
21-
- **Advanced Settings -> Grant Types**: **Token Exchange (Federated Connection)** and **Refresh Token**.
9+
- An **[Auth0](https://auth0.com)** account and the following settings and resources configured:
10+
- An application to initiate the authorization flow:
11+
- **Application Type**: `Regular Web Application`
12+
- **Allowed Callback URLs**: `http://localhost:3000/auth/callback`
13+
- **Allowed Logout URLs**: `http://localhost:3000`
14+
- **Advanced Settings -> Grant Types**: `Refresh Token` and `Token Exchange (Federated Connection)` (or `urn:auth0:params:oauth:grant-type:token-exchange:federated-connection-access-token`)
15+
- Either **Google**, **Slack** or **Github** social connections enabled for the application:
16+
- **Google connection** set up instructions:
17+
- Create a [Google OAuth 2.0 Client](https://console.cloud.google.com/apis/credentials) configured with access to the `https://www.googleapis.com/auth/calendar.freebusy` scope (Google Calendar API).
18+
- On Auth0 Dashboard, set up the client ID and secret from the previously created Google client.
19+
- Enable following settings:
20+
- **Offline access** enabled.
21+
- **https://www.googleapis.com/auth/calendar.freebusy** scope granted.
22+
- **Token Vault** enabled.
23+
- **Slack connection** set up instructions:
24+
- Create a [Slack App](https://api.slack.com/apps) and follow the [Auth0's Signin with Slack](https://marketplace.auth0.com/integrations/sign-in-with-slack) `installation` instructions to set up the connection.
25+
- On Slack's OAuth & Permission settings, make sure to add the `channels:read` scope to the User Token scopes.
26+
- **Github connection** set up instructions:
27+
- Register a new app in [GitHub Developer Settings: OAuth Apps](https://github.com/settings/developers#oauth-apps) and follow the [Auth0's Github social connection](https://marketplace.auth0.com/integrations/github-social-connection) `installation` instructions to set up the connection.
28+
- On Auth0 Dashboard, set up the client ID and secret from the previously created Github App.
2229

2330
### Setup
2431

25-
Create a `.env` file using the format below:
32+
Copy the file `.env.example` to `.env` and fill in the required values:
2633

2734
```sh
2835
# Auth0

examples/calling-apis/llama-index-examples/poetry.lock

Lines changed: 102 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/calling-apis/llama-index-examples/pyproject.toml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,14 @@ python = "^3.11"
1414
python-dotenv = "^1.0.1"
1515
flask = { extras = ["async"], version = "^3.1.0" }
1616
requests = "^2.32.3"
17-
authlib = "^1.5.1"
1817
hypercorn = "^0.17.3"
1918
llama-index = "^0.12.33"
2019
llama-index-agent-openai = "^0.4.6"
20+
auth0-server-python = "^1.0.0b4"
2121
auth0-ai-llamaindex = { path = "../../../packages/auth0-ai-llamaindex", develop = true }
22+
slack-sdk = "^3.35.0"
23+
pygithub = "^2.6.1"
24+
asgiref = "^3.8.1"
2225

2326
[build-system]
2427
requires = ["poetry-core"]
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
import asyncio
2+
from asgiref.wsgi import WsgiToAsgi
23
from hypercorn.config import Config
34
from hypercorn.asyncio import serve
45
from src.app.app import app
56

7+
68
def main():
79
config = Config()
810
config.bind = ["0.0.0.0:3000"]
911
config.worker_class = "asyncio"
1012
config.use_reloader = True
1113

12-
loop = asyncio.new_event_loop()
13-
asyncio.set_event_loop(loop)
14-
loop.run_until_complete(serve(app, config))
14+
asyncio.run(serve(WsgiToAsgi(app), config))
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
from datetime import datetime
2+
from llama_index.agent.openai import OpenAIAgent
3+
4+
from .memory import get_memory
5+
from .tools.check_user_calendar import check_user_calendar_tool
6+
from .tools.list_channels import list_slack_channels_tool
7+
from .tools.list_repositories import list_github_repositories_tool
8+
9+
10+
system_prompt = f"""You are an assistant designed to answer random user's questions.
11+
**Additional Guidelines**:
12+
- Today’s date for reference: {datetime.now().isoformat()}
13+
"""
14+
15+
16+
async def get_agent(user_id: str, chat_id: str):
17+
chat_memory = await get_memory(user_id, chat_id)
18+
return OpenAIAgent.from_tools(
19+
model="gpt-4o",
20+
memory=chat_memory,
21+
system_prompt=system_prompt,
22+
tools=[check_user_calendar_tool, list_github_repositories_tool,
23+
list_slack_channels_tool],
24+
verbose=True
25+
)
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
from llama_index.core.storage.chat_store import SimpleChatStore
2+
from llama_index.core.memory import ChatMemoryBuffer
3+
4+
chat_store = SimpleChatStore()
5+
6+
7+
async def get_memory(user_id: str, chat_id: str):
8+
return ChatMemoryBuffer.from_defaults(
9+
token_limit=3000,
10+
chat_store=chat_store,
11+
chat_store_key=f"{user_id}_{chat_id}",
12+
)

examples/calling-apis/llama-index-examples/src/tools/check_user_calendar.py renamed to examples/calling-apis/llama-index-examples/src/agents/tools/check_user_calendar.py

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
1+
import requests
12
from datetime import datetime, timedelta
23
from typing import Annotated
3-
4-
import requests
5-
from auth0_ai_llamaindex.federated_connections import (
6-
FederatedConnectionError,
7-
get_credentials_for_connection,
8-
)
94
from llama_index.core.tools import FunctionTool
105

6+
from auth0_ai_llamaindex.federated_connections import FederatedConnectionError, get_credentials_for_connection
7+
from src.auth0.auth0_ai import with_calendar_free_busy_access
8+
119

1210
def add_hours(dt: datetime, hours: int) -> str:
1311
return (dt + timedelta(hours=hours)).isoformat()
@@ -31,7 +29,8 @@ def check_user_calendar_tool_function(
3129

3230
response = requests.post(
3331
url,
34-
headers={"Authorization": f"{credentials["token_type"]} {credentials["access_token"]}"},
32+
headers={
33+
"Authorization": f"{credentials["token_type"]} {credentials["access_token"]}"},
3534
json=body
3635
)
3736

@@ -46,8 +45,8 @@ def check_user_calendar_tool_function(
4645
return {"available": len(busy_resp["calendars"]["primary"]["busy"]) == 0}
4746

4847

49-
check_user_calendar_tool = FunctionTool.from_defaults(
48+
check_user_calendar_tool = with_calendar_free_busy_access(FunctionTool.from_defaults(
5049
name="check_user_calendar",
5150
description="Use this function to check if the user is available on a certain date and time",
5251
fn=check_user_calendar_tool_function,
53-
)
52+
))
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
from slack_sdk import WebClient
2+
from slack_sdk.errors import SlackApiError
3+
from llama_index.core.tools import FunctionTool
4+
5+
from auth0_ai_llamaindex.federated_connections import get_credentials_for_connection, FederatedConnectionError
6+
from src.auth0.auth0_ai import with_slack_access
7+
8+
9+
def list_channels_tool_function():
10+
# Get the access token from Auth0 AI
11+
credentials = get_credentials_for_connection()
12+
13+
# Slack SDK
14+
try:
15+
client = WebClient(token=credentials["access_token"])
16+
response = client.conversations_list(
17+
exclude_archived=True,
18+
types="public_channel,private_channel",
19+
limit=10
20+
)
21+
channels = response['channels']
22+
channel_names = [channel['name'] for channel in channels]
23+
return channel_names
24+
except SlackApiError as e:
25+
if e.response['error'] == 'not_authed':
26+
raise FederatedConnectionError(
27+
"Authorization required to access the Federated Connection API")
28+
29+
raise ValueError(f"An error occurred: {e.response['error']}")
30+
31+
32+
list_slack_channels_tool = with_slack_access(FunctionTool.from_defaults(
33+
name="list_slack_channels",
34+
description="List channels for the current user on Slack",
35+
fn=list_channels_tool_function,
36+
))

0 commit comments

Comments
 (0)