VibecoderMcSwaggins's picture
fix(arch): End-to-end BYOK support for unified architecture
915b009
raw
history blame
2.97 kB
"""Factory for creating orchestrators.
Implements the Factory Pattern (GoF) for creating the appropriate
orchestrator based on configuration and available credentials.
Design Principles:
- Open/Closed: Easy to add new orchestrator types without modifying existing code
- Dependency Inversion: Returns protocol-compatible objects, not concrete types
- Single Responsibility: Only handles orchestrator creation logic
"""
from typing import TYPE_CHECKING, Literal
import structlog
from src.config.domain import ResearchDomain
from src.orchestrators.base import (
JudgeHandlerProtocol,
OrchestratorProtocol,
SearchHandlerProtocol,
)
from src.utils.config import settings
from src.utils.models import OrchestratorConfig
if TYPE_CHECKING:
from src.orchestrators.advanced import AdvancedOrchestrator
logger = structlog.get_logger()
def _get_advanced_orchestrator_class() -> type["AdvancedOrchestrator"]:
"""Import AdvancedOrchestrator lazily."""
try:
from src.orchestrators.advanced import AdvancedOrchestrator
return AdvancedOrchestrator
except ImportError as e:
logger.error("Failed to import AdvancedOrchestrator", error=str(e))
# With unified architecture, we should never fail here unless installation is broken
raise
def create_orchestrator(
search_handler: SearchHandlerProtocol | None = None,
judge_handler: JudgeHandlerProtocol | None = None,
config: OrchestratorConfig | None = None,
mode: Literal["simple", "magentic", "advanced", "hierarchical"] | None = None,
api_key: str | None = None,
domain: ResearchDomain | str | None = None,
) -> OrchestratorProtocol:
"""
Create an orchestrator instance.
Defaults to AdvancedOrchestrator (Unified Architecture).
Simple Mode is deprecated and mapped to Advanced Mode.
"""
effective_config = config or OrchestratorConfig()
effective_mode = _determine_mode(mode)
logger.info("Creating orchestrator", mode=effective_mode, domain=domain)
if effective_mode == "hierarchical":
from src.orchestrators.hierarchical import HierarchicalOrchestrator
return HierarchicalOrchestrator(config=effective_config, domain=domain, api_key=api_key)
# Default: Advanced Mode (Unified)
# Handles both Paid (OpenAI) and Free (HuggingFace) tiers
orchestrator_cls = _get_advanced_orchestrator_class()
return orchestrator_cls(
max_rounds=settings.advanced_max_rounds,
api_key=api_key,
domain=domain,
)
def _determine_mode(explicit_mode: str | None) -> str:
"""Determine which mode to use.
Args:
explicit_mode: Mode explicitly requested by caller
Returns:
Effective mode string: "advanced" (default) or "hierarchical"
"""
if explicit_mode == "hierarchical":
return "hierarchical"
# "simple" is deprecated -> upgrade to "advanced"
# "magentic" is alias for "advanced"
return "advanced"