Skip to content
Open
Show file tree
Hide file tree
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
29 changes: 27 additions & 2 deletions openai_agents/model_providers/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,32 @@ The example uses Anthropic Claude by default but can be modified to use other Li

Find more LiteLLM providers at: https://docs.litellm.ai/docs/providers

#### Tuning Engines
Uses a custom `ModelProvider` to route OpenAI Agents SDK model calls through the Tuning Engines OpenAI-compatible gateway.

Set your Tuning Engines inference key and, optionally, the tenant model alias to use:

```bash
export TUNING_ENGINES_API_KEY="sk-te-..."
export TUNING_ENGINES_MODEL="your-model-alias"
# Optional, defaults to https://api.tuningengines.com/v1
export TUNING_ENGINES_BASE_URL="https://api.tuningengines.com/v1"
```

Start the Tuning Engines provider worker:

```bash
uv run openai_agents/model_providers/run_tuning_engines_worker.py
```

Then run the example in a separate terminal:

```bash
uv run openai_agents/model_providers/run_tuning_engines_workflow.py
```

Use a model alias that is available to the configured Tuning Engines inference key.

### Extra

#### GPT-OSS with Ollama
Expand Down Expand Up @@ -63,5 +89,4 @@ uv run openai_agents/model_providers/run_gpt_oss_workflow.py

- **Custom Example Agent** - Custom OpenAI client integration
- **Custom Example Global** - Global default client configuration
- **Custom Example Provider** - Custom ModelProvider pattern
- **LiteLLM Provider** - Interactive model/API key input
- **LiteLLM Provider** - Interactive model/API key input
74 changes: 74 additions & 0 deletions openai_agents/model_providers/run_tuning_engines_worker.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import asyncio
import os
from datetime import timedelta
from typing import Optional

from agents import (
Model,
ModelProvider,
OpenAIChatCompletionsModel,
set_tracing_disabled,
)
from openai import AsyncOpenAI
from temporalio.client import Client
from temporalio.contrib.openai_agents import ModelActivityParameters, OpenAIAgentsPlugin
from temporalio.worker import Worker

from openai_agents.model_providers.workflows.tuning_engines_workflow import (
TuningEnginesWorkflow,
)

TUNING_ENGINES_BASE_URL = os.environ.get(
"TUNING_ENGINES_BASE_URL", "https://api.tuningengines.com/v1"
)
TUNING_ENGINES_MODEL = os.environ.get("TUNING_ENGINES_MODEL")
TUNING_ENGINES_API_KEY = os.environ.get("TUNING_ENGINES_API_KEY")

if not TUNING_ENGINES_API_KEY:
raise RuntimeError("Set TUNING_ENGINES_API_KEY before starting this worker")

tuning_engines_client = AsyncOpenAI(
base_url=TUNING_ENGINES_BASE_URL,
api_key=TUNING_ENGINES_API_KEY,
)


class TuningEnginesModelProvider(ModelProvider):
def get_model(self, model_name: Optional[str]) -> Model:
model = OpenAIChatCompletionsModel(
model=TUNING_ENGINES_MODEL or model_name or "tuning-engines-default",
openai_client=tuning_engines_client,
)
return model


async def main():
# Disable Agents SDK tracing — the default exporter sends traces to OpenAI's
# backend, which requires an OpenAI API key not available in these samples.
# Call here rather than in the workflow because it's a global side effect.
set_tracing_disabled(disabled=True)

client = await Client.connect(
"localhost:7233",
plugins=[
OpenAIAgentsPlugin(
model_params=ModelActivityParameters(
start_to_close_timeout=timedelta(seconds=30)
),
model_provider=TuningEnginesModelProvider(),
),
],
)

worker = Worker(
client,
task_queue="openai-agents-model-providers-task-queue",
workflows=[
TuningEnginesWorkflow,
],
)
await worker.run()


if __name__ == "__main__":
asyncio.run(main())
29 changes: 29 additions & 0 deletions openai_agents/model_providers/run_tuning_engines_workflow.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import asyncio

from temporalio.client import Client
from temporalio.contrib.openai_agents import OpenAIAgentsPlugin

from openai_agents.model_providers.workflows.tuning_engines_workflow import (
TuningEnginesWorkflow,
)


async def main():
client = await Client.connect(
"localhost:7233",
plugins=[
OpenAIAgentsPlugin(),
],
)

result = await client.execute_workflow(
TuningEnginesWorkflow.run,
"Explain why a governed model gateway is useful in production.",
id="tuning-engines-workflow-id",
task_queue="openai-agents-model-providers-task-queue",
)
print(f"Result: {result}")


if __name__ == "__main__":
asyncio.run(main())
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from __future__ import annotations

from agents import Agent, Runner, function_tool
from temporalio import workflow


@workflow.defn
class TuningEnginesWorkflow:
@workflow.run
async def run(self, prompt: str) -> str:
@function_tool
def summarize_gateway_policy(topic: str):
return (
f"For {topic}, keep model access scoped, log usage, and route "
"through approved tenant model aliases."
)

agent = Agent(
name="Assistant",
instructions=(
"You explain production AI gateway tradeoffs clearly and use the "
"policy summary tool when governance is relevant."
),
model="tuning-engines-default",
tools=[summarize_gateway_policy],
)

result = await Runner.run(agent, prompt)
return result.final_output