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
lang_extract lib lang_extract span.ex
Raw

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