PineRouterDocs
GuidesModelsAPI referenceApps
SDKs and frameworks

OpenAI Agents SDK

Run OpenAI Agents SDK agents in Python and TypeScript on this API.

The OpenAI Agents SDK takes your own OpenAI client. Give it a client pointed at https://pinerouter.ai/v1, use the Chat Completions API, and turn off tracing (traces go to OpenAI and need an OpenAI key).

Install

pip install openai-agents
uv add openai-agents
npm install @openai/agents openai zod
pnpm add @openai/agents openai zod
bun add @openai/agents openai zod

Configure API keys

.env
API_KEY=sk-...

Load it into the environment before you run the code (for example with python-dotenv, or node --env-file=.env). Keep the key out of your code.

Run

Text

import os
from agents import Agent, AsyncOpenAI, OpenAIChatCompletionsModel, Runner, set_tracing_disabled

set_tracing_disabled(disabled=True)

client = AsyncOpenAI(base_url="https://pinerouter.ai/v1", api_key=os.environ["API_KEY"])
model = OpenAIChatCompletionsModel(model="gpt-6-luna", openai_client=client)

agent = Agent(name="Assistant", instructions="You are concise.", model=model)
result = Runner.run_sync(agent, "Name three rivers in Europe.")
print(result.final_output)
import OpenAI from "openai";
import { Agent, run, setDefaultOpenAIClient, setOpenAIAPI, setTracingDisabled } from "@openai/agents";

setDefaultOpenAIClient(new OpenAI({ baseURL: "https://pinerouter.ai/v1", apiKey: process.env.API_KEY }));
setOpenAIAPI("chat_completions");
setTracingDisabled(true);

const agent = new Agent({ name: "Assistant", instructions: "You are concise.", model: "gpt-6-luna" });
const result = await run(agent, "Name three rivers in Europe.");
console.log(result.finalOutput);

Stream

import asyncio
from openai.types.responses import ResponseTextDeltaEvent

async def main():
    result = Runner.run_streamed(agent, "Write a haiku about rivers.")
    async for event in result.stream_events():
        if event.type == "raw_response_event" and isinstance(event.data, ResponseTextDeltaEvent):
            print(event.data.delta, end="", flush=True)

asyncio.run(main())
const stream = await run(agent, "Write a haiku about rivers.", { stream: true });
stream.toTextStream({ compatibleWithNodeStreams: true }).pipe(process.stdout);
await stream.completed;

Tool calling

from agents import function_tool

@function_tool
def get_weather(city: str) -> str:
    """Current weather for a city."""
    return f"Sunny, 21 C in {city}"

weather_agent = Agent(name="Weather", instructions="Answer weather questions.", model=model, tools=[get_weather])
print(Runner.run_sync(weather_agent, "What is the weather in Paris?").final_output)
import { tool } from "@openai/agents";
import { z } from "zod";

const getWeather = tool({
  name: "get_weather",
  description: "Current weather for a city",
  parameters: z.object({ city: z.string() }),
  async execute({ city }) {
    return `Sunny, 21 C in ${city}`;
  },
});

const weatherAgent = new Agent({ name: "Weather", instructions: "Answer weather questions.", model: "gpt-6-luna", tools: [getWeather] });
console.log((await run(weatherAgent, "What is the weather in Paris?")).finalOutput);

Specifics

  • Python: to use the client for every agent, call set_default_openai_client(client) and set_default_openai_api("chat_completions") once, then give agents a model name such as "gpt-6-luna".
  • The SDK uses OpenAI's Responses API by default. We serve /v1/responses too, but Chat Completions works with every text model, so the examples switch to it.
  • With tracing off you lose OpenAI's trace dashboard. To keep traces, add your own trace processor; see the SDK's tracing docs.
  • For images, video and other media call Jobs with the HTTP helper inside a function tool.

Next