Add OpenAI Agents example (#447)
Add a TypeScript example showing how to integrate OpenAI Agents with Arcade AI, including basic usage and manual authorization flow.
This commit is contained in:
parent
bbe8cb3478
commit
6921500e3c
8 changed files with 1851 additions and 0 deletions
2
examples/openai-agents-ts/.env.example
Normal file
2
examples/openai-agents-ts/.env.example
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
OPENAI_API_KEY=sk-proj-1234567890
|
||||
ARCADE_API_KEY=arc_1234567890
|
||||
42
examples/openai-agents-ts/.gitignore
vendored
Normal file
42
examples/openai-agents-ts/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
# Dependencies
|
||||
node_modules/
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# Environment variables
|
||||
.env
|
||||
.env.local
|
||||
.env.*.local
|
||||
|
||||
# Build output
|
||||
dist/
|
||||
build/
|
||||
out/
|
||||
|
||||
# IDE and editor files
|
||||
.idea/
|
||||
.vscode/
|
||||
*.swp
|
||||
*.swo
|
||||
.DS_Store
|
||||
|
||||
# Logs
|
||||
logs/
|
||||
*.log
|
||||
|
||||
# Testing
|
||||
coverage/
|
||||
|
||||
# Temporary files
|
||||
tmp/
|
||||
temp/
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
.eslintcache
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
21
examples/openai-agents-ts/LICENSE
Normal file
21
examples/openai-agents-ts/LICENSE
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2025, Arcade AI
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
158
examples/openai-agents-ts/README.md
Normal file
158
examples/openai-agents-ts/README.md
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
<h3 align="center">
|
||||
<a name="readme-top"></a>
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/ArcadeAI/.github/refs/heads/main/profile/assets/new_arcade_logo_white.svg" width="300">
|
||||
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/ArcadeAI/.github/refs/heads/main/profile/assets/new_arcade_logo_black.svg" width="300">
|
||||
<img alt="Arcade AI Logo" src="https://raw.githubusercontent.com/ArcadeAI/.github/refs/heads/main/profile/assets/new_arcade_logo_black.svg" width="300" >
|
||||
</picture>
|
||||
</h3>
|
||||
<div align="center">
|
||||
<h3>OpenAI Agents + Arcade AI Example</h3>
|
||||
<a href="https://github.com/your-organization/openai-ts/blob/main/LICENSE">
|
||||
<img src="https://img.shields.io/badge/License-ISC-blue.svg" alt="License">
|
||||
</a>
|
||||
<p align="center">
|
||||
<a href="https://docs.arcade.dev" target="_blank">Arcade Documentation</a> •
|
||||
<a href="https://docs.arcade.dev/toolkits" target="_blank">Integrations</a> •
|
||||
<a href="https://github.com/ArcadeAI/arcade-js" target="_blank">Arcade JS Client</a> •
|
||||
<a href="https://platform.openai.com/docs/assistants/tools" target="_blank">OpenAI Agents</a>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
# OpenAI Agents + Arcade AI
|
||||
|
||||
This TypeScript project demonstrates how to integrate [Arcade AI](https://docs.arcade.dev) with [OpenAI Agents](https://openai.github.io/openai-agents-js/) to create powerful AI agents that can interact with external services. Arcade provides access to a wide range of tools including Gmail, Slack, LinkedIn, and more through its Google toolkit and other integrations.
|
||||
|
||||
The project showcases two approaches:
|
||||
|
||||
- **Basic integration** (`src/index.ts`): Simple one-time execution with Google toolkit
|
||||
- **Authorization handling** (`src/waitForCompletion.ts`): Manual authorization flow management
|
||||
|
||||
For a list of all hosted tools and auth providers, see the [Arcade Integrations](https://docs.arcade.dev/toolkits) documentation.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- [Node.js](https://nodejs.org/en/download/) (v18.20.8 or higher)
|
||||
- [npm](https://www.npmjs.com/) or [pnpm](https://pnpm.io/installation)
|
||||
- [OpenAI API key](https://platform.openai.com/account/api-keys)
|
||||
- [Arcade API key](https://docs.arcade.dev/home/api-keys)
|
||||
|
||||
## Installation
|
||||
|
||||
1. Clone the repository and install dependencies:
|
||||
|
||||
```bash
|
||||
npm install
|
||||
```
|
||||
|
||||
2. Set up environment variables:
|
||||
- Create a `.env` file in the root directory
|
||||
- Add your API keys:
|
||||
|
||||
```
|
||||
OPENAI_API_KEY=your_openai_api_key
|
||||
ARCADE_API_KEY=your_arcade_api_key
|
||||
```
|
||||
|
||||
3. Update the user ID placeholder:
|
||||
- In both `src/index.ts` and `src/waitForCompletion.ts`
|
||||
- Replace `<YOUR_SYSTEM_USER_ID>` with your application's user identifier (e.g., email address, UUID, etc.)
|
||||
|
||||
## Basic Usage
|
||||
|
||||
This example creates an AI agent that can read and process your Gmail emails using Arcade's Google toolkit.
|
||||
|
||||
### Simple Execution
|
||||
|
||||
Run the basic example:
|
||||
|
||||
```bash
|
||||
npm run dev
|
||||
```
|
||||
|
||||
This script will:
|
||||
|
||||
1. Initialize the Arcade client
|
||||
2. Fetch available Google toolkit tools (up to 30)
|
||||
3. Convert them to OpenAI Agents compatible format
|
||||
4. Create an agent that can assist with Google API calls
|
||||
5. Ask "What are my latest emails?" and display the result
|
||||
|
||||
### Authorization Flow Example
|
||||
|
||||
For a more robust implementation that handles authorization flows:
|
||||
|
||||
```bash
|
||||
npm run dev:waitForCompletion
|
||||
```
|
||||
|
||||
This version includes:
|
||||
|
||||
- Automatic authorization detection and handling
|
||||
- Browser-based OAuth flow initiation
|
||||
- Waiting for authorization completion
|
||||
- Automatic retry after successful authorization
|
||||
|
||||
If you haven't authorized Arcade with Google yet, you'll see a message like:
|
||||
|
||||
```bash
|
||||
Please complete the authorization challenge in your browser: https://accounts.google.com/o/oauth2/v2/auth?access_type=offline&client_id=...
|
||||
```
|
||||
|
||||
Visit the provided URL to authorize Arcade with your Google account. The script will automatically detect when authorization is complete and continue execution.
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
openai-ts/
|
||||
├── src/
|
||||
│ ├── index.ts # Basic OpenAI Agents + Arcade integration
|
||||
│ └── waitForCompletion.ts # Manual authorization flow management
|
||||
├── package.json # Dependencies and scripts
|
||||
└── README.md # This file
|
||||
```
|
||||
|
||||
## Available Toolkits
|
||||
|
||||
You can modify the `toolkit` parameter to access different integrations:
|
||||
|
||||
- `"google"` - Gmail, Google Calendar, Google Drive, Google Docs
|
||||
- `"slack"` - Slack messaging and channels
|
||||
- `"github"` - GitHub repositories and issues
|
||||
- `"linkedin"` - LinkedIn posts and connections
|
||||
- And more in [Arcade Integrations](https://docs.arcade.dev/toolkits) documentation
|
||||
|
||||
## Development
|
||||
|
||||
To extend or modify the functionality:
|
||||
|
||||
1. **Change the toolkit**: Update the `toolkit` parameter in the `client.tools.list()` call
|
||||
2. **Modify the query**: Change the question asked to the agent in the `run()` function
|
||||
3. **Add custom instructions**: Update the agent's `instructions` parameter for different behaviors
|
||||
4. **Handle different models**: Switch the `model` parameter to use different OpenAI models
|
||||
|
||||
Example customization:
|
||||
|
||||
```typescript
|
||||
const slackToolkit = await client.tools.list({ toolkit: "slack", limit: 30 });
|
||||
// ... rest of setup
|
||||
|
||||
const slackAgent = new Agent({
|
||||
name: "Slack agent",
|
||||
instructions: "You are a helpful assistant for managing Slack communications.",
|
||||
model: "gpt-4o",
|
||||
tools
|
||||
});
|
||||
|
||||
const result = await run(slackAgent, "Send a message to the #general channel");
|
||||
```
|
||||
|
||||
## Security Best Practices
|
||||
|
||||
- Never commit your `.env` file to version control
|
||||
- Keep your API keys secure and rotate them regularly
|
||||
- Use appropriate user identification in production
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the MIT License - see the LICENSE file for details.
|
||||
1511
examples/openai-agents-ts/package-lock.json
generated
Normal file
1511
examples/openai-agents-ts/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
17
examples/openai-agents-ts/package.json
Normal file
17
examples/openai-agents-ts/package.json
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"name": "openai-ts",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"license": "ISC",
|
||||
"author": "",
|
||||
"type": "module",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"dev": "npx tsx --env-file=.env src/index.ts",
|
||||
"dev:waitForCompletion": "npx tsx --env-file=.env src/waitForCompletion.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"@arcadeai/arcadejs": "1.7.0",
|
||||
"@openai/agents": "^0.0.8"
|
||||
}
|
||||
}
|
||||
40
examples/openai-agents-ts/src/index.ts
Normal file
40
examples/openai-agents-ts/src/index.ts
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
import Arcade from '@arcadeai/arcadejs';
|
||||
import { executeOrAuthorizeZodTool, toZod } from "@arcadeai/arcadejs/lib";
|
||||
import { Agent, run, tool } from '@openai/agents';
|
||||
|
||||
// 1) Initialize Arcade client
|
||||
const client = new Arcade();
|
||||
|
||||
// 2) Fetch Google toolkit from Arcade and prepare tools for OpenAI Agents
|
||||
const googleToolkit = await client.tools.list({ toolkit: "google", limit: 30 });
|
||||
const arcadeTools = toZod({
|
||||
tools: googleToolkit.items,
|
||||
client,
|
||||
userId: "<YOUR_SYSTEM_USER_ID>", // Replace this with your application's user ID (e.g. email address, UUID, etc.)
|
||||
executeFactory: executeOrAuthorizeZodTool,
|
||||
})
|
||||
|
||||
// 3) Convert the tools to a format that OpenAI Agents can use
|
||||
const tools = arcadeTools.map(({ name, description, execute, parameters }) =>
|
||||
tool({
|
||||
name,
|
||||
description: description ?? "",
|
||||
parameters: parameters as any,
|
||||
execute,
|
||||
strict: true,
|
||||
}),
|
||||
);
|
||||
|
||||
// 4) Create a new agent with the Google toolkit
|
||||
const googleAgent = new Agent({
|
||||
name: "Google agent",
|
||||
instructions: "You are a helpful assistant that can assist with Google API calls.",
|
||||
model: "gpt-4o-mini",
|
||||
tools
|
||||
});
|
||||
|
||||
// 5) Run the agent
|
||||
const result = await run(googleAgent, "What are my latest emails?");
|
||||
|
||||
// 6) Print the result
|
||||
console.log(result.finalOutput);
|
||||
60
examples/openai-agents-ts/src/waitForCompletion.ts
Normal file
60
examples/openai-agents-ts/src/waitForCompletion.ts
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
import Arcade from '@arcadeai/arcadejs';
|
||||
import { isAuthorizationRequiredError, toZod } from "@arcadeai/arcadejs/lib";
|
||||
import { Agent, run, tool } from '@openai/agents';
|
||||
|
||||
async function main() {
|
||||
// 1) Initialize Arcade client
|
||||
const client = new Arcade();
|
||||
|
||||
// 2) Fetch Google toolkit from Arcade and prepare tools for OpenAI Agents
|
||||
const googleToolkit = await client.tools.list({ toolkit: "google", limit: 30 });
|
||||
const arcadeTools = toZod({
|
||||
tools: googleToolkit.items,
|
||||
client,
|
||||
userId: "<YOUR_SYSTEM_USER_ID_2>", // Replace this with your application's user ID (e.g. email address, UUID, etc.)
|
||||
})
|
||||
|
||||
// 3) Convert the tools to a format that OpenAI Agents can use
|
||||
const tools = arcadeTools.map(({ name, description, execute, parameters }) =>
|
||||
tool({
|
||||
name,
|
||||
description: description ?? "",
|
||||
parameters: parameters as any,
|
||||
execute,
|
||||
errorFunction: (_, error) => { throw error }
|
||||
}),
|
||||
);
|
||||
|
||||
// 4) Create a new agent with the Google toolkit
|
||||
const googleAgent = new Agent({
|
||||
name: "Google agent",
|
||||
instructions: "You are a helpful assistant that can assist with Google API calls.",
|
||||
model: "gpt-4o-mini",
|
||||
tools
|
||||
});
|
||||
|
||||
// 5) Run the agent, if authorization is required, wait for it to complete and retry
|
||||
while (true) {
|
||||
try {
|
||||
const result = await run(googleAgent, "What are my latest emails?");
|
||||
console.log(result.finalOutput);
|
||||
break; // Exit the loop if the result is successful
|
||||
} catch (error) {
|
||||
if (error instanceof Error && isAuthorizationRequiredError(error)) {
|
||||
const response = await client.tools.authorize({
|
||||
tool_name: "Google_ListEmails",
|
||||
user_id: "<YOUR_SYSTEM_USER_ID_2>",
|
||||
});
|
||||
if (response.status !== "completed") {
|
||||
console.log(`Please complete the authorization challenge in your browser: ${response.url}`);
|
||||
}
|
||||
|
||||
// Wait for the authorization to complete
|
||||
await client.auth.waitForCompletion(response);
|
||||
console.log("Authorization completed, retrying...");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
Loading…
Reference in a new issue