aeat.application.ledger._evidence_draft_vision module¶
On-host vision fallback for invoice-field extraction from a scan-only PDF or image.
extract_invoice_fields() reads a PDF’s embedded text
layer. A scan-only or image-only invoice has no text layer at all, so that
primitive raises. This module supplies the on-host fallback: rasterise the PDF
(or use an image directly) into in-memory base64 PNG pages
(rasterise_pdf_pages_to_base64_png()) and read them
with the same LOCAL Ollama vision model the classification path already uses
(LocalVisionLLMClassifier), fully on-host
(sensitive-financial-data-secure-storage-only). Nothing is written to disk and
nothing leaves the machine; this needs no cloud consent gate.
The vision model’s role here is strictly transcription, never derivation: the
prompt instructs it to copy each field’s printed value verbatim (or emit null
when a field is not visibly printed) and forbids it from computing, inferring, or
estimating any figure. Every field the model returns is re-validated through the
exact same grounded heuristics the text-layer path uses –
validate_spanish_tax_id(),
parse_date(), and Decimal parsing via
normalize_decimal_separators() – so a malformed or
hallucinated value is rejected (left None) rather than trusted. This mirrors the
document-printed-value semantics
extract_invoice_fields() already has for text-layer PDFs:
both paths recover what is printed on the
document, never a registry-derived or model-computed tax figure
(evidence-read-never-emits-regulated-numbers in spirit – the persisted
Invoice this draft eventually confirms into still goes
through the operator review step before anything is minted).
Gated by LLM_VISION: an operator who has opted
out of on-host vision reading gets a typed refusal naming the capability toggle,
never a silent empty draft.
See also
InvoiceDraftTyped draft this vision path returns after grounded re-validation.
extract_invoice_fields()Text-layer extraction primitive this module complements for scan-only or image-only evidence.
extract_invoice_draft_from_evidence()Orchestration layer that falls back to this on-host reader.
LocalVisionLLMClassifierSibling local Ollama vision transport used for classification and split suggestions.
- parse_vision_extraction_response(text)[source]¶
Parse the vision model’s raw completion text into
_VisionExtractedFields.- Parameters:
text (
str) – Raw completion text from the local vision model.- Returns:
The parsed (but not yet grounded) fields.
- Return type:
_VisionExtractedFields- Raises:
PurchaseInvoiceEvidenceInputError – When no JSON object is present or the object fails schema validation.
- class LocalVisionInvoiceFieldExtractor(*, model=None, client=None, settings=None)[source]¶
Bases:
objectRead an invoice image on-host with a local Ollama vision model into an
InvoiceDraft.Mirrors
LocalVisionLLMClassifier’s transport (a local Ollama vision model fed in-memory base64 images) but for field transcription instead of category classification. Every returned field is re-validated through the grounded heuristicsextract_invoice_fields()uses for the text-layer path, so a hallucinated or malformed value never reaches the operator as a fabricated fact.- Parameters:
model (
str|None) – Local Ollama vision model identifier; defaults toSettings.aeat_llm_ollama_vision_model.client (
LLMClient|None) – InjectedLLMClient(dependency injection for tests); default-constructed against the resolved settings otherwise.settings (
Settings|None) – Injected settings; defaults toload_settings().
- property decided_by: str¶
Provenance stamp for this extractor’s transport (distinct from classification).
- extract(*, evidence_images)[source]¶
Read
evidence_imageswith the local vision model and return a grounded draft.- Parameters:
evidence_images (
tuple[str,...]) – In-memory base64 page/image renders of the evidence (fromrasterise_pdf_pages_to_base64_png()for a scan-only PDF, or the raw image bytes base64-encoded for an image attachment).- Returns:
Every field the model transcribed AND that passed grounded re-validation; everything else is
None.- Return type:
- extract_invoice_fields_from_images(evidence_images, *, model=None, settings=None)[source]¶
Convenience wrapper: build a
LocalVisionInvoiceFieldExtractorand extract.