strix/strix/llm/multi_provider_setup.py
0xallam 4d2fa45db6 refactor: scrub migration scars, dead code, and unused helpers
- Strip PLAYBOOK / AUDIT / Phase-N / C-numbered references from
  module docstrings across 16 files; rename
  ``_PHASE1_PARALLEL_DEFAULT`` → ``_PARALLEL_TOOL_CALLS_DEFAULT``.
- Delete unused exception classes: ``SandboxInitializationError``,
  ``ImplementedInClientSideOnlyError``.
- Delete the no-op ``on_handoff`` hook (we don't use SDK handoffs).
- Delete the unreachable backward-compat tab-delimited fallback in
  ``_parse_git_diff_output``.
- Delete orphaned ``strix/tools/load_skill/`` (dir contained only a
  pycache) and stale pycache files.
- Rewrite ``strix/skills/__init__.py``: 168 → 56 LoC. Drop seven
  helper functions (``get_available_skills``, ``get_all_skill_names``,
  ``validate_skill_names``, ``parse_skill_list``,
  ``validate_requested_skills``, ``generate_skills_description``,
  ``_get_all_categories``) — none had external callers; only
  ``load_skills`` is used.
- Drop the stale ``strix/agents/sdk_factory.py`` per-file ruff ignore
  (file no longer exists).
2026-04-25 12:05:24 -07:00

48 lines
1.8 KiB
Python

"""Multi-provider routing setup.
Wraps the SDK's :class:`MultiProvider` and registers a custom Anthropic
route so models named ``anthropic/<model>`` 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.
"""
from __future__ import annotations
from agents.exceptions import UserError
from agents.models.interface import Model, ModelProvider
from agents.models.multi_provider import MultiProvider, MultiProviderMap
from strix.llm.anthropic_cache_wrapper import AnthropicCachingLitellmModel
class _AnthropicCachingProvider(ModelProvider):
"""Routes ``anthropic/<model>`` aliases through
:class:`AnthropicCachingLitellmModel`.
The SDK's ``MultiProvider`` strips the matched prefix before calling
``get_model``, so we receive bare ``"<model>"`` (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(
"Anthropic provider requires a non-empty model name (e.g. 'claude-sonnet-4-6').",
)
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.
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("anthropic", _AnthropicCachingProvider())
return MultiProvider(provider_map=pmap)