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
46 changes: 45 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,48 @@ next-env.d.ts
.vscode
# LangGraph API
.langgraph_api
.claude/*
.claude/*

### Python ###
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# C extensions
*.so

# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST

# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Python virtual environments
.env
.venv
venv/
env/
4 changes: 2 additions & 2 deletions py-langchain/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,8 @@ Finally, you can start the frontend server in another terminal:
```bash
cd frontend
cp .env.example .env # Copy the `.env.example` file to `.env`.
npm install
npm run dev
bun install
bun run dev
```

This will start a React vite server on port 5173.
Expand Down
6 changes: 4 additions & 2 deletions py-langchain/backend/app/agents/assistant0.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@ def get_prompt():
today_str = date.today().strftime('%Y-%m-%d')
return (
f"You are a personal assistant named Assistant0. You are a helpful assistant that can answer questions and help with tasks. "
f"Today's date is {today_str}. You have access to a set of tools, use the tools as needed to answer the user's question. "
f"Render the email body as a markdown block, do not wrap it in code blocks."
f"You have access to a set of tools. When using tools, you MUST provide valid JSON arguments. Always format tool call arguments as proper JSON objects. "
f"For example, when calling shop_online tool, format like this: "
f'{{"product": "iPhone", "qty": 1, "priceLimit": 1000}} '
f"Use the tools as needed to answer the user's question. Render the email body as a markdown block, do not wrap it in code blocks. Today is {today_str}."
)

agent = create_react_agent(
Expand Down
8 changes: 4 additions & 4 deletions py-langchain/backend/app/agents/tools/google_calendar.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
from google.oauth2.credentials import Credentials
from googleapiclient.discovery import build
from pydantic import BaseModel
from auth0_ai_langchain.federated_connections import (
get_access_token_for_connection,
from auth0_ai_langchain.token_vault import (
get_access_token_from_token_vault,
)
import datetime
import json
Expand All @@ -13,10 +13,10 @@

async def list_upcoming_events_fn():
"""List upcoming events from the user's Google Calendar"""
google_access_token = get_access_token_for_connection()
google_access_token = get_access_token_from_token_vault()
if not google_access_token:
raise ValueError(
"Authorization required to access the Federated Connection API"
"Authorization required to access the Token Vault API"
)

calendar_service = build(
Expand Down
10 changes: 5 additions & 5 deletions py-langchain/backend/app/agents/tools/shop_online.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import httpx
from langchain_core.tools import StructuredTool
from auth0_ai_langchain.ciba import get_ciba_credentials
from auth0_ai_langchain.async_authorization import get_async_authorization_credentials
from pydantic import BaseModel

from app.core.auth0_ai import with_async_user_confirmation
from app.core.auth0_ai import with_async_authorization
from app.core.config import settings


Expand All @@ -21,10 +21,10 @@ async def shop_online_fn(product: str, quantity: int):
# No API set, mock a response
return f"Ordered {quantity} {product}"

credentials = get_ciba_credentials()
credentials = get_async_authorization_credentials()

if not credentials:
raise ValueError("CIBA credentials not found")
raise ValueError("Async Authorization credentials not found")

headers = {
"Authorization": f"Bearer {credentials['access_token']}",
Expand Down Expand Up @@ -56,7 +56,7 @@ async def shop_online_fn(product: str, quantity: int):
}


shop_online = with_async_user_confirmation(
shop_online = with_async_authorization(
StructuredTool(
name="shop_online",
description="Tool to buy products online.",
Expand Down
9 changes: 6 additions & 3 deletions py-langchain/backend/app/core/auth0_ai.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@
)
)

with_calendar_access = auth0_ai.with_federated_connection(
with_calendar_access = auth0_ai.with_token_vault(
connection="google-oauth2",
scopes=["https://www.googleapis.com/auth/calendar.events"],
)

with_async_user_confirmation = auth0_ai.with_async_user_confirmation(
with_async_authorization = auth0_ai.with_async_authorization(
audience=settings.SHOP_API_AUDIENCE,
# add any scopes you want to use with your API
scopes=["openid", "product:buy"],
scopes=["openid", "buy:product"],
binding_message=lambda product,
quantity: f"Do you want to buy {quantity} {product}",
user_id=lambda *_, **__: ensure_config()
Expand All @@ -39,4 +39,7 @@
# In practice, the process that is awaiting the user confirmation
# could crash or timeout before the user approves the request.
on_authorization_request="block",
# Note: Setting a requested expiry greater than 300 (seconds) will force email verification
# instead of using the push notification flow.
# requested_expiry=301,
)
13 changes: 10 additions & 3 deletions py-langchain/backend/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,19 @@ description = "Assistant0: An AI Personal Assistant Secured with Auth0 - LangGra
readme = "README.md"
requires-python = ">=3.13"
dependencies = [
"auth0-ai>=0.2.0",
"auth0-ai-langchain>=1.0.0b3",
"auth0-ai",
"auth0-ai-langchain",
"auth0-fastapi>=1.0.0b4",
"fastapi[standard]>=0.115.14",
"google-api-python-client>=2.176.0",
"httpx>=0.28.1",
"itsdangerous>=2.2.0",
"langchain-openai>=0.3.28",
"langgraph-cli[inmem]>=0.2.12",
"langchain-text-splitters>=0.3.0",
"langgraph-cli[inmem]>=0.3.6",
"langgraph>=0.5.4",
"langgraph-api==0.2.102",
"langgraph-runtime-inmem==0.6.0",
"pydantic-settings>=2.10.1",
"sqlmodel>=0.0.24",
"openfga-sdk>=0.9.5",
Expand All @@ -24,3 +27,7 @@ dependencies = [
"langchain-postgres>=0.0.15",
"greenlet>=3.2.3",
]

[tool.uv.sources]
auth0-ai = { path = "../../temp-packages/auth0-ai", editable = true }
auth0-ai-langchain = { path = "../../temp-packages/auth0-ai-langchain", editable = true }
60 changes: 37 additions & 23 deletions py-langchain/backend/uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file added py-langchain/frontend/auth0-ai-0.0.0.tgz
Binary file not shown.
Loading