mirror of
https://github.com/TauricResearch/TradingAgents.git
synced 2026-06-16 21:06:15 +03:00
Clear the deferred full-repo lint backlog so the whole tree passes the strict ruff select (E,W,F,I,B,UP,C4,SIM). Mechanical fixes dominate: import sorting, pep585/604 annotations, dropped dead imports, and whitespace. The few semantic changes are behavior-preserving: declare __all__ on the agent_utils and alpha_vantage re-export hubs; expand 'from x import *' to explicit names; use immutable tuple defaults instead of mutable list defaults; contextlib.suppress for try/except/pass; and narrow an over-broad assertRaises.
75 lines
3.3 KiB
Python
75 lines
3.3 KiB
Python
"""Generic OpenAI-compatible provider (vLLM / LM Studio / llama.cpp / relays).
|
|
|
|
Verifies the user-supplied base_url is required and honored, the key is optional
|
|
(keyless local default), Chat Completions (not the Responses API) is used, any
|
|
model name is accepted, and the env backend URL precedence (#978).
|
|
"""
|
|
|
|
import pytest
|
|
|
|
from tradingagents.llm_clients.api_key_env import get_api_key_env
|
|
from tradingagents.llm_clients.factory import create_llm_client
|
|
from tradingagents.llm_clients.validators import validate_model
|
|
|
|
# Note: assert by class NAME, not isinstance — other tests reload the
|
|
# openai_client module, which would otherwise create a second class identity.
|
|
|
|
|
|
@pytest.mark.unit
|
|
def test_factory_routes_to_openai_client():
|
|
client = create_llm_client(
|
|
provider="openai_compatible", model="my-model", base_url="http://localhost:8000/v1"
|
|
)
|
|
assert type(client).__name__ == "OpenAIClient"
|
|
|
|
|
|
@pytest.mark.unit
|
|
def test_base_url_required(monkeypatch):
|
|
monkeypatch.delenv("OPENAI_COMPATIBLE_API_KEY", raising=False)
|
|
with pytest.raises(ValueError, match="requires a base_url"):
|
|
create_llm_client(provider="openai_compatible", model="m").get_llm()
|
|
|
|
|
|
@pytest.mark.unit
|
|
def test_keyless_local_uses_placeholder_and_chat_completions(monkeypatch):
|
|
monkeypatch.delenv("OPENAI_COMPATIBLE_API_KEY", raising=False)
|
|
llm = create_llm_client(
|
|
provider="openai_compatible", model="qwen2.5", base_url="http://localhost:8000/v1"
|
|
).get_llm()
|
|
assert type(llm).__name__ == "NormalizedChatOpenAI"
|
|
assert str(llm.openai_api_base) == "http://localhost:8000/v1"
|
|
# keyless local servers: a placeholder key is sent
|
|
key = llm.openai_api_key.get_secret_value() if hasattr(llm.openai_api_key, "get_secret_value") else llm.openai_api_key
|
|
assert key == "EMPTY"
|
|
# must use Chat Completions, not OpenAI's Responses API
|
|
assert getattr(llm, "use_responses_api", False) in (False, None)
|
|
|
|
|
|
@pytest.mark.unit
|
|
def test_optional_key_from_env(monkeypatch):
|
|
monkeypatch.setenv("OPENAI_COMPATIBLE_API_KEY", "sk-relay-123")
|
|
llm = create_llm_client(
|
|
provider="openai_compatible", model="m", base_url="https://relay.example/v1"
|
|
).get_llm()
|
|
key = llm.openai_api_key.get_secret_value() if hasattr(llm.openai_api_key, "get_secret_value") else llm.openai_api_key
|
|
assert key == "sk-relay-123"
|
|
|
|
|
|
@pytest.mark.unit
|
|
def test_any_model_accepted_no_forced_key():
|
|
assert validate_model("openai_compatible", "literally-anything") is True
|
|
# The key env exists (read for keyed relays) but the provider is marked
|
|
# key-optional, so the CLI never forces a prompt and keyless servers work.
|
|
assert get_api_key_env("openai_compatible") == "OPENAI_COMPATIBLE_API_KEY"
|
|
from tradingagents.llm_clients.openai_client import OPENAI_COMPATIBLE_PROVIDERS
|
|
assert OPENAI_COMPATIBLE_PROVIDERS["openai_compatible"].key_optional is True
|
|
|
|
|
|
@pytest.mark.unit
|
|
def test_env_backend_url_precedence():
|
|
# #978: explicit env URL wins over the menu/default regardless of provider source.
|
|
from cli.utils import resolve_backend_url
|
|
assert resolve_backend_url("openai", "https://api.openai.com/v1", env_url="http://proxy/v1") == "http://proxy/v1"
|
|
assert resolve_backend_url("openai", "https://api.openai.com/v1", env_url=None) == "https://api.openai.com/v1"
|
|
assert resolve_backend_url("deepseek", None, None) == "https://api.deepseek.com"
|