TDR-004: OrchestrationService Pre-Builds Dependencies the Factory Could Own¶
Description¶
OrchestrationService receives conversation_context_repository and builds domain_agent_registry in its __init__, then passes both to create_global_supervisor(). These dependencies are only used for building the supervisor — no other method in OrchestrationService references them.
The create_global_supervisor factory accepts either pre-built dependencies OR raw services (memory_service, rag_service) and builds them internally. This "either/or" interface exists because OrchestrationService does prework the factory could do itself.
Current State¶
FastAPI DI → builds conversation_context_repository
→ passes to OrchestrationService
→ OrchestrationService stores it
→ OrchestrationService passes it to factory
→ factory passes it to supervisor constructor
Ideal State¶
FastAPI DI → passes memory_service + rag_service to OrchestrationService
→ OrchestrationService passes raw services to factory
→ factory builds conversation_context_repository + domain_agent_registry
→ factory passes them to supervisor constructor
Why It Matters¶
- Duplicated wiring logic — the factory knows how to build these dependencies, but
OrchestrationServicedoes it too - Factory's "either/or" interface is confusing — it accepts pre-built OR raw services, which is unusual
- DI layer complexity —
get_conversation_context_repositorydependency in FastAPI exists only to pass through to the supervisor
Why We Deferred¶
- Changing
OrchestrationService.__init__signature requires updating the FastAPI DI layer (services_deps.py) and the voice event handler (voice_event_handler.py) - The current approach works correctly — the toggle works, production uses the factory
- The v2 evolution will likely simplify
OrchestrationServicesignificantly, making this cleanup natural
Cleanup Plan¶
When evolving the v2 supervisor (PR 2+):
1. Remove conversation_context_repository from OrchestrationService.__init__ params
2. Add memory_service param instead (or get it from DI)
3. Remove domain_agent_registry construction from __init__
4. Pass memory_service + rag_service to the factory (raw services path)
5. Remove the "either/or" from the factory — only accept raw services
6. Update services_deps.py and voice_event_handler.py
Impact¶
- Low risk — no behavioral change
- ~30 lines changed across 3 files
- Cleaner separation: factory owns ALL supervisor construction,
OrchestrationServiceowns orchestration
Files Affected¶
swisper/services/orchestration.py— remove pre-built deps, pass raw servicesswisper/services/global_supervisor_factory.py— simplify to raw services onlyswisper/services/services_deps.py— removeget_conversation_context_repositorydep, addget_memory_serviceswisper/services/voice/voice_event_handler.py— same change