File size: 1,807 Bytes
661eb14 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | from __future__ import annotations
from typing import Literal, Optional
from pydantic import BaseModel, Field
import uuid
class Rule(BaseModel):
type: Literal["numeric_threshold", "count_threshold", "certification_present", "document_present"]
field: str
operator: Literal[">=", "<=", "==", "exists"]
value: float | int | None = None
unit: str | None = None
class Criterion(BaseModel):
id: str
title: str
category: Literal["financial", "technical", "compliance"]
mandatory: bool
description: str
rule: Rule
query_hints: list[str]
source_page: int
source_clause: str
class Evidence(BaseModel):
bidder_id: str
doc_name: str
page: int
text: str
source_type: Literal["text_pdf", "tesseract", "vision_llm"]
ocr_confidence: float | None = None
class Source(BaseModel):
doc_name: str
page: int
snippet: str
source_type: Literal["text_pdf", "tesseract", "vision_llm"]
class Verdict(BaseModel):
verdict_id: str = Field(default_factory=lambda: f"V-{uuid.uuid4().hex[:8]}")
bidder_id: str
criterion_id: str
verdict: Literal["eligible", "not_eligible", "needs_review"]
extracted_value: str | None = None
normalized_value: float | int | None = None
source: Source | None = None
llm_confidence: float = 0.0
ocr_confidence: float | None = None
combined_confidence: float = 0.0
reason: str = ""
model_version: str = ""
timestamp: str = ""
review_status: Literal["pending", "approved", "edited", "rejected"] = "pending"
class AuditEntry(BaseModel):
id: int | None = None
ts: str
action: str
actor: str
model_version: str | None = None
bidder_id: str | None = None
criterion_id: str | None = None
payload_json: str | None = None
|