-
Notifications
You must be signed in to change notification settings - Fork 2.3k
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
Added Outlook integration toolkit #3465
Open
hahahafafa
wants to merge
74
commits into
langchain-ai:main
Choose a base branch
from
hahahafafa:main
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
74 commits
Select commit
Hold shift + click to select a range
12dd2a9
outlook integration
hahahafafa 3388d62
Update outlookIntegration.ts
SimonLi1020 2694daf
Merge pull request #1 from hahahafafa/develop
hahahafafa 884bab7
get message tips integrated
hahahafafa 929f9f8
added some tests and added getToken for getting Access token
oscarchen178 44928c1
move our integration to outlook folder, extract authentication to oth…
oscarchen178 ba52666
add get credentials from env, remove unused package
oscarchen178 106868d
create entrypoints for outlook, create read and send tool extending b…
oscarchen178 3b54b6f
Update index.ts
oscarchen178 5c259c7
reformat the read email
Qi123123Li 3d123c5
now our outlook tools depend on abstract authFlowBase not concrete au…
oscarchen178 df52718
added two authentication flow, make outlook tool construct more simpl…
oscarchen178 5fc9972
change the code to fit standard lint rules
Qi123123Li 43388c7
add test case for send email
Qi123123Li 497e486
fix some small bugs
Qi123123Li e29c32d
Merge branch 'langchain-ai:main' into main
hahahafafa 11d91fc
add invalid token test
oscarchen178 d19b446
Merge branch 'dev2'
hahahafafa 7091118
Update .env.example
SimonLi1020 d48ab61
Merge branch 'main' into main
SimonLi1020 6234417
Merge branch 'main' into main
SimonLi1020 d38f9f6
use typedoc
Qi123123Li 1bc7761
Merge branch 'main' into run-typedoc
Qi123123Li 0ff7f6d
Merge pull request #4 from hahahafafa/run-typedoc
Qi123123Li 12d160f
add http and url in package
Qi123123Li cf52d46
Merge branch 'run-typedoc'
Qi123123Li 7c03901
Merge branch 'main' into main
Qi123123Li 083a8ae
Merge branch 'main' into main
oscarchen178 d70da41
remove optional deps, remove modules using opt depd from index entryp…
oscarchen178 918ad47
Merge branch 'main' into main
oscarchen178 9a6ef37
Merge branch 'main' into main
oscarchen178 43ee152
add to create-entrypoints
oscarchen178 d4bf536
change from openurl to open package
oscarchen178 d21fc40
Merge branch 'main' into main
oscarchen178 960d082
remove url from dependencies
oscarchen178 f4861fe
log the url for manually open instead of using open package
oscarchen178 bdb51ab
Merge branch 'main' into main
oscarchen178 c518e9f
Update langchain/src/tools/outlook/authFlowREST.ts
Qi123123Li 3212a3c
Update langchain/src/tools/outlook/descriptions.ts
Qi123123Li 767acbc
Update langchain/src/tools/outlook/descriptions.ts
Qi123123Li 216c3cc
Update langchain/src/tools/tests/outlookIntegration.test.ts
Qi123123Li c94886e
fix the format
Qi123123Li c3f6c74
add the jsdoc
Qi123123Li 3cec11e
add jsdoc
Qi123123Li 9b1d3f4
change OutlookBase to abstract; remove `state` in rest; apply camel c…
oscarchen178 d92e771
Merge branch 'main' into main
oscarchen178 6ebb241
Merge branch 'main' of https://github.com/hwchase17/langchainjs into …
jacoblee93 da61a07
Merge
jacoblee93 ed41abe
Skip test
jacoblee93 ba2ec31
Merge branch 'main' into main
oscarchen178 d9ca68d
Merge branch 'main' into main
oscarchen178 04a7221
Merge branch 'main' into main
oscarchen178 23271fd
Merge branch 'main' of https://github.com/hwchase17/langchainjs into …
jacoblee93 562df12
Move/rename files around
jacoblee93 a9ba549
add a docs page for outlook toolkit
oscarchen178 7fa8d85
Update outlook.mdx
jacoblee93 c2a9eba
Update outlook.mdx
oscarchen178 c7eb5c6
Update outlook.mdx
oscarchen178 6718669
add getRefreshToken for AuthFlowREST
oscarchen178 4cbdeb9
Merge branch 'main' into main
Qi123123Li b300654
Merge branch 'main' into main
oscarchen178 1fb53e0
move getAuth from outlook tool to authFLow
oscarchen178 4719a52
format
oscarchen178 cdde1d4
update docs
oscarchen178 ab49c28
Merge branch 'main' into main
oscarchen178 175324c
Merge branch 'main' into main
oscarchen178 8751341
Merge branch 'main' into main
oscarchen178 42189f8
format outlook.mdx
oscarchen178 f94225a
Merge branch 'main' into main
oscarchen178 d1e961e
putting example in the examples/
oscarchen178 569b34e
Update outlook.mdx
oscarchen178 981242e
Update outlook.ts
oscarchen178 1aa5ee3
Merge remote-tracking branch 'upstream/main'
oscarchen178 d03bd77
Merge branch 'main' into main
oscarchen178 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
import CodeBlock from "@theme/CodeBlock"; | ||
|
||
# Outlook Toolkit | ||
|
||
## Overview | ||
|
||
Using this toolkit, you can integrate Microsoft Graph API functionalities into | ||
your applications to manage email interactions. | ||
|
||
## Learn Microsoft Graph | ||
|
||
Microsoft Graph is a RESTful web API that enables you to access Microsoft | ||
Cloud service resources. With Microsoft Graph, you can integrate various | ||
Microsoft services and data, including users' emails, calendar, contacts, | ||
and more, into your applications. | ||
|
||
After you register your app and get authentication tokens for a user or service, | ||
you can make requests to the Microsoft Graph API. | ||
|
||
How to get authentication tokens for a user: | ||
https://learn.microsoft.com/en-us/graph/auth-v2-user | ||
|
||
## Set up | ||
|
||
An `accessToken` is needed to use the Outlook Toolkit. | ||
|
||
You need to first register an application in Azure Portal to obtain | ||
necessary credentials. | ||
|
||
### App register | ||
|
||
1. Register an Application: | ||
|
||
- Go to Azure Portal. | ||
- Navigate to Azure Active Directory -> App registrations. | ||
- Register a new application, note down the Client ID. | ||
|
||
2. Generate Client Secret: | ||
|
||
- In the application settings, go to Certificates & Secrets. | ||
- Create a new client secret and note down the Client Secret. | ||
|
||
3. Configure Redirect URI: | ||
|
||
- In the application settings, go to Authentication. | ||
- Add a Redirect URI and note down the Redirect URI. | ||
|
||
4. Permissions and Admin Consent: | ||
- In API permissions, grant necessary permissions for Microsoft Graph API or | ||
Outlook API. | ||
- Grant admin consent for the added permissions. | ||
|
||
At this point, you should have these three credentials: | ||
clientId, clientSecret, redirectUri | ||
|
||
Set them as environment variables: | ||
|
||
```env | ||
OUTLOOK_CLIENT_ID=your_client_id | ||
OUTLOOK_CLIENT_SECRET=your_client_secret | ||
OUTLOOK_REDIRECT_URI=your_redirect_uri | ||
``` | ||
|
||
**Keep these values secure and avoid exposing them in public repositories.** | ||
|
||
The following link from Microsoft is a good reference for the above steps: | ||
https://learn.microsoft.com/en-us/graph/auth-v2-user | ||
|
||
This video may also be helpful: | ||
https://www.youtube.com/watch?v=NAtiNpwnivI&t=309s | ||
|
||
### Get an accessToken | ||
|
||
Now you are able to use the above credentials to get an `accessToken`. | ||
|
||
The `AuthFlowREST` class implements the OAuth 2.0 authorization code flow. | ||
You can use the `getAccessToken()` which will open a temporary server on | ||
your `redirectUri` and you need to manually open the printed link to login | ||
on behalf of the user. For every `AuthFlowREST` instance, you only need to | ||
login once. The next time you can run the `getAccessToken()` method, it will | ||
make use of the `refreshToken` obtained together with the first `accessToken` | ||
to get a new `accessToken` without the need of the server and login. | ||
|
||
Having the above credentials, you can either pass them to the constructor | ||
or put them in the environment. | ||
|
||
```typescript | ||
import { AuthFlowREST } from "@langchain/community/tools/outlook"; | ||
|
||
const authFlow = new AuthFlowREST(); | ||
const authFlow = new AuthFlowREST(clientId, clientSecret, redirectUri); | ||
// Get accessToken | ||
const accessToken = await authFlow.getAccessToken(); | ||
// After the above line, you can get the refreshToken | ||
const refreshToken = authFlow.getRefreshToken(); | ||
// Get accessToken again without login | ||
const accessToken = await authFlow.getAccessToken(); | ||
``` | ||
|
||
Now you can set the `accessToken` and `refreshToken` as environment variable: | ||
|
||
```env | ||
OUTLOOK_ACCESS_TOKEN=your_access_token | ||
OUTLOOK_REFRESH_TOKEN=your_refresh_token | ||
``` | ||
|
||
### Provide accessToken to Outlook Toolkit | ||
|
||
The Outlook Toolkit needs `AuthFlowBase` abstarct class to provide accessToken. | ||
|
||
```typescript | ||
const authFlow = new AuthFlowREST(); | ||
const outlookReadMail = new OutlookReadMailTool(authFlow); | ||
// or simply this when you have the credentials in .env | ||
const outlookReadMail = new OutlookReadMailTool(undefined, "rest"); | ||
``` | ||
|
||
### Other classes to provide accessToken | ||
|
||
If you only have a valid `accessToken` in your env, you can use `AuthFlowToken`: | ||
|
||
```typescript | ||
const authFlow = new AuthFlowToken(accessToken); | ||
// if you have accessToken stored in .env | ||
const authFlow = new AuthFlowToken(); | ||
const outlookReadMail = new OutlookReadMailTool(authFlow); | ||
// or simply this when you have accessToken in .env | ||
const outlookReadMail = new OutlookReadMailTool(undefined, "token"); | ||
``` | ||
|
||
Usually when you obtain a accessToken you also get a refreshToken | ||
used to refresh expired accessToken. The `AuthFlowRefresh` class needs | ||
the following credentials: `clientId`, `clientSecret`, `redirectUri` | ||
and `refreshToken`. In this way you won't need to login, no server | ||
will be open. | ||
|
||
```typescript | ||
const authFlow = new AuthFlowRefresh(); | ||
const outlookReadMail = new OutlookReadMailTool(authFlow); | ||
// or simply this when you have the credentials in .env | ||
const outlookReadMail = new OutlookReadMailTool(undefined, "refresh"); | ||
``` | ||
|
||
### Customize your own authentication flow | ||
|
||
Inherit from `AuthFlowBase` and implement the `getAccessToken()` method. | ||
|
||
## Usage | ||
|
||
These two examples show how to readand send emails by using agent. | ||
|
||
import ToolExample from "@examples/tools/outlook.ts"; | ||
|
||
<CodeBlock language="typescript">{ToolExample}</CodeBlock> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
import { | ||
OutlookReadMailTool, | ||
OutlookSendMailTool, | ||
} from "@langchain/community/tools/outlook"; | ||
import { ChatOpenAI } from "@langchain/openai"; | ||
import type { ChatPromptTemplate } from "@langchain/core/prompts"; | ||
import { pull } from "langchain/hub"; | ||
import { AgentExecutor, createOpenAIFunctionsAgent } from "langchain/agents"; | ||
|
||
async function AgentRead() { | ||
const llm = new ChatOpenAI({ | ||
modelName: "gpt-3.5-turbo-1106", | ||
}); | ||
|
||
const outlookReadMail = new OutlookReadMailTool(undefined, "token"); | ||
const tools = [outlookReadMail]; | ||
const prompt = await pull<ChatPromptTemplate>( | ||
"hwchase17/openai-functions-agent" | ||
); | ||
|
||
const agent = await createOpenAIFunctionsAgent({ | ||
llm, | ||
tools, | ||
prompt, | ||
}); | ||
|
||
const agentExecutor = new AgentExecutor({ | ||
agent, | ||
tools, | ||
}); | ||
|
||
const input = "show my emails"; | ||
const result = await agentExecutor.invoke({ input }); | ||
|
||
console.log(result); | ||
} | ||
|
||
AgentRead(); | ||
|
||
async function AgentSend() { | ||
const llm = new ChatOpenAI({ | ||
modelName: "gpt-4", | ||
}); | ||
|
||
const sendMailTool = new OutlookSendMailTool(undefined, "token"); | ||
const tools = [sendMailTool]; | ||
const prompt = await pull<ChatPromptTemplate>( | ||
"hwchase17/openai-functions-agent" | ||
); | ||
|
||
const agent = await createOpenAIFunctionsAgent({ | ||
llm, | ||
tools, | ||
prompt, | ||
}); | ||
const agentExecutor = new AgentExecutor({ | ||
agent, | ||
tools, | ||
}); | ||
|
||
const input = | ||
"send an email to YOUR_EMAIL and invite him to a meeting at 3pm tomorrow"; | ||
const result = await agentExecutor.invoke({ input }); | ||
|
||
console.log(result); | ||
} | ||
|
||
AgentSend(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
/** | ||
* Base class for handling authentication flows. | ||
* | ||
* @class AuthFlowBase | ||
*/ | ||
export abstract class AuthFlowBase { | ||
/** | ||
* The client ID used for authentication. | ||
* | ||
* @protected | ||
* @type {string} | ||
* @memberof AuthFlowBase | ||
*/ | ||
protected clientId: string; | ||
|
||
/** | ||
* The access token obtained through authentication. | ||
* | ||
* @protected | ||
* @type {string} | ||
* @memberof AuthFlowBase | ||
*/ | ||
protected accessToken = ""; | ||
|
||
/** | ||
* Creates an instance of AuthFlowBase. | ||
* | ||
* @param {string} clientId - The client ID for authentication. | ||
* @memberof AuthFlowBase | ||
*/ | ||
constructor(clientId: string) { | ||
this.clientId = clientId; | ||
} | ||
|
||
/** | ||
* Abstract method to get the access token. | ||
* | ||
* @abstract | ||
* @returns {Promise<string>} A promise that resolves to the access token. | ||
* @memberof AuthFlowBase | ||
*/ | ||
public abstract getAccessToken(): Promise<string>; | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
So someone needs to run this script beforehand?
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.
Yes, if he doesn't have the tokens.