HR-ATS-Portal/backend/inbox_classifier/models.py

44 lines
1.8 KiB
Python

"""The triage verdict exchanged with the intake-gate model.
Pure module: no FastAPI imports and no HTTPException.
``extra="forbid"`` is load-bearing — it emits ``additionalProperties: false``, which
the structured-outputs schema dialect requires (same reason as
app/models/scoring.py:22-23). Every field is required: structured outputs puts all
declared properties in ``required``, so a defaulted field buys nothing here.
Mirrors agent/models.py — this package's models.py holds the shape the LLM pass
exchanges, not a SQLModel table. The triage TABLE lives in inbox/models.py beside
Inbox_Messages, because it is an inbox-domain fact and this package never opens a
session.
"""
from __future__ import annotations
from pydantic import BaseModel, ConfigDict, Field
from inbox_classifier.enums import Triage_Reason_Code
class EmailTriageVerdict(BaseModel):
"""One intake decision about one email.
``confidence`` carries the model's doubt so the boolean does not have to. The
prompt tells it to answer the boolean the way a recruiter would want and to report
uncertainty here instead, which is what makes INBOX_TRIAGE_MIN_CONFIDENCE a usable
knob rather than a second, contradictory gate.
reason_code is the Triage_Reason_Code enum rather than a Literal, so the labels
live in one place; Pydantic renders it as the same JSON-schema enum either way.
"""
model_config = ConfigDict(extra="forbid")
is_application: bool
reason_code: Triage_Reason_Code
confidence: float = Field(ge=0.0, le=1.0)
# One clause naming the signal used. Stored for the review screen, never logged:
# the model is told not to quote personal data, but it is still model-authored
# text derived from an email body.
evidence: str = Field(min_length=1, max_length=200)