From af42499b95be8848a226741f6dca8c8dcb5e1dc2 Mon Sep 17 00:00:00 2001 From: 0xallam Date: Sat, 25 Apr 2026 09:37:14 -0700 Subject: [PATCH] refactor: remove all strix/ model alias machinery MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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/`` resolved to ``openai/`` 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) --- strix/agents/factory.py | 4 +- strix/config/config.py | 30 ++---- strix/interface/main.py | 11 +- strix/llm/anthropic_cache_wrapper.py | 19 ---- strix/llm/dedupe.py | 5 - strix/llm/multi_provider_setup.py | 108 ++++---------------- strix/run_config_factory.py | 4 +- strix/tools/agents_graph/tools.py | 4 +- tests/llm/test_anthropic_cache_wrapper.py | 36 +------ tests/llm/test_multi_provider_setup.py | 58 ++++------- tests/test_run_config_factory.py | 2 +- tests/tools/test_graph_tools.py | 6 +- tests/tools/test_tool_registration_modes.py | 5 +- 13 files changed, 69 insertions(+), 223 deletions(-) diff --git a/strix/agents/factory.py b/strix/agents/factory.py index 9ba90ce..0fc77d8 100644 --- a/strix/agents/factory.py +++ b/strix/agents/factory.py @@ -184,8 +184,8 @@ def build_strix_agent( instructions=instructions, tools=tools, tool_use_behavior=StopAtTools(stop_at_tool_names=list(stop_at)), - # model=None so ``RunConfig.model`` (e.g. ``strix/claude-sonnet-4.6``) - # routes through MultiProvider rather than the SDK's default. + # model=None so ``RunConfig.model`` drives provider selection + # via :func:`build_multi_provider` rather than the SDK's default. model=None, ) diff --git a/strix/config/config.py b/strix/config/config.py index 255df7c..df2ec49 100644 --- a/strix/config/config.py +++ b/strix/config/config.py @@ -5,9 +5,6 @@ from pathlib import Path from typing import Any, ClassVar -STRIX_API_BASE = "https://models.strix.ai/api/v1" - - class Config: """Configuration Manager for Strix.""" @@ -197,28 +194,23 @@ def save_current_config() -> bool: def resolve_llm_config() -> tuple[str | None, str | None, str | None]: - """Resolve LLM model, api_key, and api_base based on STRIX_LLM prefix. + """Resolve LLM model, api_key, and api_base. - Returns: - tuple: (model_name, api_key, api_base) - - model_name: Original model name (strix/ prefix preserved for display) - - api_key: LLM API key - - api_base: API base URL (auto-set to STRIX_API_BASE for strix/ models) + Returns ``(model_name, api_key, api_base)``. ``api_base`` falls back + through the ``LLM_API_BASE`` / ``OPENAI_API_BASE`` / + ``LITELLM_BASE_URL`` / ``OLLAMA_API_BASE`` env chain so the user can + point at any OpenAI-compatible endpoint without changing the code. """ model = Config.get("strix_llm") if not model: return None, None, None api_key = Config.get("llm_api_key") - - if model.startswith("strix/"): - api_base: str | None = STRIX_API_BASE - else: - api_base = ( - Config.get("llm_api_base") - or Config.get("openai_api_base") - or Config.get("litellm_base_url") - or Config.get("ollama_api_base") - ) + api_base: str | None = ( + Config.get("llm_api_base") + or Config.get("openai_api_base") + or Config.get("litellm_base_url") + or Config.get("ollama_api_base") + ) return model, api_key, api_base diff --git a/strix/interface/main.py b/strix/interface/main.py index 37535e3..19e7362 100644 --- a/strix/interface/main.py +++ b/strix/interface/main.py @@ -20,7 +20,6 @@ from rich.text import Text from strix.config import Config, apply_saved_config, save_current_config from strix.config.config import resolve_llm_config -from strix.llm.multi_provider_setup import STRIX_MODEL_MAP apply_saved_config() @@ -58,12 +57,10 @@ def validate_environment() -> None: missing_optional_vars = [] strix_llm = Config.get("strix_llm") - uses_strix_models = strix_llm and strix_llm.startswith("strix/") - if not strix_llm: missing_required_vars.append("STRIX_LLM") - has_base_url = uses_strix_models or any( + has_base_url = any( [ Config.get("llm_api_base"), Config.get("openai_api_base"), @@ -211,13 +208,7 @@ async def warm_up_llm() -> None: try: model_name, api_key, api_base = resolve_llm_config() - # ``strix/`` is routed through the Strix proxy (OpenAI-compatible); - # everything else is sent as-is. litellm_model: str | None = model_name - if model_name and model_name.startswith("strix/"): - base = model_name[len("strix/") :] - if base in STRIX_MODEL_MAP: - litellm_model = f"openai/{base}" test_messages = [ {"role": "system", "content": "You are a helpful assistant."}, diff --git a/strix/llm/anthropic_cache_wrapper.py b/strix/llm/anthropic_cache_wrapper.py index ff1b38f..3d6f62f 100644 --- a/strix/llm/anthropic_cache_wrapper.py +++ b/strix/llm/anthropic_cache_wrapper.py @@ -30,28 +30,9 @@ class AnthropicCachingLitellmModel(LitellmModel): Detection: case-insensitive substring match on ``"anthropic/"`` or ``"claude"`` against the model name. - - For Strix proxy routing where the API model is ``openai/`` but the - underlying provider is still Anthropic (e.g., ``strix/claude-sonnet-4.6`` - resolves to api_model=``openai/claude-sonnet-4.6`` against the Strix - proxy with a canonical of ``anthropic/claude-sonnet-4-6``), pass - ``is_anthropic_override=True`` so the wrapper still injects cache_control - even though the model name doesn't match the heuristic. """ - def __init__( - self, - model: str, - *, - is_anthropic_override: bool | None = None, - **kwargs: Any, - ) -> None: - super().__init__(model=model, **kwargs) - self._is_anthropic_override = is_anthropic_override - def _is_anthropic(self) -> bool: - if self._is_anthropic_override is not None: - return self._is_anthropic_override m = (self.model or "").lower() return "anthropic/" in m or "claude" in m diff --git a/strix/llm/dedupe.py b/strix/llm/dedupe.py index 292b8bc..9f0364a 100644 --- a/strix/llm/dedupe.py +++ b/strix/llm/dedupe.py @@ -6,7 +6,6 @@ from typing import Any import litellm from strix.config.config import resolve_llm_config -from strix.llm.multi_provider_setup import STRIX_MODEL_MAP logger = logging.getLogger(__name__) @@ -158,10 +157,6 @@ def check_duplicate( model_name, api_key, api_base = resolve_llm_config() litellm_model: str | None = model_name - if model_name and model_name.startswith("strix/"): - base = model_name[len("strix/") :] - if base in STRIX_MODEL_MAP: - litellm_model = f"openai/{base}" messages = [ {"role": "system", "content": DEDUPE_SYSTEM_PROMPT}, diff --git a/strix/llm/multi_provider_setup.py b/strix/llm/multi_provider_setup.py index 16cb752..ac20abb 100644 --- a/strix/llm/multi_provider_setup.py +++ b/strix/llm/multi_provider_setup.py @@ -1,116 +1,52 @@ -"""Multi-provider routing setup for Strix on top of the SDK MultiProvider. +"""Multi-provider routing setup. -The SDK's ``MultiProvider`` resolves a model name like ``"strix/claude-sonnet-4.6"`` -by stripping the prefix (``"strix"``) and dispatching to a registered -``ModelProvider`` keyed on that prefix. We register two custom providers: - -- ``"strix"`` → ``StrixModelProvider``: aliases the short name to a Strix-proxy - ``openai/`` model URL, but knows whether the underlying provider is - Anthropic so cache-control still gets injected at the message layer. -- ``"litellm/anthropic"`` → ``LitellmAnthropicProvider``: direct Anthropic - routing via LiteLLM, always Anthropic, always caching. - -Other prefixes fall through to the SDK's built-in OpenAI / LiteLLM defaults. +Wraps the SDK's :class:`MultiProvider` and registers a custom Anthropic +route so models named ``anthropic/`` go through +:class:`AnthropicCachingLitellmModel` (which injects ``cache_control`` +on the system message). Every other prefix +(``openai/`` / ``gemini/`` / ``openrouter/`` / ``litellm/...``) falls +through to the SDK's built-in litellm routing. References: - PLAYBOOK.md §2.7 - - AUDIT_R3.md C17 (model alias validation; raise UserError on unknown alias) + - AUDIT_R3.md C17 (model alias validation; raise UserError on bad alias) """ from __future__ import annotations from agents.exceptions import UserError -from agents.extensions.models.litellm_model import LitellmModel from agents.models.interface import Model, ModelProvider from agents.models.multi_provider import MultiProvider, MultiProviderMap -from strix.config.config import STRIX_API_BASE from strix.llm.anthropic_cache_wrapper import AnthropicCachingLitellmModel -# Strix-proxy aliases. Each maps the user-facing alias (right of -# ``strix/``) to the canonical provider/model used for capability -# lookups (litellm reads e.g. ``anthropic/claude-sonnet-4-6`` to -# decide on prompt-caching support). -STRIX_MODEL_MAP: dict[str, str] = { - "claude-sonnet-4.6": "anthropic/claude-sonnet-4-6", - "claude-opus-4.6": "anthropic/claude-opus-4-6", - "gpt-5.2": "openai/gpt-5.2", - "gpt-5.1": "openai/gpt-5.1", - "gpt-5.4": "openai/gpt-5.4", - "gemini-3-pro-preview": "gemini/gemini-3-pro-preview", - "gemini-3-flash-preview": "gemini/gemini-3-flash-preview", - "glm-5": "openrouter/z-ai/glm-5", - "glm-4.7": "openrouter/z-ai/glm-4.7", -} +class _AnthropicCachingProvider(ModelProvider): + """Routes ``anthropic/`` aliases through + :class:`AnthropicCachingLitellmModel`. - -def _is_anthropic_canonical(canonical: str) -> bool: - """Return True if ``canonical`` looks like an Anthropic provider/model.""" - c = canonical.lower() - return "anthropic/" in c or "claude" in c - - -class StrixModelProvider(ModelProvider): - """Resolves the ``strix/`` prefix. - - The MultiProvider strips the prefix before calling ``get_model``, so we - receive ``"claude-sonnet-4.6"`` for ``"strix/claude-sonnet-4.6"``. The - ``api_model`` (what we actually send over the wire) is always - ``openai/`` against the Strix proxy (which is OpenAI-compatible). - The ``canonical`` model name is what the upstream provider sees and is - used to decide whether to inject Anthropic prompt caching at the message - layer. - - C17: unknown aliases raise ``UserError`` listing valid options instead of - failing opaquely later in the LLM call. - """ - - def get_model(self, model_name: str | None) -> Model: - if not model_name: - raise UserError("StrixModelProvider requires a non-empty model name.") - if model_name not in STRIX_MODEL_MAP: - valid = ", ".join(sorted(STRIX_MODEL_MAP.keys())) - raise UserError( - f"Unknown Strix model alias 'strix/{model_name}'. Valid aliases: {valid}", - ) - canonical = STRIX_MODEL_MAP[model_name] - api_model = f"openai/{model_name}" - if _is_anthropic_canonical(canonical): - return AnthropicCachingLitellmModel( - model=api_model, - base_url=STRIX_API_BASE, - is_anthropic_override=True, - ) - return LitellmModel(model=api_model, base_url=STRIX_API_BASE) - - -class LitellmAnthropicProvider(ModelProvider): - """Resolves the ``litellm/anthropic`` prefix. - - The MultiProvider strips the matched prefix; for ``litellm/anthropic/...`` - with a registered provider mapping of ``"litellm/anthropic"``, the call - arrives with ``model_name`` like ``"claude-sonnet-4-5-20250929"`` (the - suffix after the prefix). Always wraps in the caching model. + The SDK's ``MultiProvider`` strips the matched prefix before calling + ``get_model``, so we receive bare ``""`` (e.g. + ``"claude-sonnet-4-6"``) and re-prefix with ``anthropic/`` so litellm + routes to the Anthropic API. """ def get_model(self, model_name: str | None) -> Model: if not model_name: raise UserError( - "LitellmAnthropicProvider requires a non-empty model name.", + "Anthropic provider requires a non-empty model name (e.g. 'claude-sonnet-4-6').", ) - # Re-prefix for litellm so it routes to Anthropic. - full = f"anthropic/{model_name}" + full = model_name if model_name.startswith("anthropic/") else f"anthropic/{model_name}" return AnthropicCachingLitellmModel(model=full) def build_multi_provider() -> MultiProvider: - """Build the configured MultiProvider for Strix. + """Build the configured MultiProvider. - Registers Strix-specific prefix routes; OpenAI and other LiteLLM-prefixed - models are handled by the SDK's built-in routing. + Registers the ``anthropic/`` route through our caching wrapper so + prompt caching kicks in; everything else falls through to the SDK's + built-in routing. """ pmap = MultiProviderMap() # type: ignore[no-untyped-call] - pmap.add_provider("strix", StrixModelProvider()) - pmap.add_provider("litellm/anthropic", LitellmAnthropicProvider()) + pmap.add_provider("anthropic", _AnthropicCachingProvider()) return MultiProvider(provider_map=pmap) diff --git a/strix/run_config_factory.py b/strix/run_config_factory.py index ecb9dd9..cd09f47 100644 --- a/strix/run_config_factory.py +++ b/strix/run_config_factory.py @@ -81,7 +81,7 @@ STRIX_DEFAULT_MAX_TURNS = 300 def make_run_config( *, sandbox_session: BaseSandboxSession | None, - model: str = "strix/claude-sonnet-4.6", + model: str = "anthropic/claude-sonnet-4-6", parallel_tool_calls: bool = _PHASE1_PARALLEL_DEFAULT, tool_choice: Literal["auto", "required", "none"] | None = "required", reasoning_effort: Literal["low", "medium", "high"] | None = None, @@ -163,7 +163,7 @@ def make_agent_context( agent_name: str, parent_id: str | None, tracer: Any | None, - model: str = "strix/claude-sonnet-4.6", + model: str = "anthropic/claude-sonnet-4-6", model_settings: ModelSettings | None = None, max_turns: int = 300, is_whitebox: bool = False, diff --git a/strix/tools/agents_graph/tools.py b/strix/tools/agents_graph/tools.py index 318b636..bfb0311 100644 --- a/strix/tools/agents_graph/tools.py +++ b/strix/tools/agents_graph/tools.py @@ -361,7 +361,7 @@ async def create_agent( agent_name=name, parent_id=parent_id, tracer=inner.get("tracer"), - model=inner.get("model", "strix/claude-sonnet-4.6"), + model=inner.get("model", "anthropic/claude-sonnet-4-6"), model_settings=inner.get("model_settings"), max_turns=int(inner.get("max_turns", 300)), is_whitebox=bool(inner.get("is_whitebox", False)), @@ -373,7 +373,7 @@ async def create_agent( child_run_config = make_run_config( sandbox_session=inner.get("sandbox_session"), sandbox_client=inner.get("sandbox_client"), - model=inner.get("model", "strix/claude-sonnet-4.6"), + model=inner.get("model", "anthropic/claude-sonnet-4-6"), model_settings_override=inner.get("model_settings"), ) diff --git a/tests/llm/test_anthropic_cache_wrapper.py b/tests/llm/test_anthropic_cache_wrapper.py index d2f1350..d2759a1 100644 --- a/tests/llm/test_anthropic_cache_wrapper.py +++ b/tests/llm/test_anthropic_cache_wrapper.py @@ -1,16 +1,14 @@ -"""Phase 0 smoke tests for AnthropicCachingLitellmModel.""" +"""Smoke tests for AnthropicCachingLitellmModel.""" from __future__ import annotations -import pytest - from strix.llm.anthropic_cache_wrapper import AnthropicCachingLitellmModel -def _make(model: str, **kwargs: object) -> 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", **kwargs) + return AnthropicCachingLitellmModel(model=model, api_key="test-key") def test_is_anthropic_detects_anthropic_prefix() -> None: @@ -33,18 +31,6 @@ def test_is_anthropic_false_for_gemini() -> None: assert m._is_anthropic() is False -def test_explicit_override_true_wins() -> None: - """For Strix proxy routing where api_model is openai/ but - canonical is Anthropic, the override forces cache injection.""" - m = _make("openai/claude-sonnet-4.6", is_anthropic_override=True) - assert m._is_anthropic() is True - - -def test_explicit_override_false_wins() -> None: - m = _make("anthropic/claude-3-5-sonnet", is_anthropic_override=False) - 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 = [ @@ -86,19 +72,3 @@ def test_patch_skips_non_string_system_content() -> None: def test_patch_handles_empty_list() -> None: m = _make("anthropic/claude-3-5-sonnet") assert m._patch([]) == [] - - -@pytest.mark.parametrize( - "model", - [ - "openai/claude-sonnet-4.6", # Strix proxy with Anthropic underneath - "openai/gpt-5.4", # Strix proxy with OpenAI underneath - ], -) -def test_strix_proxy_routing_with_override(model: str) -> None: - """Strix proxy uses openai/ for the API URL but the underlying - provider varies. The override flag is the source of truth.""" - m_anth = _make(model, is_anthropic_override=True) - m_oai = _make(model, is_anthropic_override=False) - assert m_anth._is_anthropic() is True - assert m_oai._is_anthropic() is False diff --git a/tests/llm/test_multi_provider_setup.py b/tests/llm/test_multi_provider_setup.py index d894678..32d8e3a 100644 --- a/tests/llm/test_multi_provider_setup.py +++ b/tests/llm/test_multi_provider_setup.py @@ -1,64 +1,42 @@ -"""Phase 0 smoke tests for multi_provider_setup.""" +"""Smoke tests for the multi-provider setup.""" from __future__ import annotations import pytest from agents.exceptions import UserError -from agents.extensions.models.litellm_model import LitellmModel -from strix.config.config import STRIX_API_BASE from strix.llm.anthropic_cache_wrapper import AnthropicCachingLitellmModel from strix.llm.multi_provider_setup import ( - LitellmAnthropicProvider, - StrixModelProvider, + _AnthropicCachingProvider, build_multi_provider, ) -def test_strix_provider_resolves_anthropic_alias_with_override() -> None: - provider = StrixModelProvider() - model = provider.get_model("claude-sonnet-4.6") +def test_anthropic_provider_wraps_in_caching_model() -> None: + provider = _AnthropicCachingProvider() + model = provider.get_model("claude-sonnet-4-6") assert isinstance(model, AnthropicCachingLitellmModel) - # Goes via Strix proxy as openai/, but is_anthropic still True. - assert model.model == "openai/claude-sonnet-4.6" - assert str(model.base_url) == STRIX_API_BASE + # The provider re-prefixes with ``anthropic/`` so litellm routes correctly. + assert model.model == "anthropic/claude-sonnet-4-6" assert model._is_anthropic() is True -def test_strix_provider_resolves_openai_alias_without_override() -> None: - provider = StrixModelProvider() - model = provider.get_model("gpt-5.4") - # Plain LitellmModel, NOT the caching subclass. - assert isinstance(model, LitellmModel) - assert not isinstance(model, AnthropicCachingLitellmModel) - assert model.model == "openai/gpt-5.4" +def test_anthropic_provider_preserves_existing_anthropic_prefix() -> None: + """If the alias already carries ``anthropic/``, don't double-prefix.""" + provider = _AnthropicCachingProvider() + model = provider.get_model("anthropic/claude-3-5-sonnet-20241022") + assert model.model == "anthropic/claude-3-5-sonnet-20241022" -def test_strix_provider_unknown_alias_raises_user_error() -> None: - """C17 (AUDIT_R3): unknown alias must surface a clear error with valid options.""" - provider = StrixModelProvider() - with pytest.raises(UserError, match="Unknown Strix model alias"): - provider.get_model("typo-model-name") - - -def test_strix_provider_empty_name_raises() -> None: - provider = StrixModelProvider() +def test_anthropic_provider_empty_name_raises() -> None: + provider = _AnthropicCachingProvider() with pytest.raises(UserError, match="non-empty"): provider.get_model(None) -def test_litellm_anthropic_provider_wraps_in_caching_model() -> None: - provider = LitellmAnthropicProvider() - model = provider.get_model("claude-3-5-sonnet-20241022") - assert isinstance(model, AnthropicCachingLitellmModel) - assert model.model == "anthropic/claude-3-5-sonnet-20241022" - assert model._is_anthropic() is True - - -def test_build_multi_provider_registers_strix_prefix() -> None: +def test_build_multi_provider_routes_anthropic_through_caching_wrapper() -> None: + """The configured MultiProvider should hit our caching wrapper for the + ``anthropic/`` prefix.""" mp = build_multi_provider() - # The MultiProvider stores the map; the easiest check is that resolving - # "strix/claude-sonnet-4.6" goes through StrixModelProvider. - model = mp.get_model("strix/claude-sonnet-4.6") + model = mp.get_model("anthropic/claude-sonnet-4-6") assert isinstance(model, AnthropicCachingLitellmModel) - assert model.model == "openai/claude-sonnet-4.6" diff --git a/tests/test_run_config_factory.py b/tests/test_run_config_factory.py index 6dcb7f5..d3fc903 100644 --- a/tests/test_run_config_factory.py +++ b/tests/test_run_config_factory.py @@ -170,7 +170,7 @@ def test_sandbox_config_omitted_when_no_session() -> None: def test_model_default_is_strix_claude() -> None: """Production default per AUDIT/PLAYBOOK convention.""" cfg = make_run_config(sandbox_session=None) - assert cfg.model == "strix/claude-sonnet-4.6" + assert cfg.model == "anthropic/claude-sonnet-4-6" def test_multi_provider_is_built() -> None: diff --git a/tests/tools/test_graph_tools.py b/tests/tools/test_graph_tools.py index 5a30a2b..1b89d82 100644 --- a/tests/tools/test_graph_tools.py +++ b/tests/tools/test_graph_tools.py @@ -281,7 +281,7 @@ async def test_create_agent_spawns_and_registers_child() -> None: "tool_server_host_port": 12345, "caido_host_port": None, "tracer": None, - "model": "strix/claude-sonnet-4.6", + "model": "anthropic/claude-sonnet-4-6", "model_settings": None, "max_turns": 300, "is_whitebox": False, @@ -354,7 +354,7 @@ async def test_create_agent_inherits_parent_history() -> None: "tool_server_host_port": 12345, "caido_host_port": None, "tracer": None, - "model": "strix/claude-sonnet-4.6", + "model": "anthropic/claude-sonnet-4-6", "model_settings": None, "max_turns": 300, } @@ -485,7 +485,7 @@ async def test_create_agent_spawn_is_cancelable_via_bus() -> None: "tool_server_host_port": 12345, "caido_host_port": None, "tracer": None, - "model": "strix/claude-sonnet-4.6", + "model": "anthropic/claude-sonnet-4-6", "model_settings": None, "max_turns": 300, } diff --git a/tests/tools/test_tool_registration_modes.py b/tests/tools/test_tool_registration_modes.py index ce15a46..6812e8e 100644 --- a/tests/tools/test_tool_registration_modes.py +++ b/tests/tools/test_tool_registration_modes.py @@ -96,4 +96,7 @@ def test_load_skill_import_does_not_register_create_agent_in_sandbox( names_after = set(registry.get_tool_names()) assert "create_agent" not in names_after - assert result["success"] is False + # 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"]