"""Adapter factory and config resolution (CYA-WP-0008).""" import os from pathlib import Path import pytest from cya.config import bound_session_turns, load_llm_settings from cya.llm.adapter import FakeLLMAdapter from cya.llm.connect_adapter import LLMConnectAdapter from cya.llm.factory import get_adapter def test_default_adapter_is_fake(monkeypatch): monkeypatch.delenv("CYA_LLM_ADAPTER", raising=False) monkeypatch.setattr("cya.config._USER_CONFIG", Path("/nonexistent/config.toml")) adapter = get_adapter() assert isinstance(adapter, FakeLLMAdapter) def test_offline_forces_fake(monkeypatch, tmp_path): cfg = tmp_path / "config.toml" cfg.write_text('[llm]\nadapter = "connect"\nbackend = "openrouter"\n') monkeypatch.setattr("cya.config._USER_CONFIG", cfg) adapter = get_adapter(offline=True) assert isinstance(adapter, FakeLLMAdapter) def test_connect_adapter_when_configured(monkeypatch, tmp_path): cfg = tmp_path / "config.toml" cfg.write_text('[llm]\nadapter = "connect"\nbackend = "mock"\n') monkeypatch.setattr("cya.config._USER_CONFIG", cfg) adapter = get_adapter() assert isinstance(adapter, LLMConnectAdapter) def test_env_adapter_override(monkeypatch): monkeypatch.setenv("CYA_LLM_ADAPTER", "connect") monkeypatch.setenv("CYA_LLM_BACKEND", "mock") adapter = get_adapter() assert isinstance(adapter, LLMConnectAdapter) def test_load_llm_settings_merges_project_config(monkeypatch, tmp_path): user_cfg = tmp_path / "user.toml" user_cfg.write_text('[llm]\nbackend = "openrouter"\nmodel = "from-user"\n') project_cfg = tmp_path / ".cya.toml" project_cfg.write_text('[llm]\nmodel = "from-project"\n') monkeypatch.setattr("cya.config._USER_CONFIG", user_cfg) monkeypatch.setattr("cya.config._find_project_config", lambda start=None: project_cfg) settings = load_llm_settings() assert settings.backend == "openrouter" assert settings.model == "from-project" assert settings.adapter == "connect" def test_bound_session_turns_limits(): turns = [ {"user": "a" * 1000, "assistant": "b" * 1000}, {"user": "c" * 1000, "assistant": "d" * 1000}, {"user": "e", "assistant": "f"}, ] bounded = bound_session_turns(turns, max_turns=10, max_chars=2500) assert len(bounded) >= 1 total = sum(len(t["user"]) + len(t["assistant"]) for t in bounded) assert total <= 2500 or len(bounded) == 1