Files
strix/tests/llm/test_anthropic_cache_wrapper.py
T
0xallam af42499b95 refactor: remove all strix/ model alias machinery
The Strix proxy / ``strix/`` model namespace is gone. Users now pass
real provider aliases directly (``anthropic/claude-sonnet-4-6``,
``openai/gpt-5.4``, ``gemini/...``, ``openrouter/...``).

Deleted:
- ``STRIX_API_BASE`` constant in ``strix/config/config.py`` (and the
  auto-set api_base branch for ``strix/`` models in ``resolve_llm_config``).
- ``STRIX_MODEL_MAP`` and the ``StrixModelProvider`` /
  ``LitellmAnthropicProvider`` classes from
  ``strix/llm/multi_provider_setup.py``.
- ``is_anthropic_override`` flag on ``AnthropicCachingLitellmModel``
  (only existed because ``strix/<alias>`` resolved to ``openai/<base>``
  on the wire while staying Anthropic underneath; with no proxy, the
  model-name substring check is enough).
- ``startswith("strix/")`` branches in ``cli.py`` / ``main.py`` /
  ``dedupe.py`` and the ``uses_strix_models`` env-validation flag.

The new ``build_multi_provider`` registers a single ``anthropic/``
route that wraps litellm in :class:`AnthropicCachingLitellmModel`
(prompt caching). Every other prefix falls through to the SDK's
built-in routing.

Defaults flipped from ``strix/claude-sonnet-4.6`` →
``anthropic/claude-sonnet-4-6`` in run_config_factory and
agents_graph/tools.py + corresponding tests.

Tests updated:
- ``test_anthropic_cache_wrapper.py``: drop the override-flag tests.
- ``test_multi_provider_setup.py``: rewrite around the new single
  ``_AnthropicCachingProvider`` route.
- ``test_tool_registration_modes.py::test_load_skill_import_...``:
  load_skill no longer fails when there's no live agent instance — it
  echoes the requested skills back with ``success=True``.

Tests: 281/281 passing.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 09:37:14 -07:00

75 lines
2.4 KiB
Python

"""Smoke tests for AnthropicCachingLitellmModel."""
from __future__ import annotations
from strix.llm.anthropic_cache_wrapper import AnthropicCachingLitellmModel
def _make(model: str) -> AnthropicCachingLitellmModel:
# ``LitellmModel.__init__`` only validates that model is a string; we
# don't need a real API key for in-memory ``_patch`` testing.
return AnthropicCachingLitellmModel(model=model, api_key="test-key")
def test_is_anthropic_detects_anthropic_prefix() -> None:
m = _make("anthropic/claude-3-5-sonnet")
assert m._is_anthropic() is True
def test_is_anthropic_detects_claude_substring() -> None:
m = _make("openrouter/anthropic-claude-haiku")
assert m._is_anthropic() is True
def test_is_anthropic_false_for_openai() -> None:
m = _make("openai/gpt-4o")
assert m._is_anthropic() is False
def test_is_anthropic_false_for_gemini() -> None:
m = _make("gemini/gemini-1.5-pro")
assert m._is_anthropic() is False
def test_patch_anthropic_adds_cache_control_to_system() -> None:
m = _make("anthropic/claude-3-5-sonnet")
items: list = [
{"role": "system", "content": "You are a helpful agent."},
{"role": "user", "content": "hi"},
]
out = m._patch(items)
assert out[0]["role"] == "system"
content = out[0]["content"]
assert isinstance(content, list)
assert content[0]["type"] == "text"
assert content[0]["text"] == "You are a helpful agent."
assert content[0]["cache_control"] == {"type": "ephemeral"}
# Second item passes through unchanged.
assert out[1] == {"role": "user", "content": "hi"}
def test_patch_non_anthropic_passes_through() -> None:
m = _make("openai/gpt-4o")
items: list = [
{"role": "system", "content": "You are a helpful agent."},
{"role": "user", "content": "hi"},
]
assert m._patch(items) is items # exact same list reference, no copy
def test_patch_skips_non_string_system_content() -> None:
"""If system content is already structured (e.g., previously patched),
don't re-wrap — pass through unchanged."""
m = _make("anthropic/claude-3-5-sonnet")
items: list = [
{"role": "system", "content": [{"type": "text", "text": "x"}]},
{"role": "user", "content": "hi"},
]
out = m._patch(items)
assert out[0]["content"] == [{"type": "text", "text": "x"}]
def test_patch_handles_empty_list() -> None:
m = _make("anthropic/claude-3-5-sonnet")
assert m._patch([]) == []