AMRYB's picture
Upload 91 files
287f3d3 verified
Raw
History Blame Contribute Delete
1.96 kB
"""Structured output of the Database Agent."""
from __future__ import annotations
from typing import Any, ClassVar
from pydantic import BaseModel, Field, field_validator
from .limits import CappedListModel
class DBField(BaseModel):
name: str
type: str
primary_key: bool = False
foreign_key: str | None = None
nullable: bool = False
unique: bool = False
indexed: bool = False
@field_validator("primary_key", "nullable", "unique", "indexed", mode="before")
@classmethod
def _normalize_bools(cls, v: Any) -> bool:
if isinstance(v, str):
return v.strip().lower() in ("true", "1", "yes", "t")
return bool(v)
@field_validator("foreign_key", mode="before")
@classmethod
def _normalize_fk(cls, v: Any) -> str | None:
if v is None or v is False or v == "" or str(v).strip().lower() in ("none", "null", "false"):
return None
return str(v).strip()
class DBEntity(CappedListModel):
name: str
description: str
fields: list[DBField] = Field(default_factory=list, max_length=10)
class DatabaseOutput(CappedListModel):
database_technology: str = ""
entities: list[DBEntity] = Field(..., max_length=8)
relationships: list[str] = Field(default_factory=list, max_length=8)
indexes: list[str] = Field(default_factory=list)
constraints: list[str] = Field(default_factory=list)
sql_schema: str = ""
erd_mermaid: str = ""
# sql_schema and erd_mermaid are derived locally (see artifacts/render.py).
# indexes and constraints are derived from entity fields (PKs, FKs, unique flags),
# so the model never needs to spend output tokens on them.
# Keeping the LLM output small is the main lever for preventing database timeouts.
llm_exclude_fields: ClassVar[frozenset[str]] = frozenset({
"sql_schema", "erd_mermaid", "indexes", "constraints"
})