Behaviour for authentication providers.
Providers own protocol-specific login/refresh and token-to-LLM wiring. Shared storage/callback plumbing lives outside providers so additional sign-in options can be added without duplicating persistence code.
Summary
Types
Callbacks
@callback ensure_fresh() :: {:ok, credentials()} | {:error, term()}
@callback id() :: String.t()
@callback load() :: {:ok, credentials()} | {:error, term()}
@callback login(keyword()) :: {:ok, credentials()} | {:error, term()}
@callback model_prefixes() :: [String.t()]
@callback put_credentials(credentials()) :: :ok | {:error, term()}
@callback refresh(credentials()) :: {:ok, credentials()} | {:error, term()}
@callback request_options() :: [request_option()]
@callback resolve_model(prefix :: String.t(), model_id :: String.t()) :: {reqllm_model :: term(), [request_option()]}