Skip to content

Orchestrator Decomposition

Overview

The AgentOrchestrator (~4,593 LOC) is a facade coordinating extracted components, decomposed from a larger monolith through multiple refactoring phases. Ongoing work continues to shrink the facade.

Component Topology

AgentOrchestrator (~4,593 LOC facade)
├── CallbackCoordinator (96 LOC)    ← tool/streaming lifecycle callbacks
│   ├── MetricsCoordinator          ← metrics collection + RL reward signals
│   ├── ToolCoordinator             ← tool completion handling + file tracking
│   └── UsageAnalytics              ← session analytics
├── OrchestratorPropertyFacade (496 LOC) ← 37 property definitions
│   ├── Simple accessors (17)       ← conversation_controller, tool_pipeline, etc.
│   ├── Lazy coordinators (8)       ← protocol_adapter, execution_coordinator, etc.
│   ├── Recovery properties (2)     ← recovery_handler, recovery_integration
│   └── Session state (10)          ← tool_calls_used, observed_files, etc. (with setters)
├── InitializationPhaseManager (153 LOC) ← 9-phase structured init
├── SessionStateAccessor            ← session state delegation to SessionStateManager
├── Runtime Boundaries (12 modules in victor/agent/runtime/)
│   ├── ProviderRuntime             ← provider coordinator + ProviderPool (feature-flagged)
│   ├── MetricsRuntime              ← usage logger, streaming metrics, cost tracker
│   ├── WorkflowRuntime             ← lazy workflow registry
│   ├── MemoryRuntime               ← memory manager + conversation embedding store
│   ├── ResilienceRuntime           ← recovery handler + integration
│   ├── CoordinationRuntime         ← recovery/chunk/planner/task coordinators
│   ├── InteractionRuntime          ← service-first chat/tool/session surfaces + compat shims
│   └── ServicesRuntime             ← DI service layer (Strangler Fig pattern)
├── 15 Coordinators (victor/agent/coordinators/)
│   ├── ExecutionCoordinator        ← agentic loop execution
│   ├── SyncChatCoordinator         ← deprecated non-streaming compatibility shim
│   ├── StreamingChatCoordinator    ← deprecated streaming compatibility shim
│   ├── UnifiedChatCoordinator      ← deprecated sync/streaming facade shim
│   ├── ProtocolAdapter             ← DIP compliance adapter
│   ├── MetricsCoordinator          ← centralized metrics
│   ├── SafetyCoordinator           ← safety rule evaluation
│   ├── ConversationCoordinator     ← conversation management
│   └── ... (7 more)
└── Vertical Integration
    ├── VerticalContext              ← unified vertical state container
    ├── VerticalIntegrationAdapter   ← single-source vertical method delegation
    └── ModeWorkflowTeamCoordinator ← intelligent team/workflow suggestions (lazy)

Extraction Summary

Component LOC in Orchestrator LOC Saved Phase
OrchestratorPropertyFacade 496 (in own file) -574 from orchestrator 3B
CallbackCoordinator 96 (in own file) -40 3A
SessionStateAccessor — (prior work) -100
InitializationPhaseManager 153 (in own file) structural 3C

Property Installation Pattern

Properties are installed as real class-level property descriptors via install_properties() at module load time. This preserves unittest.mock.patch.object compatibility:

# orchestrator_properties.py
_PROPERTY_REGISTRY = {
    "conversation_controller": (_conversation_controller_get, None),
    "tool_calls_used": (_tool_calls_used_get, _tool_calls_used_set),
    # ... 37 total
}

def install_properties(cls):
    for name, (getter, setter) in _PROPERTY_REGISTRY.items():
        setattr(cls, name, property(getter, setter, doc=getter.__doc__))

# orchestrator.py (bottom of file)
install_properties(AgentOrchestrator)

All property access patterns are preserved:

orchestrator.conversation_controller   # simple accessor
orchestrator.protocol_adapter          # lazy-inits on first access
orchestrator.tool_calls_used = 5       # setter works via property

Current chat/runtime note:
- Canonical chat entry points are ChatService and ServiceStreamingRuntime
- Deprecated chat coordinators remain only as compatibility import/runtime shims

Extension Loader Decomposition

The VerticalExtensionLoader (1,897 LOC) delegates to three extracted components:

Component LOC Purpose
ExtensionModuleResolver 259 Module path resolution, availability checking, class name generation
ExtensionCacheManager 167 Thread-safe namespaced caching with get_or_create/invalidate
ExtensionLoaderPressureMonitor ~150 Metrics counters, queue pressure thresholds, cooldown logic
CapabilityNegotiator 111 Validates ExtensionManifest during vertical activation

Extension Loading Flow

VerticalLoader.load(name)
  → VerticalRegistry.get(name) or entry point discovery
  → VerticalRuntimeAdapter.as_runtime_vertical_class()
  → _negotiate_manifest() → CapabilityNegotiator.negotiate(manifest)
  → _activate() → set as active vertical

Module Resolution Flow

get_safety_extension() / get_middleware() / etc.
  → _find_available_candidates(suffix)
      → _module_resolver.resolve_candidates(vertical_name, suffix)
      → filter by _module_resolver.is_available(path)
  → _resolve_factory_extension(key, suffix)
      → _get_extension_factory(key, module_path)
          → _module_resolver.auto_generate_class_name()
          → _module_resolver.load_attribute()
      → _cache_manager.get_or_create(namespace, key, factory)

ProviderPool

Single ProviderPool class in victor/providers/factory.py (duplicate removed). Wired into ProviderRuntimeComponents via use_provider_pooling feature flag in FeatureFlagSettings. Pool cleanup runs during graceful_shutdown().