Skip to content

Commit 1c0ff59

Browse files
authored
feat: add any-llm model support with responses-compatible routing (#2706)
1 parent 8e1915e commit 1c0ff59

File tree

12 files changed

+2059
-23
lines changed

12 files changed

+2059
-23
lines changed

examples/model_providers/README.md

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,24 @@
1-
# Custom LLM providers
1+
# Model provider examples
22

3-
The examples in this directory demonstrate how you might use a non-OpenAI LLM provider. To run them, first set a base URL, API key and model.
3+
The examples in this directory show how to route models through adapter layers such as LiteLLM and
4+
any-llm. The default examples all use OpenRouter so you only need one API key:
45

56
```bash
6-
export EXAMPLE_BASE_URL="..."
7-
export EXAMPLE_API_KEY="..."
8-
export EXAMPLE_MODEL_NAME"..."
7+
export OPENROUTER_API_KEY="..."
98
```
109

11-
Then run the examples, e.g.:
10+
Run one of the adapter examples:
1211

12+
```bash
13+
uv run examples/model_providers/any_llm_provider.py
14+
uv run examples/model_providers/any_llm_auto.py
15+
uv run examples/model_providers/litellm_provider.py
16+
uv run examples/model_providers/litellm_auto.py
1317
```
14-
python examples/model_providers/custom_example_provider.py
1518

16-
Loops within themselves,
17-
Function calls its own being,
18-
Depth without ending.
19+
Direct-model examples let you override the target model:
20+
21+
```bash
22+
uv run examples/model_providers/any_llm_provider.py --model openrouter/openai/gpt-5.4-mini
23+
uv run examples/model_providers/litellm_provider.py --model openrouter/openai/gpt-5.4-mini
1924
```
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
from __future__ import annotations
2+
3+
import asyncio
4+
5+
from pydantic import BaseModel
6+
7+
from agents import Agent, ModelSettings, Runner, function_tool, set_tracing_disabled
8+
9+
"""This example uses the built-in any-llm routing through OpenRouter.
10+
11+
Set OPENROUTER_API_KEY before running it.
12+
"""
13+
14+
set_tracing_disabled(disabled=True)
15+
16+
17+
@function_tool
18+
def get_weather(city: str):
19+
print(f"[debug] getting weather for {city}")
20+
return f"The weather in {city} is sunny."
21+
22+
23+
class Result(BaseModel):
24+
output_text: str
25+
tool_results: list[str]
26+
27+
28+
async def main():
29+
agent = Agent(
30+
name="Assistant",
31+
instructions="You only respond in haikus.",
32+
model="any-llm/openrouter/openai/gpt-5.4-mini",
33+
tools=[get_weather],
34+
model_settings=ModelSettings(tool_choice="required"),
35+
output_type=Result,
36+
)
37+
38+
result = await Runner.run(agent, "What's the weather in Tokyo?")
39+
print(result.final_output)
40+
41+
42+
if __name__ == "__main__":
43+
import os
44+
45+
if os.getenv("OPENROUTER_API_KEY") is None:
46+
raise ValueError(
47+
"OPENROUTER_API_KEY is not set. Please set the environment variable and try again."
48+
)
49+
50+
asyncio.run(main())
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
from __future__ import annotations
2+
3+
import asyncio
4+
import os
5+
6+
from agents import Agent, Runner, function_tool, set_tracing_disabled
7+
from agents.extensions.models.any_llm_model import AnyLLMModel
8+
9+
"""This example uses the AnyLLMModel directly.
10+
11+
You can run it like this:
12+
uv run examples/model_providers/any_llm_provider.py --model openrouter/openai/gpt-5.4-mini
13+
or
14+
uv run examples/model_providers/any_llm_provider.py --model openrouter/anthropic/claude-4.5-sonnet
15+
"""
16+
17+
set_tracing_disabled(disabled=True)
18+
19+
20+
@function_tool
21+
def get_weather(city: str):
22+
print(f"[debug] getting weather for {city}")
23+
return f"The weather in {city} is sunny."
24+
25+
26+
async def main(model: str, api_key: str):
27+
if api_key == "dummy":
28+
print("Skipping run because no valid OPENROUTER_API_KEY was provided.")
29+
return
30+
31+
agent = Agent(
32+
name="Assistant",
33+
instructions="You only respond in haikus.",
34+
model=AnyLLMModel(model=model, api_key=api_key),
35+
tools=[get_weather],
36+
)
37+
38+
result = await Runner.run(agent, "What's the weather in Tokyo?")
39+
print(result.final_output)
40+
41+
42+
if __name__ == "__main__":
43+
import argparse
44+
45+
parser = argparse.ArgumentParser()
46+
parser.add_argument("--model", type=str, required=False)
47+
parser.add_argument("--api-key", type=str, required=False)
48+
args = parser.parse_args()
49+
50+
model = args.model or os.environ.get("ANY_LLM_MODEL", "openrouter/openai/gpt-5.4-mini")
51+
api_key = args.api_key or os.environ.get("OPENROUTER_API_KEY", "dummy")
52+
53+
if not args.model:
54+
print(f"Using default model: {model}")
55+
if not args.api_key:
56+
print("Using OPENROUTER_API_KEY from environment (or dummy placeholder).")
57+
58+
asyncio.run(main(model, api_key))

examples/model_providers/litellm_auto.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@
66

77
from agents import Agent, ModelSettings, Runner, function_tool, set_tracing_disabled
88

9-
"""This example uses the built-in support for LiteLLM. To use this, ensure you have the
10-
ANTHROPIC_API_KEY environment variable set.
9+
"""This example uses the built-in support for LiteLLM through OpenRouter.
10+
11+
Set OPENROUTER_API_KEY before running it.
1112
"""
1213

1314
set_tracing_disabled(disabled=True)
@@ -32,7 +33,7 @@ async def main():
3233
name="Assistant",
3334
instructions="You only respond in haikus.",
3435
# We prefix with litellm/ to tell the Runner to use the LitellmModel
35-
model="litellm/anthropic/claude-sonnet-4-5-20250929",
36+
model="litellm/openrouter/openai/gpt-5.4-mini",
3637
tools=[get_weather],
3738
model_settings=ModelSettings(tool_choice="required"),
3839
output_type=Result,
@@ -45,9 +46,9 @@ async def main():
4546
if __name__ == "__main__":
4647
import os
4748

48-
if os.getenv("ANTHROPIC_API_KEY") is None:
49+
if os.getenv("OPENROUTER_API_KEY") is None:
4950
raise ValueError(
50-
"ANTHROPIC_API_KEY is not set. Please set it the environment variable and try again."
51+
"OPENROUTER_API_KEY is not set. Please set the environment variable and try again."
5152
)
5253

5354
asyncio.run(main())

examples/model_providers/litellm_provider.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88

99
"""This example uses the LitellmModel directly, to hit any model provider.
1010
You can run it like this:
11-
uv run examples/model_providers/litellm_provider.py --model anthropic/claude-3-5-sonnet-20240620
11+
uv run examples/model_providers/litellm_provider.py --model openrouter/openai/gpt-5.4-mini
1212
or
13-
uv run examples/model_providers/litellm_provider.py --model gemini/gemini-2.0-flash
13+
uv run examples/model_providers/litellm_provider.py --model openrouter/anthropic/claude-4.5-sonnet
1414
1515
Find more providers here: https://docs.litellm.ai/docs/providers
1616
"""
@@ -26,7 +26,7 @@ def get_weather(city: str):
2626

2727
async def main(model: str, api_key: str):
2828
if api_key == "dummy":
29-
print("Skipping run because no valid LITELLM_API_KEY was provided.")
29+
print("Skipping run because no valid OPENROUTER_API_KEY was provided.")
3030
return
3131
agent = Agent(
3232
name="Assistant",
@@ -48,12 +48,12 @@ async def main(model: str, api_key: str):
4848
parser.add_argument("--api-key", type=str, required=False)
4949
args = parser.parse_args()
5050

51-
model = args.model or os.environ.get("LITELLM_MODEL", "openai/gpt-4o-mini")
52-
api_key = args.api_key or os.environ.get("LITELLM_API_KEY", "dummy")
51+
model = args.model or os.environ.get("LITELLM_MODEL", "openrouter/openai/gpt-5.4-mini")
52+
api_key = args.api_key or os.environ.get("OPENROUTER_API_KEY", "dummy")
5353

5454
if not args.model:
5555
print(f"Using default model: {model}")
5656
if not args.api_key:
57-
print("Using LITELLM_API_KEY from environment (or dummy placeholder).")
57+
print("Using OPENROUTER_API_KEY from environment (or dummy placeholder).")
5858

5959
asyncio.run(main(model, api_key))

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ Repository = "https://github.com/openai/openai-agents-python"
3737
voice = ["numpy>=2.2.0, <3; python_version>='3.10'", "websockets>=15.0, <16"]
3838
viz = ["graphviz>=0.17"]
3939
litellm = ["litellm>=1.81.0, <2"]
40+
any-llm = ["any-llm-sdk>=1.11.0, <2; python_version >= '3.11'"]
4041
realtime = ["websockets>=15.0, <16"]
4142
sqlalchemy = ["SQLAlchemy>=2.0", "asyncpg>=0.29.0"]
4243
encrypt = ["cryptography>=45.0, <46"]

0 commit comments

Comments
 (0)