Packages
Extract structured data from text using LLMs with source grounding. Maps every extraction back to exact byte positions in the source. Supports Claude, OpenAI, and Gemini providers. Elixir port of google/langextract.
Current section
Files
Jump to
Current section
Files
lib/lang_extract/span.ex
defmodule LangExtract.Span do
@moduledoc """
An aligned extraction with its byte position in the source text.
`byte_start` and `byte_end` are `nil` when `status` is `:not_found` —
the aligner refused to guess rather than ground the extraction at wrong
offsets. Guard offset arithmetic with `located?/1`.
"""
@type status :: :exact | :fuzzy | :not_found
@type t :: %__MODULE__{
text: String.t(),
byte_start: non_neg_integer() | nil,
byte_end: non_neg_integer() | nil,
status: status(),
class: String.t() | nil,
attributes: map()
}
@enforce_keys [:text, :status]
defstruct [:text, :byte_start, :byte_end, :status, :class, attributes: %{}]
@doc """
Whether the aligner grounded this span — `status` is `:exact` or
`:fuzzy`, so the byte offsets are present.
The filtering idiom for consumers doing offset arithmetic:
iex> spans = [
...> %LangExtract.Span{text: "found", status: :exact, byte_start: 0, byte_end: 5},
...> %LangExtract.Span{text: "lost", status: :not_found}
...> ]
iex> Enum.filter(spans, &LangExtract.Span.located?/1)
[%LangExtract.Span{text: "found", status: :exact, byte_start: 0, byte_end: 5}]
"""
@spec located?(t()) :: boolean()
def located?(%__MODULE__{status: status}), do: status in [:exact, :fuzzy]
end