Coverage for src/lilbee/providers/factory.py: 100%

15 statements  

« prev     ^ index     » next       coverage.py v7.15.2, created at 2026-09-17 10:02 +0000

1"""Factory for creating LLM provider instances.""" 

2 

3from __future__ import annotations 

4 

5from typing import TYPE_CHECKING, assert_never 

6 

7from lilbee.core.config.enums import LlmProvider 

8from lilbee.providers.base import ProviderError 

9 

10if TYPE_CHECKING: 

11 from lilbee.core.config import Config 

12 from lilbee.providers.base import LLMProvider 

13 

14 

15def create_provider(config: Config, *, hold_warm: bool = False) -> LLMProvider: 

16 """Create a new LLM provider instance from the given config. 

17 

18 *hold_warm* marks the provider as serving an interactive session, so a local 

19 fleet bound to that session keeps its weights resident instead of 

20 idle-unloading for as long as the session owns the process (a keep-warm fleet 

21 outlives it and keeps its idle window). Irrelevant to a remote provider, which 

22 has no local engine to hold. 

23 """ 

24 match config.llm_provider: 

25 case LlmProvider.AUTO: 

26 # heavy: routing_provider eagerly imports litellm_sdk (>50ms; litellm fanout) 

27 from lilbee.providers.routing_provider import RoutingProvider 

28 

29 return RoutingProvider(hold_warm=hold_warm) 

30 

31 case LlmProvider.REMOTE: 

32 # THIS is the swap line: the single import that changes when 

33 # migrating to a different SDK. Replace LitellmSdkBackend here 

34 # with the new adapter and the rest of lilbee is untouched. 

35 # heavy: litellm_sdk loads litellm provider fanout (>50ms) 

36 from lilbee.providers.litellm_sdk import LitellmSdkBackend 

37 from lilbee.providers.sdk_llm_provider import SdkLLMProvider 

38 

39 backend = LitellmSdkBackend() 

40 if not backend.available(): 

41 raise ProviderError( 

42 "SDK backend adapter is not installed. Install with: " 

43 "pip install 'lilbee[litellm]'" 

44 ) 

45 return SdkLLMProvider( 

46 backend, 

47 api_key=config.llm_api_key, 

48 ) # pragma: no cover 

49 

50 assert_never(config.llm_provider) # pragma: no cover