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:
Sergio Serrano 2025-06-17 18:25:10 -03:00 committed by GitHub
parent bbe8cb3478
commit 6921500e3c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 1851 additions and 0 deletions

View 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
View 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

View 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.

View 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

File diff suppressed because it is too large Load diff

View 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"
}
}

View 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);

View 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();