# OpenAI Agents SDK

TherosAI integrates with the OpenAI Agents SDK via function tool definitions. Add vault payment capabilities — policy-governed, settled on Solana — to any OpenAI-based agent in a few lines.

***

## Installation

```bash
npm install @TherosAI/sdk
pip install therosai
```

No dedicated OpenAI integration package is needed - TherosAI tools are defined as standard function call schemas.

***

## TypeScript

```typescript
import OpenAI from "openai";
import { TherosAI } from "@TherosAI/sdk";

const openai = new OpenAI();
const theros = new TherosAI({ apiKey: process.env.THEROS_API_KEY! });
const wallet = await theros.wallets.get(process.env.THEROS_WALLET_ID!);

// Tool definitions
const tools: OpenAI.Responses.Tool[] = [
  {
    type: "function",
    name: "theros_pay",
    description: "Send a USDC payment from this agent's wallet to a recipient address or domain.",
    parameters: {
      type: "object",
      properties: {
        to: {
          type: "string",
          description: "Recipient Solana address or domain string (e.g. 'api.perplexity.ai')",
        },
        amount: {
          type: "string",
          description: "USDC amount as a decimal string (e.g. '2.50')",
        },
        memo: {
          type: "string",
          description: "Human-readable description of the payment purpose",
        },
      },
      required: ["to", "amount"],
    },
  },
  {
    type: "function",
    name: "theros_balance",
    description: "Get the current USDC balance of this agent's wallet.",
    parameters: { type: "object", properties: {} },
  },
];

// Tool handler
async function handleToolCall(name: string, args: Record<string, string>) {
  switch (name) {
    case "theros_pay": {
      const tx = await wallet.pay({
        to: args.to,
        amount: args.amount,
        currency: "USDC",
        memo: args.memo,
      });
      return {
        status: "confirmed",
        tx_signature: tx.txSignature,
        amount: args.amount,
        recipient: args.to,
      };
    }
    case "theros_balance": {
      const balance = await wallet.balance();
      return { usdc_balance: balance };
    }
    default:
      throw new Error(`Unknown tool: ${name}`);
  }
}

// Agent loop
async function runAgent(userMessage: string) {
  const messages: OpenAI.Responses.MessageParam[] = [
    { role: "user", content: userMessage },
  ];

  while (true) {
    const response = await openai.responses.create({
      model: "gpt-4o",
      input: messages,
      tools,
    });

    if (response.output_type === "message") {
      return response.output_text;
    }

    if (response.output_type === "function_calls") {
      for (const call of response.output) {
        if (call.type === "function_call") {
          const result = await handleToolCall(call.name, JSON.parse(call.arguments));
          messages.push({
            role: "tool",
            tool_call_id: call.call_id,
            content: JSON.stringify(result),
          });
        }
      }
    }
  }
}
```

***

## Python

```python
from openai import OpenAI
import therosai
import json
import os

openai_client = OpenAI()
theros_client = therosai.Client(api_key=os.environ["THEROS_API_KEY"])
wallet = theros_client.wallets.get(os.environ["THEROS_WALLET_ID"])

tools = [
    {
        "type": "function",
        "function": {
            "name": "theros_pay",
            "description": "Send a USDC payment from this agent's wallet.",
            "parameters": {
                "type": "object",
                "properties": {
                    "to": {"type": "string", "description": "Recipient address or domain"},
                    "amount": {"type": "string", "description": "USDC amount"},
                    "memo": {"type": "string", "description": "Payment description"},
                },
                "required": ["to", "amount"],
            },
        },
    },
    {
        "type": "function",
        "function": {
            "name": "theros_balance",
            "description": "Get current USDC balance.",
            "parameters": {"type": "object", "properties": {}},
        },
    },
]


def handle_tool_call(name, args):
    if name == "theros_pay":
        tx = wallet.pay(to=args["to"], amount=args["amount"], currency="USDC", memo=args.get("memo"))
        return {"status": "confirmed", "tx_signature": tx.tx_signature, "amount": args["amount"]}
    elif name == "theros_balance":
        return {"usdc_balance": wallet.balance()}
    raise ValueError(f"Unknown tool: {name}")


def run_agent(user_message: str) -> str:
    messages = [{"role": "user", "content": user_message}]

    while True:
        response = openai_client.chat.completions.create(
            model="gpt-4o",
            messages=messages,
            tools=tools,
        )

        choice = response.choices[0]

        if choice.finish_reason == "stop":
            return choice.message.content

        if choice.finish_reason == "tool_calls":
            messages.append(choice.message)
            for call in choice.message.tool_calls:
                result = handle_tool_call(call.function.name, json.loads(call.function.arguments))
                messages.append({
                    "role": "tool",
                    "tool_call_id": call.id,
                    "content": json.dumps(result),
                })
```

***

## Notes

* The tool handler runs in your infrastructure — TherosAI API calls are made server-side, not by the OpenAI model.
* Always validate the amounts and recipients your model proposes before executing. Add a confirmation step for amounts above your threshold if operating in production.
* Consider setting `requireCoSign` on the vault policy as a secondary safeguard for high-value payments.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.therosai.com/integrations/openai-agents.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
