"""Base provider interface - extend this to implement your own provider.""" from abc import ABC, abstractmethod from collections.abc import AsyncIterator from typing import Any from pydantic import BaseModel class ProviderConfig(BaseModel): """Configuration for a provider. Base fields apply to all providers. Provider-specific parameters (e.g. NIM temperature, top_p) are passed by the provider constructor. """ api_key: str base_url: str | None = None rate_limit: int | None = None rate_window: int = 60 max_concurrency: int = 5 http_read_timeout: float = 300.0 http_write_timeout: float = 10.0 http_connect_timeout: float = 2.0 class BaseProvider(ABC): """Base class for all providers. Extend this to add your own.""" def __init__(self, config: ProviderConfig): self._config = config @abstractmethod async def cleanup(self) -> None: """Release any resources held by this provider.""" @abstractmethod async def stream_response( self, request: Any, input_tokens: int = 0, *, request_id: str | None = None, ) -> AsyncIterator[str]: """Stream response in Anthropic SSE format.""" if False: yield "" # Required for ty/mypy to accept abstract async generator