Skip to content
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

Add Langgraph samples #33

Merged
merged 9 commits into from
Jan 23, 2025
Merged
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
11 changes: 11 additions & 0 deletions examples/authorization-for-rag/genkit/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# OpenAI
OPENAI_API_KEY=<your-openai-api-key>


# Okta FGA
FGA_STORE_ID=<your-fga-store-id>
FGA_CLIENT_ID=<your-fga-store-client-id>
FGA_CLIENT_SECRET=<your-fga-store-client-secret>
# Required only for non-US regions
FGA_API_URL=https://api.xxx.fga.dev
FGA_API_AUDIENCE=https://api.xxx.fga.dev/
3 changes: 1 addition & 2 deletions examples/authorization-for-rag/genkit/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,8 @@ OPENAI_API_KEY=xx-xxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxx
FGA_STORE_ID=xxxxxxxxxxxxxxxxxxxxxxxxxxx
FGA_CLIENT_ID=xxxxxxxxxxxxxxxxxxxxxxxxxxx
FGA_CLIENT_SECRET=xxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxx
# Optional
# Required only for non-US regions
FGA_API_URL=https://api.xxx.fga.dev
FGA_API_TOKEN_ISSUER=auth.fga.dev
FGA_API_AUDIENCE=https://api.xxx.fga.dev/
```

Expand Down
11 changes: 11 additions & 0 deletions examples/authorization-for-rag/langchain/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# OpenAI
OPENAI_API_KEY=<your-openai-api-key>


# Okta FGA
FGA_STORE_ID=<your-fga-store-id>
FGA_CLIENT_ID=<your-fga-store-client-id>
FGA_CLIENT_SECRET=<your-fga-store-client-secret>
# Required only for non-US regions
FGA_API_URL=https://api.xxx.fga.dev
FGA_API_AUDIENCE=https://api.xxx.fga.dev/
3 changes: 1 addition & 2 deletions examples/authorization-for-rag/langchain/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,8 @@ This example demonstrates how to combine [LangChain](https://js.langchain.com/do
FGA_STORE_ID=xxxxxxxxxxxxxxxxxxxxxxxxxxx
FGA_CLIENT_ID=xxxxxxxxxxxxxxxxxxxxxxxxxxx
FGA_CLIENT_SECRET=xxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxx
# Optional
# Required only for non-US regions
FGA_API_URL=https://api.xxx.fga.dev
FGA_API_TOKEN_ISSUER=auth.fga.dev
FGA_API_AUDIENCE=https://api.xxx.fga.dev/
```

Expand Down
45 changes: 10 additions & 35 deletions examples/authorization-for-rag/langchain/helpers/langchain.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { createStuffDocumentsChain } from "langchain/chains/combine_documents";
import { createRetrievalChain } from "langchain/chains/retrieval";
import { MemoryVectorStore } from "langchain/vectorstores/memory";

import { Document, DocumentInterface } from "@langchain/core/documents";
import { DocumentInterface } from "@langchain/core/documents";
import { ChatPromptTemplate } from "@langchain/core/prompts";
import { BaseRetrieverInterface } from "@langchain/core/retrievers";
import { Runnable, RunnableInterface } from "@langchain/core/runnables";
import { ChatOpenAI, OpenAIEmbeddings } from "@langchain/openai";
import { ChatOpenAI } from "@langchain/openai";
import { LanguageModelLike } from "@langchain/core/language_models/base";

/**
* Represents a chain that uses a retriever to gather relevant documents
Expand Down Expand Up @@ -36,7 +36,10 @@ export class RetrievalChain {
`Answer the user's question: {input} based on the following context {context}. Only use the information provided in the context. If you need more information, ask for it.`
);
const combineDocsChain = await createStuffDocumentsChain({
llm: new ChatOpenAI({ temperature: 0, modelName: "gpt-4o-mini" }),
llm: new ChatOpenAI({
temperature: 0,
model: "gpt-4o-mini",
}) as unknown as LanguageModelLike,
prompt,
});
const retrievalChain = await createRetrievalChain({
Expand All @@ -48,39 +51,11 @@ export class RetrievalChain {
}

// Query the retrieval chain with a user question
async query({ query }: { query: string }) {
const response = await this.engine.invoke({
async query(query: string) {
const { answer } = await this.engine.invoke({
input: query,
});

return response;
}
}

/**
* Represents an in-memory store for the vector embeddings of the documents.
*
* @remarks
* This store is used to create a vector store retriever for the retrieval chain.
*/
export class MemoryStore {
private store: MemoryVectorStore;

private constructor(store: MemoryVectorStore) {
this.store = store;
}

static async fromDocuments(documents: Document<Record<string, any>>[]) {
const embeddings = new OpenAIEmbeddings();
const vectorStore = await MemoryVectorStore.fromDocuments(
documents,
embeddings
);

return new MemoryStore(vectorStore);
}

asRetriever() {
return this.store.asRetriever();
return answer;
}
}
15 changes: 8 additions & 7 deletions examples/authorization-for-rag/langchain/index.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
/**
* LangChain Example: Retrievers with Okta FGA (Fine-Grained Authorization)
*
*
*/
import "dotenv/config";
import { FGARetriever } from "@auth0/ai-langchain";

