% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/classify-from-documents.R
\name{classify_from_documents}
\alias{classify_from_documents}
\title{Build a fully-classified `PedonRecord` from documents in one call}
\usage{
classify_from_documents(
  pdf = NULL,
  image = NULL,
  fieldsheet = NULL,
  pedon = NULL,
  provider = "auto",
  model = NULL,
  systems = c("wrb", "sibcs", "usda"),
  report = NULL,
  overwrite = FALSE,
  verbose = TRUE
)
}
\arguments{
\item{pdf}{Optional path to a soil-description PDF.}

\item{image}{Optional path to a profile-wall image (JPG /
PNG); if supplied, Munsell extraction is
attempted with the configured provider.}

\item{fieldsheet}{Optional path to a site-metadata field sheet
(image or PDF).}

\item{pedon}{Optional existing \code{\link{PedonRecord}};
when supplied, the function fills only the
fields VLM extraction can fill (subject to the
provenance-authority order).}

\item{provider}{Either a provider name passed to
\code{\link{vlm_provider}} (default
\code{"ollama"}) OR a pre-built ellmer chat
object (when you want full control over
\code{system_prompt}, \code{api_key}, ...).}

\item{model}{Optional model identifier; passed through to
\code{vlm_provider()} when \code{provider} is a
string. Defaults to the per-provider default
from \code{\link{default_model}}.}

\item{systems}{Character vector listing which classification
systems to run; subset of
\code{c("wrb", "sibcs", "usda")}. Default: all
three.}

\item{report}{Optional output path for a self-contained
report (\code{.html} or \code{.pdf}). When
supplied, \code{\link{report}} is called on the
classification results + pedon. Default
\code{NULL} (no report file).}

\item{overwrite}{When merging extracted values into an existing
pedon, allow VLM-extracted attributes to clobber
already-recorded ones. Default \code{FALSE} --
the provenance authority order
(\code{measured > extracted_vlm}) is enforced
by \code{PedonRecord$add_measurement()}.}

\item{verbose}{Emit cli progress messages. Default
\code{TRUE}.}
}
\value{
A list with elements:
  \describe{
    \item{\code{pedon}}{The (mutated) \code{\link{PedonRecord}}.}
    \item{\code{classifications}}{Named list with up to three
          \code{\link{ClassificationResult}} objects keyed by
          \code{wrb}, \code{sibcs}, \code{usda}.}
    \item{\code{report}}{Path to the rendered report file (if
          \code{report = ...} was supplied), else \code{NULL}.}
    \item{\code{provider}}{The chat-provider object actually used
          (useful for downstream debugging or cost accounting).}
  }
}
\description{
Highest-level entry point of the soilKey VLM pipeline. Given a
soil-description PDF and / or a profile-wall photograph, this
function:
}
\details{
\enumerate{
  \item Constructs a vision-language provider chat object via
        \code{\link{vlm_provider}} (defaults to local Ollama with
        Gemma 4 edge for institutional independence and data
        sovereignty).
  \item Extracts horizons from \code{pdf} via
        \code{\link{extract_horizons_from_pdf}}, Munsell colours
        from \code{image} via
        \code{\link{extract_munsell_from_photo}}, and site
        metadata from \code{fieldsheet} via
        \code{\link{extract_site_from_fieldsheet}}. Every
        extracted attribute is stamped \code{source =
        "extracted_vlm"} in the PedonRecord's provenance log.
  \item Runs the three deterministic keys
        (\code{\link{classify_wrb2022}},
        \code{\link{classify_sibcs}},
        \code{\link{classify_usda}}). The VLM never classifies --
        the package's architectural invariant is preserved.
  \item Optionally renders a one-pager HTML / PDF report via
        \code{\link{report}}.
}

At least one of \code{pdf}, \code{image} or \code{fieldsheet}
must be supplied; you can also pass an existing partially-filled
\code{PedonRecord} via \code{pedon} and let this function fill
the gaps.
}
\section{Why local-first by default}{

The default \code{provider = "ollama"} runs the entire VLM pipeline
on the user's machine via Gemma 4 (edge variant, ~3 GB, multimodal
text+image). No part of the soil description, photograph or
field sheet ever leaves the local network. This is the
recommended configuration for governmental surveys, indigenous
land studies, and unpublished research data; it also makes the
pipeline reproducible without an internet connection. Cloud
providers (\code{"anthropic"}, \code{"openai"}, \code{"google"})
remain one argument away when they are the right call.
}

\section{Architectural invariants preserved}{

\itemize{
  \item The VLM never classifies. Every extracted value carries
        \code{source = "extracted_vlm"}; the deterministic keys
        consume the resulting \code{PedonRecord} unaware of how
        each value was obtained.
  \item Provenance is preserved end-to-end. The
        \code{evidence_grade} on each
        \code{ClassificationResult} reflects whether decisive
        attributes came from \code{measured},
        \code{predicted_spectra}, \code{extracted_vlm},
        \code{inferred_prior}, or \code{user_assumed} -- so a
        caller always knows how robust the classification is.
  \item Authority order is enforced. A pre-existing
        \code{measured} value is never silently overwritten by a
        later \code{extracted_vlm} value (unless
        \code{overwrite = TRUE}).
}
}

\examples{
\dontshow{if (requireNamespace("ellmer", quietly = TRUE)) withAutoprint(\{ # examplesIf}
\donttest{
# Requires user-provided PDF/image files and a VLM provider; the
# block guards against missing inputs so it no-ops on CRAN.
pdf_path <- "perfil_042_descricao.pdf"
if (file.exists(pdf_path) && interactive()) {
  # The simplest possible end-to-end call -- local Gemma 4 edge.
  res <- classify_from_documents(
    pdf      = pdf_path,
    image    = "perfil_042_parede.jpg",
    report   = file.path(tempdir(), "perfil_042.html")
  )
  res$classifications$wrb$name

  # Cloud provider for a one-shot, production run
  res <- classify_from_documents(
    pdf      = pdf_path,
    provider = "anthropic"
  )

  # Different Gemma 4 size on Ollama
  res <- classify_from_documents(
    pdf      = pdf_path,
    provider = "ollama",
    model    = "gemma4:31b"
  )
}
}
\dontshow{\}) # examplesIf}
}
\seealso{
\code{\link{vlm_provider}},
         \code{\link{extract_horizons_from_pdf}},
         \code{\link{classify_wrb2022}},
         \code{\link{report}}.
}
