Files
strix/tests/tools/test_tool_registration_modes.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

103 lines
3.5 KiB
Python

import importlib
import sys
from types import ModuleType
from typing import Any
from strix.config import Config
from strix.tools.registry import clear_registry
def _empty_config_load(_cls: type[Config]) -> dict[str, dict[str, str]]:
return {"env": {}}
def _reload_tools_module() -> ModuleType:
clear_registry()
for name in list(sys.modules):
if name == "strix.tools" or name.startswith("strix.tools."):
sys.modules.pop(name, None)
return importlib.import_module("strix.tools")
def test_non_sandbox_skips_browser_and_web_search_when_disabled(
monkeypatch: Any,
) -> None:
"""Browser registration is gated on STRIX_DISABLE_BROWSER and
web_search on PERPLEXITY_API_KEY; both should stay out of the
in-container ``register_tool`` registry when their gates are off.
Agents_graph is no longer in this registry — those tools are SDK
function tools (host-side only), not in-container tools.
"""
monkeypatch.setenv("STRIX_SANDBOX_MODE", "false")
monkeypatch.setenv("STRIX_DISABLE_BROWSER", "true")
monkeypatch.delenv("PERPLEXITY_API_KEY", raising=False)
monkeypatch.setattr(Config, "load", classmethod(_empty_config_load))
tools = _reload_tools_module()
names = set(tools.get_tool_names())
assert "browser_action" not in names
assert "web_search" not in names
def test_sandbox_registers_sandbox_tools_but_not_non_sandbox_tools(
monkeypatch: Any,
) -> None:
monkeypatch.setenv("STRIX_SANDBOX_MODE", "true")
monkeypatch.setenv("STRIX_DISABLE_BROWSER", "true")
monkeypatch.delenv("PERPLEXITY_API_KEY", raising=False)
monkeypatch.setattr(Config, "load", classmethod(_empty_config_load))
tools = _reload_tools_module()
names = set(tools.get_tool_names())
assert "terminal_execute" in names
assert "python_action" in names
assert "list_requests" in names
assert "create_agent" not in names
assert "finish_scan" not in names
assert "load_skill" not in names
assert "browser_action" not in names
assert "web_search" not in names
def test_load_skill_import_does_not_register_create_agent_in_sandbox(
monkeypatch: Any,
) -> None:
monkeypatch.setenv("STRIX_SANDBOX_MODE", "true")
monkeypatch.setenv("STRIX_DISABLE_BROWSER", "true")
monkeypatch.delenv("PERPLEXITY_API_KEY", raising=False)
monkeypatch.setattr(Config, "load", classmethod(_empty_config_load))
clear_registry()
for name in list(sys.modules):
if name == "strix.tools" or name.startswith("strix.tools."):
sys.modules.pop(name, None)
load_skill_module = importlib.import_module("strix.tools.load_skill.load_skill_actions")
registry = importlib.import_module("strix.tools.registry")
names_before = set(registry.get_tool_names())
assert "load_skill" not in names_before
assert "create_agent" not in names_before
state_type = type(
"DummyState",
(),
{
"agent_id": "agent_test",
"context": {},
"update_context": lambda self, key, value: self.context.__setitem__(key, value),
},
)
result = load_skill_module.load_skill(state_type(), "nmap")
names_after = set(registry.get_tool_names())
assert "create_agent" not in names_after
# load_skill no longer reaches into the legacy _agent_instances global —
# it returns ``success=True`` with the requested skills echoed back.
assert result["success"] is True
assert result["loaded_skills"] == ["nmap"]