Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,18 @@ description: "Learn how to use Arcade tools in OpenAI Agents applications"

import { Steps, Tabs, Callout } from "nextra/components";

<!-- Editorial: Voice and Tone - Changed "Learn how to" to direct statement; Structure - Added intro sentence -->

# Setup Arcade with OpenAI Agents SDK

The [OpenAI Agents SDK](https://openai.github.io/openai-agents-python/) is a popular Python library for building AI agents. It builds on top of the OpenAI API, and provides an interface for building agents.
Integrate Arcade tools into OpenAI Agents applications to build CLI agents that handle tool authorization automatically.

The [OpenAI Agents SDK](https://openai.github.io/openai-agents-python/) is a Python library for building AI agents. It builds on top of the OpenAI API, and provides an interface for building agents. You'll implement a CLI agent that can use Arcade tools to help users with their requests. The harness handles tools that require authorization automatically, so users don't need to worry about it.

<GuideOverview>
<GuideOverview.Outcomes>

Learn how to integrate Arcade tools using OpenAI Agents primitives. You will implement a CLI agent that can user Arcade tools to help the user with their requests. The harness handles tools that require authorization automatically, so users don't need to worry about it.
Integrate Arcade tools using OpenAI Agents primitives. You will implement a CLI agent that can use Arcade tools to help the user with their requests. The harness handles tools that require authorization automatically, so users don't need to worry about it.

</GuideOverview.Outcomes>

Expand Down Expand Up @@ -89,7 +93,7 @@ import asyncio
import json
```

This includes several imports, here's a breakdown:
This includes multiple imports, here's a breakdown:

- Arcade imports:
- `AsyncArcade`: The Arcade client, used to interact with the Arcade API.
Expand All @@ -111,7 +115,7 @@ This includes several imports, here's a breakdown:

### Configure the agent

These variables are used in the rest of the code to customize the agent and manage the tools. Feel free to configure them to your liking.
Tools, MCP servers, prompts, and models configure the agent and determine which tools you can use. Configure them to your liking.

```python filename="main.py"
# Load environment variables
Expand All @@ -133,7 +137,7 @@ MODEL = "gpt-4o-mini"

### Write a custom error and utility functions to help with tool calls

Here, you define `ToolError` to handle errors from the Arcade tools. It wraps the `AgentsException` and provides an informative error message that can be handled in the agentic loop in case anything goes wrong.
Here, you define `ToolError` to handle errors from the Arcade tools. It wraps the `AgentsException` and provides an informative error message that the agentic loop can handle in case anything goes wrong.

You also define `convert_output_to_json` to convert the output of the Arcade tools to a JSON string. This is useful because the output of the Arcade tools is not always a JSON object, and the OpenAI Agents SDK expects a JSON string.

Expand Down Expand Up @@ -164,7 +168,7 @@ def convert_output_to_json(output: Any) -> str:

### Write a helper function to authorize Arcade tools

This helper function is how you implement "just in time" (JIT) tool authorization using Arcade's client. When the agent tries to execute a tool that requires authorization, the `result` object's `status` will be `"pending"`, and you can use the `authorize` method to get an authorization URL. You then wait for the user to complete the authorization and retry the tool call. If the user has already authorized the tool, the `status` will be `"completed"`, and the OAuth dance is skipped silently, which improves the user experience.
This helper function implements "just in time" (JIT) tool authorization using Arcade's client. When the agent tries to execute a tool that requires authorization, the `result` object's `status` will be `"pending"`, and you can use the `authorize` method to get an authorization URL. You then wait for the user to complete the authorization and retry the tool call. If the user has already authorized the tool, the `status` will be `"completed"`, and the OAuth dance skips silently, which improves the user experience.

<Callout type="info">
This function captures the authorization flow outside of the agent's context,
Expand Down Expand Up @@ -192,7 +196,7 @@ async def authorize_tool(client: AsyncArcade, context: RunContextWrapper, tool_n

### Write a helper function to execute Arcade tools

This helper function is how the OpenAI Agents framework invokes the Arcade tools. It handles the authorization flow, and then calls the tool using the `execute` method. It handles the conversion of the arguments from JSON to a dictionary (expected by Arcade) and the conversion of the output from the Arcade tool to a JSON string (expected by the OpenAI Agents framework). Here is where you call the helper functions defined earlier to authorize the tool and convert the output to a JSON string.
This helper function shows how the OpenAI Agents framework invokes the Arcade tools. It handles the authorization flow, and then calls the tool using the `execute` method. It handles the conversion of the arguments from JSON to a dictionary (expected by Arcade) and the conversion of the output from the Arcade tool to a JSON string (expected by the OpenAI Agents framework). Here is where you call the helper functions defined earlier to authorize the tool and convert the output to a JSON string.

```python filename="main.py"
async def invoke_arcade_tool(
Expand All @@ -218,9 +222,9 @@ async def invoke_arcade_tool(
return convert_output_to_json(result.output.value)
```

### Retrieve Arcade tools and transform them into LangChain tools
### Retrieve Arcade tools and transform them into OpenAI Agents tools

Here you get the Arcade tools you want the agent to use, and transform them into OpenAI Agents tools. The first step is to initialize the Arcade client, and get the tools you want to use. Since OpenAI is itself an inference provider, the Arcade API provides a convenient endpoint to get the tools in the OpenAI format, which is also the format expected by the OpenAI Agents framework.
Here you get the Arcade tools you want the agent to use, and transform them into OpenAI Agents tools. The first step is to initialize the Arcade client, and get the tools you want. Since OpenAI is itself an inference provider, the Arcade API provides a convenient endpoint to get the tools in the OpenAI format, which is also the format expected by the OpenAI Agents framework.

This helper function is long, here's a breakdown of what it does for clarity:

Expand All @@ -244,7 +248,7 @@ async def get_arcade_tools(
raise ValueError(
"No tools or MCP servers provided to retrieve tool definitions")

# Use the Arcade Client to get OpenAI-formatted tool definitions
# The Arcade Client allows you to get OpenAI-formatted tool definitions
tool_formats = []

# Retrieve individual tools if specified
Expand Down Expand Up @@ -296,14 +300,14 @@ async def get_arcade_tools(

The main function is where you:

- Get the tools from the configured MCP Servers
- Get the tools from the configured MCP servers
- Create an agent with the configured tools
- Initialize the conversation
- Run the loop

The loop is a while loop that captures the user input, appends it to the conversation history, and then runs the agent. The agent's response is then appended to the conversation history, and the loop continues.

The loop is interrupted when the agent's response contains a tool call, and the tool call is handled by the helper function you wrote earlier.
The loop continues when the agent's response contains a tool call, and the helper function you wrote earlier handles the tool call.

```python filename="main.py"
async def main():
Expand Down Expand Up @@ -360,16 +364,18 @@ You should see the agent responding to your prompts like any model, as well as h

## Key takeaways

- Arcade tools can be integrated into any agentic framework like OpenAI Agents, all you need is to transform the Arcade tools into OpenAI Agents tools and handle the authorization flow.
- You can integrate Arcade tools into any agentic framework like OpenAI Agents, all you need is to transform the Arcade tools into OpenAI Agents tools and handle the authorization flow.
- Context isolation: By handling the authorization flow outside of the agent's context, you remove the risk of the LLM replacing the authorization URL or leaking it, and you keep the context free from any authorization-related traces, which reduces the risk of hallucinations.

## Next Steps
## Next steps

1. Try adding additional tools to the agent or modifying the tools in the catalog for a different use case by modifying the `MCP_SERVERS` and `TOOLS` variables.
2. Try implementing a fully deterministic flow before the agentic loop, use this deterministic phase to prepare the context for the agent, adding things like the current date, time, or any other information that is relevant to the task at hand.

## Example code

The following example shows you how you can integrate Arcade tools into an OpenAI Agents agent:

```python filename="main.py"
from agents import Agent, Runner, TResponseInputItem
from agents.run_context import RunContextWrapper
Expand Down Expand Up @@ -473,7 +479,7 @@ async def get_arcade_tools(
raise ValueError(
"No tools or MCP servers provided to retrieve tool definitions")

# Use the Arcade Client to get OpenAI-formatted tool definitions
# The Arcade Client allows you to get OpenAI-formatted tool definitions
tool_formats = []

# Retrieve individual tools if specified
Expand Down Expand Up @@ -556,5 +562,4 @@ async def main():

# Run the main function as the entry point of the script
if __name__ == "__main__":
asyncio.run(main())
```
asyncio.run(main())