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>
This commit is contained in:
0xallam
2026-04-25 09:37:14 -07:00
parent d8881498ee
commit af42499b95
13 changed files with 69 additions and 223 deletions
+2 -2
View File
@@ -184,8 +184,8 @@ def build_strix_agent(
instructions=instructions, instructions=instructions,
tools=tools, tools=tools,
tool_use_behavior=StopAtTools(stop_at_tool_names=list(stop_at)), tool_use_behavior=StopAtTools(stop_at_tool_names=list(stop_at)),
# model=None so ``RunConfig.model`` (e.g. ``strix/claude-sonnet-4.6``) # model=None so ``RunConfig.model`` drives provider selection
# routes through MultiProvider rather than the SDK's default. # via :func:`build_multi_provider` rather than the SDK's default.
model=None, model=None,
) )
+11 -19
View File
@@ -5,9 +5,6 @@ from pathlib import Path
from typing import Any, ClassVar from typing import Any, ClassVar
STRIX_API_BASE = "https://models.strix.ai/api/v1"
class Config: class Config:
"""Configuration Manager for Strix.""" """Configuration Manager for Strix."""
@@ -197,28 +194,23 @@ def save_current_config() -> bool:
def resolve_llm_config() -> tuple[str | None, str | None, str | None]: 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: Returns ``(model_name, api_key, api_base)``. ``api_base`` falls back
tuple: (model_name, api_key, api_base) through the ``LLM_API_BASE`` / ``OPENAI_API_BASE`` /
- model_name: Original model name (strix/ prefix preserved for display) ``LITELLM_BASE_URL`` / ``OLLAMA_API_BASE`` env chain so the user can
- api_key: LLM API key point at any OpenAI-compatible endpoint without changing the code.
- api_base: API base URL (auto-set to STRIX_API_BASE for strix/ models)
""" """
model = Config.get("strix_llm") model = Config.get("strix_llm")
if not model: if not model:
return None, None, None return None, None, None
api_key = Config.get("llm_api_key") api_key = Config.get("llm_api_key")
api_base: str | None = (
if model.startswith("strix/"): Config.get("llm_api_base")
api_base: str | None = STRIX_API_BASE or Config.get("openai_api_base")
else: or Config.get("litellm_base_url")
api_base = ( or Config.get("ollama_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")
)
return model, api_key, api_base return model, api_key, api_base
+1 -10
View File
@@ -20,7 +20,6 @@ from rich.text import Text
from strix.config import Config, apply_saved_config, save_current_config from strix.config import Config, apply_saved_config, save_current_config
from strix.config.config import resolve_llm_config from strix.config.config import resolve_llm_config
from strix.llm.multi_provider_setup import STRIX_MODEL_MAP
apply_saved_config() apply_saved_config()
@@ -58,12 +57,10 @@ def validate_environment() -> None:
missing_optional_vars = [] missing_optional_vars = []
strix_llm = Config.get("strix_llm") strix_llm = Config.get("strix_llm")
uses_strix_models = strix_llm and strix_llm.startswith("strix/")
if not strix_llm: if not strix_llm:
missing_required_vars.append("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("llm_api_base"),
Config.get("openai_api_base"), Config.get("openai_api_base"),
@@ -211,13 +208,7 @@ async def warm_up_llm() -> None:
try: try:
model_name, api_key, api_base = resolve_llm_config() model_name, api_key, api_base = resolve_llm_config()
# ``strix/<alias>`` is routed through the Strix proxy (OpenAI-compatible);
# everything else is sent as-is.
litellm_model: str | None = model_name 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 = [ test_messages = [
{"role": "system", "content": "You are a helpful assistant."}, {"role": "system", "content": "You are a helpful assistant."},
-19
View File
@@ -30,28 +30,9 @@ class AnthropicCachingLitellmModel(LitellmModel):
Detection: case-insensitive substring match on ``"anthropic/"`` or Detection: case-insensitive substring match on ``"anthropic/"`` or
``"claude"`` against the model name. ``"claude"`` against the model name.
For Strix proxy routing where the API model is ``openai/<base>`` 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: def _is_anthropic(self) -> bool:
if self._is_anthropic_override is not None:
return self._is_anthropic_override
m = (self.model or "").lower() m = (self.model or "").lower()
return "anthropic/" in m or "claude" in m return "anthropic/" in m or "claude" in m
-5
View File
@@ -6,7 +6,6 @@ from typing import Any
import litellm import litellm
from strix.config.config import resolve_llm_config from strix.config.config import resolve_llm_config
from strix.llm.multi_provider_setup import STRIX_MODEL_MAP
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -158,10 +157,6 @@ def check_duplicate(
model_name, api_key, api_base = resolve_llm_config() model_name, api_key, api_base = resolve_llm_config()
litellm_model: str | None = model_name 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 = [ messages = [
{"role": "system", "content": DEDUPE_SYSTEM_PROMPT}, {"role": "system", "content": DEDUPE_SYSTEM_PROMPT},
+22 -86
View File
@@ -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"`` Wraps the SDK's :class:`MultiProvider` and registers a custom Anthropic
by stripping the prefix (``"strix"``) and dispatching to a registered route so models named ``anthropic/<model>`` go through
``ModelProvider`` keyed on that prefix. We register two custom providers: :class:`AnthropicCachingLitellmModel` (which injects ``cache_control``
on the system message). Every other prefix
- ``"strix"`` ``StrixModelProvider``: aliases the short name to a Strix-proxy (``openai/`` / ``gemini/`` / ``openrouter/`` / ``litellm/...``) falls
``openai/<base>`` model URL, but knows whether the underlying provider is through to the SDK's built-in litellm routing.
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.
References: References:
- PLAYBOOK.md §2.7 - 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 __future__ import annotations
from agents.exceptions import UserError from agents.exceptions import UserError
from agents.extensions.models.litellm_model import LitellmModel
from agents.models.interface import Model, ModelProvider from agents.models.interface import Model, ModelProvider
from agents.models.multi_provider import MultiProvider, MultiProviderMap from agents.models.multi_provider import MultiProvider, MultiProviderMap
from strix.config.config import STRIX_API_BASE
from strix.llm.anthropic_cache_wrapper import AnthropicCachingLitellmModel from strix.llm.anthropic_cache_wrapper import AnthropicCachingLitellmModel
# Strix-proxy aliases. Each maps the user-facing alias (right of class _AnthropicCachingProvider(ModelProvider):
# ``strix/``) to the canonical provider/model used for capability """Routes ``anthropic/<model>`` aliases through
# lookups (litellm reads e.g. ``anthropic/claude-sonnet-4-6`` to :class:`AnthropicCachingLitellmModel`.
# 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",
}
The SDK's ``MultiProvider`` strips the matched prefix before calling
def _is_anthropic_canonical(canonical: str) -> bool: ``get_model``, so we receive bare ``"<model>"`` (e.g.
"""Return True if ``canonical`` looks like an Anthropic provider/model.""" ``"claude-sonnet-4-6"``) and re-prefix with ``anthropic/`` so litellm
c = canonical.lower() routes to the Anthropic API.
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/<base>`` 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.
""" """
def get_model(self, model_name: str | None) -> Model: def get_model(self, model_name: str | None) -> Model:
if not model_name: if not model_name:
raise UserError( 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 = model_name if model_name.startswith("anthropic/") else f"anthropic/{model_name}"
full = f"anthropic/{model_name}"
return AnthropicCachingLitellmModel(model=full) return AnthropicCachingLitellmModel(model=full)
def build_multi_provider() -> MultiProvider: 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 Registers the ``anthropic/`` route through our caching wrapper so
models are handled by the SDK's built-in routing. prompt caching kicks in; everything else falls through to the SDK's
built-in routing.
""" """
pmap = MultiProviderMap() # type: ignore[no-untyped-call] pmap = MultiProviderMap() # type: ignore[no-untyped-call]
pmap.add_provider("strix", StrixModelProvider()) pmap.add_provider("anthropic", _AnthropicCachingProvider())
pmap.add_provider("litellm/anthropic", LitellmAnthropicProvider())
return MultiProvider(provider_map=pmap) return MultiProvider(provider_map=pmap)
+2 -2
View File
@@ -81,7 +81,7 @@ STRIX_DEFAULT_MAX_TURNS = 300
def make_run_config( def make_run_config(
*, *,
sandbox_session: BaseSandboxSession | None, 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, parallel_tool_calls: bool = _PHASE1_PARALLEL_DEFAULT,
tool_choice: Literal["auto", "required", "none"] | None = "required", tool_choice: Literal["auto", "required", "none"] | None = "required",
reasoning_effort: Literal["low", "medium", "high"] | None = None, reasoning_effort: Literal["low", "medium", "high"] | None = None,
@@ -163,7 +163,7 @@ def make_agent_context(
agent_name: str, agent_name: str,
parent_id: str | None, parent_id: str | None,
tracer: Any | None, tracer: Any | None,
model: str = "strix/claude-sonnet-4.6", model: str = "anthropic/claude-sonnet-4-6",
model_settings: ModelSettings | None = None, model_settings: ModelSettings | None = None,
max_turns: int = 300, max_turns: int = 300,
is_whitebox: bool = False, is_whitebox: bool = False,
+2 -2
View File
@@ -361,7 +361,7 @@ async def create_agent(
agent_name=name, agent_name=name,
parent_id=parent_id, parent_id=parent_id,
tracer=inner.get("tracer"), 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"), model_settings=inner.get("model_settings"),
max_turns=int(inner.get("max_turns", 300)), max_turns=int(inner.get("max_turns", 300)),
is_whitebox=bool(inner.get("is_whitebox", False)), is_whitebox=bool(inner.get("is_whitebox", False)),
@@ -373,7 +373,7 @@ async def create_agent(
child_run_config = make_run_config( child_run_config = make_run_config(
sandbox_session=inner.get("sandbox_session"), sandbox_session=inner.get("sandbox_session"),
sandbox_client=inner.get("sandbox_client"), 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"), model_settings_override=inner.get("model_settings"),
) )
+3 -33
View File
@@ -1,16 +1,14 @@
"""Phase 0 smoke tests for AnthropicCachingLitellmModel.""" """Smoke tests for AnthropicCachingLitellmModel."""
from __future__ import annotations from __future__ import annotations
import pytest
from strix.llm.anthropic_cache_wrapper import AnthropicCachingLitellmModel 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 # ``LitellmModel.__init__`` only validates that model is a string; we
# don't need a real API key for in-memory ``_patch`` testing. # 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: 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 assert m._is_anthropic() is False
def test_explicit_override_true_wins() -> None:
"""For Strix proxy routing where api_model is openai/<base> 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: def test_patch_anthropic_adds_cache_control_to_system() -> None:
m = _make("anthropic/claude-3-5-sonnet") m = _make("anthropic/claude-3-5-sonnet")
items: list = [ items: list = [
@@ -86,19 +72,3 @@ def test_patch_skips_non_string_system_content() -> None:
def test_patch_handles_empty_list() -> None: def test_patch_handles_empty_list() -> None:
m = _make("anthropic/claude-3-5-sonnet") m = _make("anthropic/claude-3-5-sonnet")
assert m._patch([]) == [] 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/<base> 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
+18 -40
View File
@@ -1,64 +1,42 @@
"""Phase 0 smoke tests for multi_provider_setup.""" """Smoke tests for the multi-provider setup."""
from __future__ import annotations from __future__ import annotations
import pytest import pytest
from agents.exceptions import UserError 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.anthropic_cache_wrapper import AnthropicCachingLitellmModel
from strix.llm.multi_provider_setup import ( from strix.llm.multi_provider_setup import (
LitellmAnthropicProvider, _AnthropicCachingProvider,
StrixModelProvider,
build_multi_provider, build_multi_provider,
) )
def test_strix_provider_resolves_anthropic_alias_with_override() -> None: def test_anthropic_provider_wraps_in_caching_model() -> None:
provider = StrixModelProvider() provider = _AnthropicCachingProvider()
model = provider.get_model("claude-sonnet-4.6") model = provider.get_model("claude-sonnet-4-6")
assert isinstance(model, AnthropicCachingLitellmModel) assert isinstance(model, AnthropicCachingLitellmModel)
# Goes via Strix proxy as openai/<base>, but is_anthropic still True. # The provider re-prefixes with ``anthropic/`` so litellm routes correctly.
assert model.model == "openai/claude-sonnet-4.6" assert model.model == "anthropic/claude-sonnet-4-6"
assert str(model.base_url) == STRIX_API_BASE
assert model._is_anthropic() is True assert model._is_anthropic() is True
def test_strix_provider_resolves_openai_alias_without_override() -> None: def test_anthropic_provider_preserves_existing_anthropic_prefix() -> None:
provider = StrixModelProvider() """If the alias already carries ``anthropic/``, don't double-prefix."""
model = provider.get_model("gpt-5.4") provider = _AnthropicCachingProvider()
# Plain LitellmModel, NOT the caching subclass. model = provider.get_model("anthropic/claude-3-5-sonnet-20241022")
assert isinstance(model, LitellmModel) assert model.model == "anthropic/claude-3-5-sonnet-20241022"
assert not isinstance(model, AnthropicCachingLitellmModel)
assert model.model == "openai/gpt-5.4"
def test_strix_provider_unknown_alias_raises_user_error() -> None: def test_anthropic_provider_empty_name_raises() -> None:
"""C17 (AUDIT_R3): unknown alias must surface a clear error with valid options.""" provider = _AnthropicCachingProvider()
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()
with pytest.raises(UserError, match="non-empty"): with pytest.raises(UserError, match="non-empty"):
provider.get_model(None) provider.get_model(None)
def test_litellm_anthropic_provider_wraps_in_caching_model() -> None: def test_build_multi_provider_routes_anthropic_through_caching_wrapper() -> None:
provider = LitellmAnthropicProvider() """The configured MultiProvider should hit our caching wrapper for the
model = provider.get_model("claude-3-5-sonnet-20241022") ``anthropic/`` prefix."""
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:
mp = build_multi_provider() mp = build_multi_provider()
# The MultiProvider stores the map; the easiest check is that resolving model = mp.get_model("anthropic/claude-sonnet-4-6")
# "strix/claude-sonnet-4.6" goes through StrixModelProvider.
model = mp.get_model("strix/claude-sonnet-4.6")
assert isinstance(model, AnthropicCachingLitellmModel) assert isinstance(model, AnthropicCachingLitellmModel)
assert model.model == "openai/claude-sonnet-4.6"
+1 -1
View File
@@ -170,7 +170,7 @@ def test_sandbox_config_omitted_when_no_session() -> None:
def test_model_default_is_strix_claude() -> None: def test_model_default_is_strix_claude() -> None:
"""Production default per AUDIT/PLAYBOOK convention.""" """Production default per AUDIT/PLAYBOOK convention."""
cfg = make_run_config(sandbox_session=None) 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: def test_multi_provider_is_built() -> None:
+3 -3
View File
@@ -281,7 +281,7 @@ async def test_create_agent_spawns_and_registers_child() -> None:
"tool_server_host_port": 12345, "tool_server_host_port": 12345,
"caido_host_port": None, "caido_host_port": None,
"tracer": None, "tracer": None,
"model": "strix/claude-sonnet-4.6", "model": "anthropic/claude-sonnet-4-6",
"model_settings": None, "model_settings": None,
"max_turns": 300, "max_turns": 300,
"is_whitebox": False, "is_whitebox": False,
@@ -354,7 +354,7 @@ async def test_create_agent_inherits_parent_history() -> None:
"tool_server_host_port": 12345, "tool_server_host_port": 12345,
"caido_host_port": None, "caido_host_port": None,
"tracer": None, "tracer": None,
"model": "strix/claude-sonnet-4.6", "model": "anthropic/claude-sonnet-4-6",
"model_settings": None, "model_settings": None,
"max_turns": 300, "max_turns": 300,
} }
@@ -485,7 +485,7 @@ async def test_create_agent_spawn_is_cancelable_via_bus() -> None:
"tool_server_host_port": 12345, "tool_server_host_port": 12345,
"caido_host_port": None, "caido_host_port": None,
"tracer": None, "tracer": None,
"model": "strix/claude-sonnet-4.6", "model": "anthropic/claude-sonnet-4-6",
"model_settings": None, "model_settings": None,
"max_turns": 300, "max_turns": 300,
} }
+4 -1
View File
@@ -96,4 +96,7 @@ def test_load_skill_import_does_not_register_create_agent_in_sandbox(
names_after = set(registry.get_tool_names()) names_after = set(registry.get_tool_names())
assert "create_agent" not in names_after 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"]