import { MemoryStore, RetrievalChain } from "./helpers/langchain";
import { RetrievalChain } from "./helpers/langchain";
import { readDocuments } from "./helpers/read-documents";
import { MemoryVectorStore } from "langchain/vectorstores/memory";
import { OpenAIEmbeddings } from "@langchain/openai";

/**
* Demonstrates the usage of the Okta FGA (Fine-Grained Authorization)
Expand All @@ -32,7 +32,10 @@ async function main() {
// 1. Read and load documents from the assets folder
const documents = await readDocuments();
// 2. Create an in-memory vector store from the documents for OpenAI models.
const vectorStore = await MemoryStore.fromDocuments(documents);
const vectorStore = await MemoryVectorStore.fromDocuments(
documents,
new OpenAIEmbeddings({ model: "text-embedding-3-small" })
);
// 3. Create a retrieval chain with root prompt and OpenAI model configuration
const retrievalChain = await RetrievalChain.create({
// 4. Chain the retriever with the FGARetriever to check the permissions.
Expand All @@ -47,9 +50,7 @@ async function main() {
}),
});
// 5. Query the retrieval chain with a prompt
const { answer } = await retrievalChain.query({
query: "Show me forecast for ZEKO?",
});
const answer = await retrievalChain.query("Show me forecast for ZEKO?");

/**
* Output: `The provided context does not include specific financial forecasts...`
Expand Down
10 changes: 5 additions & 5 deletions examples/authorization-for-rag/langchain/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "langchain-retrievers-with-fga",
"version": "0.0.0",
"description": "Demonstrates the usage of the Okta FGA with a langchain to query documents with permission checks.",
"description": "Demonstrates the usage of the Okta FGA with LangChain to query documents with permission checks.",
"x-type": "module",
"main": "index.js",
"author": {
Expand All @@ -15,12 +15,12 @@
},
"dependencies": {
"@auth0/ai-langchain": "*",
"@langchain/openai": "^0.3.16",
"@langchain/openai": "^0.3.17",
"@openfga/sdk": "^0.8.0",
"dotenv": "16.4.7",
"langchain": "^0.3.11"
"dotenv": "^16.4.7",
"langchain": "^0.3.12"
},
"devDependencies": {
"@types/node": "^22.10.6"
"@types/node": "^22.10.7"
}
}
11 changes: 11 additions & 0 deletions examples/authorization-for-rag/langgraph-agentic/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# OpenAI
OPENAI_API_KEY=<your-openai-api-key>


# Okta FGA
FGA_STORE_ID=<your-fga-store-id>
FGA_CLIENT_ID=<your-fga-store-client-id>
FGA_CLIENT_SECRET=<your-fga-store-client-secret>
# Required only for non-US regions
FGA_API_URL=https://api.xxx.fga.dev
FGA_API_AUDIENCE=https://api.xxx.fga.dev/
32 changes: 32 additions & 0 deletions examples/authorization-for-rag/langgraph-agentic/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Security
.env
.temp.md
# Node.js
node_modules/
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# TypeScript
*.tsbuildinfo

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# dotenv environment variables file
.env.test
.env.production

# Optional VS Code settings
.vscode/*
# for local testing
helpers/fga-retriever.ts
72 changes: 72 additions & 0 deletions examples/authorization-for-rag/langgraph-agentic/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# LangChain Retrievers + LangGraph Agents + Okta FGA

This example demonstrates how to combine [LangChain](https://js.langchain.com/) RAG methods and [LangGraph](https://langchain-ai.github.io/langgraphjs/) agents with robust authorization controls for RAG workflows. Using [Okta FGA](https://docs.fga.dev/), it ensures that users can only access documents they are authorized to view. The example retrieves relevant documents, enforces access permissions, and generates responses based only on authorized data, maintaining strict data security and preventing unauthorized access.

## Getting Started

### Prerequisites

- An Okta FGA account, you can create one [here](https://dashboard.fga.dev).
- An OpenAI account and API key create one [here](https://platform.openai.com).

### Setup

1. Create a `.env` file by renaming the included `.env.example` file. It should look like this:

```sh
# OpenAI
OPENAI_API_KEY=xx-xxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxx

# Okta FGA
FGA_STORE_ID=xxxxxxxxxxxxxxxxxxxxxxxxxxx
FGA_CLIENT_ID=xxxxxxxxxxxxxxxxxxxxxxxxxxx
FGA_CLIENT_SECRET=xxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxx
# Required only for non-US regions
FGA_API_URL=https://api.xxx.fga.dev
FGA_API_AUDIENCE=https://api.xxx.fga.dev/
```

#### Obtain OpenAI API Key

[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). Once you have your key, update the `.env` file accordingly.

#### Configure Okta FGA

1. **Create a client**

Navigate to _Settings_ and in the _Authorized Clients_ section click **+ Create Client** button. On the new page give your client a name and mark all three client permissions then click **Create**.

2. Copy the information on the modal and update your `.env` file with the values you now have for `FGA_STORE_ID`, `FGA_CLIENT_ID`, and `FGA_CLIENT_SECRET`. Click **Continue** to get values for `FGA_API_URL` and `FGA_API_AUDIENCE`.

### How to run it

1. Install dependencies.

```sh
$ npm install
```

2. Initialize the FGA model and tuples

```sh
$ npm run fga:init
```

3. Running the example

```sh
npm start
```

---

<p align="center">
<picture>
<source media="(prefers-color-scheme: light)" srcset="https://cdn.auth0.com/website/sdks/logos/auth0_light_mode.png" width="150">
<source media="(prefers-color-scheme: dark)" srcset="https://cdn.auth0.com/website/sdks/logos/auth0_dark_mode.png" width="150">
<img alt="Auth0 Logo" src="https://cdn.auth0.com/website/sdks/logos/auth0_light_mode.png" width="150">
</picture>
</p>
<p align="center">Auth0 is an easy to implement, adaptable authentication and authorization platform. To learn more checkout <a href="https://auth0.com/why-auth0">Why Auth0?</a></p>
<p align="center">
This project is licensed under the Apache 2.0 license. See the <a href="/LICENSE"> LICENSE</a> file for more info.</p>
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
**Zeko Advanced Systems Inc. (Ticker: ZEKO)**
**Forecast for Fiscal Year 2025**

**Executive Summary:**

As we look ahead to fiscal year 2025, we maintain a bearish outlook on Zeko Advanced Systems Inc. (ZEKO). Despite the company's stable performance in recent quarters, several factors suggest that ZEKO may underperform the broader market in the coming year. Our analysis considers the company's financial performance, market dynamics, and strategic positioning, which collectively indicate potential headwinds that could hinder growth and profitability.

**Revenue Growth Challenges:**

While Zeko reported a modest 2.3% increase in revenue for Q3 2024, this growth rate lags behind industry peers and suggests potential challenges in sustaining momentum. The company's reliance on digital health solutions and AI-driven patient monitoring devices, while innovative, may face increased competition from both established players and new entrants. Additionally, economic uncertainties and geopolitical tensions could dampen demand in key emerging markets, particularly in Asia and the Middle East, where Zeko is focusing its expansion efforts.

**Margin Pressures:**

Zeko's gross margin declined slightly to 55% in Q3 2024, primarily due to rising raw material costs and ongoing supply chain disruptions. These pressures are expected to persist into 2025, further compressing margins and impacting profitability. Additionally, the company's significant investment in research and development, while necessary for innovation, may not yield immediate returns, thereby straining operating margins.

**Operational and Strategic Concerns:**

Despite Zeko's commitment to innovation and strategic partnerships, the pace of product development and market adoption may not be sufficient to drive significant revenue growth. The introduction of new AI-driven platforms and minimally invasive surgical technologies, while promising, may face regulatory hurdles and require extensive validation before achieving widespread adoption. Furthermore, the company's expansion into emerging markets presents inherent risks, including currency fluctuations and regulatory challenges.

**Financial Outlook:**

- **Revenue:** We project Zeko's revenue growth to remain subdued, with an estimated increase of 2-3% for fiscal year 2025. This projection reflects the anticipated competitive pressures and macroeconomic uncertainties that could limit market expansion.

- **Net Income:** Net income growth is expected to be modest, with potential headwinds from increased operational costs and margin pressures. We forecast a net income increase of 1-2% year-over-year.

- **Earnings Per Share (EPS):** Given the expected challenges in revenue and net income growth, we anticipate EPS to grow at a similar rate of 1-2%, potentially reaching $1.64 to $1.65 for fiscal year 2025.

- **Gross Margin:** Gross margin is likely to remain under pressure, potentially declining further to 54-55% as cost challenges persist.

**Conclusion:**

In conclusion, while Zeko Advanced Systems Inc. continues to demonstrate resilience and a commitment to innovation, the company faces significant challenges that may impede its ability to outperform the market in fiscal year 2025. Investors should remain cautious and consider these potential headwinds when evaluating ZEKO as an investment opportunity. The company's strategic focus on emerging markets and new product development, while commendable, may not deliver the desired financial performance in the near term. As such, we maintain a bearish outlook on Zeko's prospects for the upcoming fiscal year.

---

**Note:** This document is purely fictional and is generated for the purpose of a mock or example use case. All names, technologies, and concepts mentioned are invented.
Loading
Loading