from sqlalchemy import Boolean, String, Text from sqlalchemy.orm import Mapped, mapped_column from app.models.base import Base, TimestampMixin, UUIDPrimaryKeyMixin class LLMSetting(UUIDPrimaryKeyMixin, TimestampMixin, Base): """Per-role endpoint configuration, edited in the admin UI. One row per model role. The rows are created once, at first start, from the `PABLAN_CHAT_*` / `PABLAN_UTILITY_*` / `PABLAN_EMBEDDING_*` environment variables; from then on **this table is the truth** and later `.env` edits are ignored (see docs/architecture.md, "bootstrap, then DB"). The `*_from_env` flags record where each field's current value came from, so the UI can say "taken from .env" or "changed here" per field and offer a reset. They are not a fallback mechanism: the value itself always lives in the column next to them. Tracking the provenance explicitly beats comparing against the current environment, which would mislabel every field the moment someone edits `.env` after bootstrap. The api_key is stored in plaintext because it has to be replayed to the endpoint on every call — there is nothing to compare a hash against. It is never returned by the API and never logged. """ __tablename__ = "llm_settings" role: Mapped[str] = mapped_column(String(32), unique=True) base_url: Mapped[str | None] = mapped_column(String(500)) model: Mapped[str | None] = mapped_column(String(200)) api_key: Mapped[str | None] = mapped_column(Text) base_url_from_env: Mapped[bool] = mapped_column(Boolean, default=True) model_from_env: Mapped[bool] = mapped_column(Boolean, default=True) api_key_from_env: Mapped[bool] = mapped_column(Boolean, default=True)