from typing import Any, cast import pytest from agents import ( Agent, MultiProvider, OpenAIResponsesModel, OpenAIResponsesWSModel, RunConfig, UserError, ) from agents.extensions.models.litellm_model import LitellmModel from agents.models.multi_provider import MultiProviderMap from agents.models.openai_chatcompletions import OpenAIChatCompletionsModel from agents.run_internal.run_loop import get_model def test_no_prefix_is_openai(): agent = Agent(model="gpt-4o", instructions="", name="test") model = get_model(agent, RunConfig()) assert isinstance(model, OpenAIResponsesModel) def test_openai_prefix_is_openai(): agent = Agent(model="openai/gpt-4o", instructions="", name="test") model = get_model(agent, RunConfig()) assert isinstance(model, OpenAIResponsesModel) def test_litellm_prefix_is_litellm(): agent = Agent(model="litellm/foo/bar", instructions="", name="test") model = get_model(agent, RunConfig()) assert isinstance(model, LitellmModel) def test_any_llm_prefix_uses_any_llm_provider(monkeypatch): import sys import types as pytypes captured_model: dict[str, Any] = {} class FakeAnyLLMModel: pass class FakeAnyLLMProvider: def get_model(self, model_name): captured_model["value"] = model_name return FakeAnyLLMModel() fake_module: Any = pytypes.ModuleType("agents.extensions.models.any_llm_provider") fake_module.AnyLLMProvider = FakeAnyLLMProvider monkeypatch.setitem(sys.modules, "agents.extensions.models.any_llm_provider", fake_module) agent = Agent(model="any-llm/openrouter/openai/gpt-5.4-mini", instructions="", name="test") model = get_model(agent, RunConfig()) assert isinstance(model, FakeAnyLLMModel) assert captured_model["value"] == "openrouter/openai/gpt-5.4-mini" def test_no_prefix_can_use_openai_responses_websocket(): agent = Agent(model="gpt-4o", instructions="", name="test") model = get_model( agent, RunConfig(model_provider=MultiProvider(openai_use_responses_websocket=True)), ) assert isinstance(model, OpenAIResponsesWSModel) def test_openai_prefix_can_use_openai_responses_websocket(): agent = Agent(model="openai/gpt-4o", instructions="", name="test") model = get_model( agent, RunConfig(model_provider=MultiProvider(openai_use_responses_websocket=True)), ) assert isinstance(model, OpenAIResponsesWSModel) def test_multi_provider_passes_websocket_base_url_to_openai_provider(monkeypatch): captured_kwargs = {} class FakeOpenAIProvider: def __init__(self, **kwargs): captured_kwargs.update(kwargs) def get_model(self, model_name): raise AssertionError("This test only verifies constructor passthrough.") monkeypatch.setattr("agents.models.multi_provider.OpenAIProvider", FakeOpenAIProvider) MultiProvider(openai_websocket_base_url="wss://proxy.example.test/v1") assert captured_kwargs["websocket_base_url"] == "wss://proxy.example.test/v1" def test_multi_provider_forwards_openai_buffer_streamed_tool_calls_to_chat_model(): provider = MultiProvider( openai_client=cast(Any, object()), openai_use_responses=False, openai_buffer_streamed_tool_calls=True, ) model = provider.get_model("gpt-4o") assert isinstance(model, OpenAIChatCompletionsModel) assert model._buffer_streamed_tool_calls is True def test_openai_prefix_defaults_to_alias_mode(monkeypatch): captured_model: dict[str, Any] = {} class FakeOpenAIProvider: def __init__(self, **kwargs): pass def get_model(self, model_name): captured_model["value"] = model_name return object() monkeypatch.setattr("agents.models.multi_provider.OpenAIProvider", FakeOpenAIProvider) provider = MultiProvider() provider.get_model("openai/gpt-4o") assert captured_model["value"] == "gpt-4o" def test_openai_prefix_can_be_preserved_as_literal_model_id(monkeypatch): captured_model: dict[str, Any] = {} class FakeOpenAIProvider: def __init__(self, **kwargs): pass def get_model(self, model_name): captured_model["value"] = model_name return object() monkeypatch.setattr("agents.models.multi_provider.OpenAIProvider", FakeOpenAIProvider) provider = MultiProvider(openai_prefix_mode="model_id") provider.get_model("openai/gpt-4o") assert captured_model["value"] == "openai/gpt-4o" def test_unknown_prefix_defaults_to_error(): provider = MultiProvider() with pytest.raises(UserError, match="Unknown prefix: openrouter"): provider.get_model("openrouter/openai/gpt-4o") def test_unknown_prefix_can_be_preserved_for_openai_compatible_model_ids(monkeypatch): captured_model: dict[str, Any] = {} captured_result: dict[str, Any] = {} class FakeOpenAIProvider: def __init__(self, **kwargs): pass def get_model(self, model_name): captured_model["value"] = model_name fake_model = object() captured_result["value"] = fake_model return fake_model monkeypatch.setattr("agents.models.multi_provider.OpenAIProvider", FakeOpenAIProvider) provider = MultiProvider(unknown_prefix_mode="model_id") result = provider.get_model("openrouter/openai/gpt-4o") assert result is captured_result["value"] assert captured_model["value"] == "openrouter/openai/gpt-4o" def test_provider_map_entries_override_openai_prefix_mode(monkeypatch): captured_model: dict[str, Any] = {} class FakeCustomProvider: def get_model(self, model_name): captured_model["value"] = model_name return object() class FakeOpenAIProvider: def __init__(self, **kwargs): pass def get_model(self, model_name): raise AssertionError("Expected the explicit provider_map entry to win.") monkeypatch.setattr("agents.models.multi_provider.OpenAIProvider", FakeOpenAIProvider) provider_map = MultiProviderMap() provider_map.add_provider("openai", cast(Any, FakeCustomProvider())) provider = MultiProvider( provider_map=provider_map, openai_prefix_mode="model_id", ) provider.get_model("openai/gpt-4o") assert captured_model["value"] == "gpt-4o" def test_multi_provider_rejects_invalid_prefix_modes(): bad_openai_prefix_mode: Any = "invalid" bad_unknown_prefix_mode: Any = "invalid" with pytest.raises(UserError, match="openai_prefix_mode"): MultiProvider(openai_prefix_mode=bad_openai_prefix_mode) with pytest.raises(UserError, match="unknown_prefix_mode"): MultiProvider(unknown_prefix_mode=bad_unknown_prefix_mode)