dheraingoud's picture
feat: sync upstream commits up to f17c92bc
a1bab2d
Raw
History Blame Contribute Delete
3.47 kB
"""Provider configuration construction from neutral catalog metadata."""
from free_claude_code.application.errors import ApplicationUnavailableError
from free_claude_code.config.provider_catalog import ProviderDescriptor
from free_claude_code.config.settings import Settings
from free_claude_code.providers.base import ProviderConfig
def string_setting(settings: Settings, attr_name: str | None, default: str = "") -> str:
"""Return a string-valued settings attribute, ignoring non-string mocks."""
if attr_name is None:
return default
value = getattr(settings, attr_name, default)
return value if isinstance(value, str) else default
def provider_credential(descriptor: ProviderDescriptor, settings: Settings) -> str:
"""Return the configured credential for a provider descriptor."""
if descriptor.static_credential is not None:
return descriptor.static_credential
if descriptor.credential_attr:
return string_setting(settings, descriptor.credential_attr)
return ""
def has_provider_configuration(
descriptor: ProviderDescriptor, settings: Settings
) -> bool:
"""Return whether all provider-defining settings are present."""
attrs = descriptor.configuration_attrs()
if attrs:
return all(string_setting(settings, attr).strip() for attr in attrs)
return descriptor.static_credential is not None
def require_provider_credential(
descriptor: ProviderDescriptor, credential: str
) -> None:
"""Raise a user-facing configuration error when a required key is missing."""
if descriptor.credential_env is None:
return
if credential and credential.strip():
return
message = f"{descriptor.credential_env} is not set. Add it to your .env file."
if descriptor.credential_url:
message = f"{message} Get a key at {descriptor.credential_url}"
raise ApplicationUnavailableError(message)
def build_provider_config(
descriptor: ProviderDescriptor, settings: Settings
) -> ProviderConfig:
"""Build shared provider configuration for one provider descriptor."""
credential = provider_credential(descriptor, settings)
require_provider_credential(descriptor, credential)
base_url = string_setting(
settings, descriptor.base_url_attr, descriptor.default_base_url or ""
)
resolved_base_url = base_url or descriptor.default_base_url
if not resolved_base_url:
if descriptor.base_url_attr is None:
raise AssertionError(
f"Provider {descriptor.provider_id!r} has no base URL owner."
)
field = Settings.model_fields[descriptor.base_url_attr]
env_name = field.validation_alias or descriptor.base_url_attr
raise ApplicationUnavailableError(
f"{env_name} is not set. Add it to your .env file."
)
proxy = string_setting(settings, descriptor.proxy_attr)
return ProviderConfig(
api_key=credential,
base_url=resolved_base_url,
rate_limit=settings.provider_rate_limit,
rate_window=settings.provider_rate_window,
max_concurrency=settings.provider_max_concurrency,
http_read_timeout=settings.http_read_timeout,
http_write_timeout=settings.http_write_timeout,
http_connect_timeout=settings.http_connect_timeout,
proxy=proxy,
log_raw_sse_events=settings.log_raw_sse_events,
log_api_error_tracebacks=settings.log_api_error_tracebacks,
)