import os import pytest from arena.agent import _load_dotenv, _normalize_openrouter_model, create_session from arena.model_catalog import ModelProviderConfig from arena.model_provider import create_chat_model def test_create_session_returns_local_provider_with_env() -> None: os.environ["DEEPAGENT_SANDBOX_PROVIDER"] = "local" try: session = create_session("test-session") finally: os.environ.pop("DEEPAGENT_SANDBOX_PROVIDER", None) assert session.provider == "local" assert session.thread_id == "test-session" assert session.workspace_dir == "/workspace" session.close() def test_session_creates_composite_backend() -> None: os.environ["DEEPAGENT_SANDBOX_PROVIDER"] = "local" try: session = create_session("test-composite") finally: os.environ.pop("DEEPAGENT_SANDBOX_PROVIDER", None) from deepagents.backends import CompositeBackend assert isinstance(session.backend, CompositeBackend) assert session.workspace_dir == "/workspace" assert session.agent is not None session.close() def test_disallowed_provider_raises() -> None: os.environ["DEEPAGENT_SANDBOX_PROVIDER"] = "nonexistent" try: with pytest.raises(ValueError, match="Unsupported sandbox provider"): create_session("test-bad") finally: os.environ.pop("DEEPAGENT_SANDBOX_PROVIDER", None) def test_default_model_is_used_when_not_set() -> None: os.environ["DEEPAGENT_SANDBOX_PROVIDER"] = "local" os.environ.pop("DEEPAGENT_MODEL", None) try: session = create_session("test-default-model") finally: os.environ.pop("DEEPAGENT_SANDBOX_PROVIDER", None) assert session.agent is not None session.close() @pytest.mark.parametrize( ("configured", "expected"), [ ("openrouter/qwen/qwen-2.5-7b-instruct", "qwen/qwen-2.5-7b-instruct"), ("openrouter:qwen/qwen-2.5-7b-instruct", "qwen/qwen-2.5-7b-instruct"), ("qwen/qwen-2.5-7b-instruct", "qwen/qwen-2.5-7b-instruct"), ], ) def test_openrouter_model_normalizes_legacy_prefixes(configured: str, expected: str) -> None: assert _normalize_openrouter_model(configured) == expected def test_create_chat_model_uses_custom_openai_compatible_endpoint() -> None: model = create_chat_model( ModelProviderConfig( provider="custom", model="custom-model", api_key="custom-key", base_url="https://example.test/v1", ) ) assert getattr(model, "model_name", getattr(model, "model", "")) == "custom-model" assert str(model.model_dump()["openai_api_base"]).rstrip("/") == "https://example.test/v1" def test_create_chat_model_uses_openrouter_deepagents_supported_provider() -> None: model = create_chat_model( ModelProviderConfig( provider="openrouter", model="qwen/qwen3.5-9b", api_key="user-key", ) ) assert type(model).__name__ == "ChatOpenRouter" assert getattr(model, "model_name", getattr(model, "model", "")) == "qwen/qwen3.5-9b" def test_create_chat_model_uses_cached_local_model_without_endpoint() -> None: model = create_chat_model( ModelProviderConfig( provider="local", model="unsloth/gemma-4-12B-it-qat-GGUF", ) ) assert type(model).__name__ == "CachedLocalChatModel" assert model.model_id == "unsloth/gemma-4-12B-it-qat-GGUF" def test_create_chat_model_uses_openai_compatible_local_endpoint() -> None: model = create_chat_model( ModelProviderConfig( provider="local", model="local-model", base_url="http://127.0.0.1:8000/v1", ) ) assert type(model).__name__ == "ChatOpenAI" assert str(model.model_dump()["openai_api_base"]).rstrip("/") == "http://127.0.0.1:8000/v1" def test_per_run_openrouter_config_does_not_fall_back_to_server_key(monkeypatch) -> None: monkeypatch.setenv("OPENROUTER_API_KEY", "server-secret") with pytest.raises(Exception, match="OPENROUTER_API_KEY must be set"): create_chat_model( ModelProviderConfig( provider="openrouter", model="qwen/qwen3.5-9b", ) ) def test_load_dotenv_does_not_override_existing_env() -> None: os.environ["TEST_KEY"] = "from-env" try: _load_dotenv() finally: os.environ.pop("TEST_KEY", None)