09/26/2025 | Press release | Distributed by Public on 09/26/2025 09:56
The last thing you should do is trust a LLM (Large Language Model) with a secret key and a prompt to "keep it secret, keep it safe." When we code AI agents, we need to shield secrets from the LLM that powers the agent. Instead, we give the agent access to tools that execute operations using the secret. For example, we can give the AI permission to execute a function that sends crypto tokens.
Circle Research introduces OOAK: an Object-Oriented Agent Kit. It lets you build agent tools that can access agent state (such as wallets). OOAK is a simple extension of OpenAI Agents SDK that will integrate with your existing agent code. You can even handoff tasks between your existing static function agents and OOAK agents.
Surprisingly, existing SDKs like OpenAI Agents SDK limit agents to using static functions. This means the tools cannot access the agent's state to get the wallet (or any other resource). Instead, the SDKs give agents access to a single global object that holds the state needed for all agents.
The typical work around is to make the Web3 wallet the single global object. This is very convenient until you add a second agent that needs access to a different wallet (possibly from a different framework) and a third agent that uses its credentials to access your customer database. The developer ends up needing a global container object to hold all these states.
The single global object model does not scale well in complex systems. Every agent has access to every other agent's objects. There is a possibility of namespace overlap - especially as agents designed for one system are added to another.
The only other option for giving agents access to a stateful object is to run a MCP server in a separate process. The MCP server stores state and the agent connects to the MCP server as a tool. Communication between the agent and the MCP happens either over HTTP or through the filesystem. This is an inefficient way to build a simple agent that uses local secrets.
We built an extension to OpenAI Agents SDK that allows agents to use instance methods as tools.
We introduce a new decorator called @agent_tool that works with instance methods. It detects self as part of the function signature. At load time, the decorator removes the 'self' and replaces it with an instance argument. The OOAK InstanceAgent initializer binds all @agent_tools to itself.
We can now build a WalletAgent as a subclass of the InstanceAgent. OOAK ensures that the @agent_tools call the right object.
class WalletInstanceAgent(InstanceAgent): def __init__(self, model: OpenAIChatCompletionsModel, wallet: Wallet: self.wallet = wallet agent_tools = [self.send_usdc] super().__init__(name="Wallet Agent", instructions="I send USDC on the blockchain", model=model, tools=None, agent_tools=agent_tools) @agent_tool defsend_usdc(self, receiver: str, amount: int): returnself.wallet.send_usdc(receiver, amount)
The WalletInstanceAgent initializes itself with its method send_usdc, which is marked with the @agent_tool decorator. Any instance of the wallet agent can then send USDC using its wallet. There can be multiple WalletInstanceAgents running, each with its own wallet. Other agents know nothing about these wallets and manage their own state.
We invite you to try our object oriented @agent_tool extension to the OpenAI Agents SDK on our github.
In our next post we will address how OOAK helps developers manage agent workflows.
Note: This article describes technology developed by Circle Research, a division of Circle committed to public good and open-source contributions to push the boundaries of technology used in crypto, blockchain, and Web3. These projects do not represent completed and released software or services. Unless otherwise stated, content published by Circle Research is open-source and is available for anyone to consume, use, and build upon. Due to their experimental and emergent nature, Circle Research innovations are provided to be tested and evaluated at a developer's or company's discretion.