File size: 2,002 Bytes
2415446
 
 
a1bab2d
2415446
 
 
 
 
 
a1bab2d
 
2415446
 
 
 
 
 
 
 
a1bab2d
 
2415446
 
 
a1bab2d
2415446
 
 
 
 
 
 
 
a1bab2d
 
 
2415446
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
"""One closable generation of lazily constructed provider clients."""

import asyncio
from collections.abc import Callable, MutableMapping

from free_claude_code.config.settings import Settings
from free_claude_code.providers.base import BaseProvider

from .factory import create_provider

ProviderConstructor = Callable[[str, Settings], BaseProvider]


class ProviderRuntime:
    """Own provider instances for one immutable settings snapshot."""

    def __init__(
        self,
        settings: Settings,
        providers: MutableMapping[str, BaseProvider] | None = None,
        *,
        provider_constructor: ProviderConstructor = create_provider,
    ) -> None:
        self.settings = settings
        self._providers = providers if providers is not None else {}
        self._provider_constructor = provider_constructor

    def is_cached(self, provider_id: str) -> bool:
        """Return whether a provider for this id is already cached."""
        return provider_id in self._providers

    def resolve_provider(self, provider_id: str) -> BaseProvider:
        """Return an existing provider or create it lazily."""
        if provider_id not in self._providers:
            self._providers[provider_id] = self._provider_constructor(
                provider_id, self.settings
            )
        return self._providers[provider_id]

    async def cleanup(self) -> None:
        """Release every provider client constructed by this generation."""
        errors: list[Exception] = []
        for provider_id, provider in list(self._providers.items()):
            try:
                await provider.cleanup()
            except asyncio.CancelledError:
                raise
            except Exception as exc:
                errors.append(exc)
            else:
                self._providers.pop(provider_id, None)
        if len(errors) == 1:
            raise errors[0]
        if len(errors) > 1:
            raise ExceptionGroup("One or more provider cleanups failed", errors)