Documentation
¶
Index ¶
- Constants
- Variables
- func AllSupported(claims []Claim) bool
- func HitRate(retrieved []string, relevant map[string]bool, k int) float64
- func HitTime(h ChunkHit) (time.Time, bool)
- func MRR(retrieved []string, relevant map[string]bool) float64
- func NDCGAtK(retrieved []string, relevant map[string]bool, k int) float64
- func PrecisionAtK(retrieved []string, relevant map[string]bool, k int) float64
- func RecallAtK(retrieved []string, relevant map[string]bool, k int) float64
- func SameSpace(colls []*Collection) error
- func SupportRate(claims []Claim) float64
- func ValidateCollectionName(name string) error
- type Attachment
- type Chunk
- type ChunkHit
- type ChunkID
- type ChunkResult
- type Chunker
- type ChunkerSpec
- type Citation
- type Claim
- type ClaimVerdict
- type Collection
- type Condition
- type ContentHash
- type CorpusSnapshot
- type Document
- type DocumentID
- type EmbeddingSpace
- type FixedChunker
- type MMRCandidate
- type MarkdownChunker
- type Metadata
- type Operator
- type ParsedDoc
- type Predicate
- type RankedID
- type Registry
- type SheetChunker
- type TextChunker
- type VectorMatch
Constants ¶
const ( DefaultChunkSize = 512 DefaultChunkOverlap = 76 )
Default chunking parameters: ~512 tokens, ~15% overlap. For the fixed strategy a "token" is a whitespace word; the structure-aware strategies measure real tokens via an injected counter.
const FixedChunkerVersion = 1
FixedChunkerVersion is the algorithm version of the fixed (word-window) strategy, recorded in a Collection's ChunkerSpec. Bump it if the fixed chunker's output could change for the same input.
const MetaKeyModTime = "mtime"
MetaKeyModTime is the reserved metadata key under which ingestion records a source file's filesystem modification time (RFC3339). It is a recency signal (see HitTime), distinct from author-supplied front-matter dates.
const RRFDefaultK = 60
RRFDefaultK is the conventional Reciprocal Rank Fusion constant. It dampens the weight of low ranks so a chunk near the top of several lists outranks one at the top of a single list without any one list dominating.
const SheetHeadingPrefix = "# Sheet: "
SheetHeadingPrefix introduces a sheet boundary in extracted tabular text. An extractor that can name its tables (the xlsx extractor, from the workbook's tab names) emits one such line before each table's rows; SheetChunker splits on it and repeats it on every chunk. It lives in domain rather than beside the extractor because it is the contract between them, and both sides must agree on it — the tabular analogue of markdown's "#".
const StructureChunkerVersion = 2
StructureChunkerVersion is the algorithm version of the structure-aware strategy (markdown sections + token sizing, plus the plain-text and tabular strategies that share its sizing), recorded in a ChunkerSpec. Bump it when any structure chunker's output could change for the same input.
v2 added SheetChunker: tabular formats gained sheet names and repeated header rows, so their chunk text changed. The spec is collection-wide, so this invalidates collections that hold no spreadsheets either — they stay queryable, but refuse further ingest until rebuilt.
Variables ¶
var ( // ErrInvalidArgument marks construction/validation failures of domain values. ErrInvalidArgument = errors.New("invalid argument") // ErrSpaceMismatch marks a space-coherence violation: // an attempt to mix vectors from a different EmbeddingSpace into a Collection. ErrSpaceMismatch = errors.New("embedding space mismatch") // ErrChunkerMismatch marks an attempt to (re-)ingest into a Collection with a // chunker different from the one it was pinned to (or any chunker, for a // collection that predates pinning). Like a space mismatch it is an invariant // violation; the CLI maps it to exit 4. ErrChunkerMismatch = errors.New("chunker mismatch") )
Sentinel errors for domain invariant violations. Infrastructure-level errors (ErrNotFound etc.) live in internal/app, next to the ports.
Functions ¶
func AllSupported ¶ added in v1.0.0
AllSupported reports whether every claim is supported — the condition for a faithfulness gate to pass.
func HitTime ¶ added in v1.0.0
HitTime infers the most meaningful timestamp for ranking a hit by recency, trying signals strongest-to-weakest and reporting whether one was found:
- an explicit "last modified" front-matter date (updated/modified/lastmod/…),
- the source file's recorded filesystem mtime (MetaKeyModTime),
- a date embedded in the source filename/path (2026-06-09, 2026-W20, …),
- a "created"/"date" front-matter date,
- the document's ingest time.
It assumes no single format: front-matter keys match case-insensitively, dates parse in several layouts (see parseDate), and filename dates cover ISO calendar dates and ISO weeks. A hit with none of these is unknown (ok=false) and keeps full weight in DecayByRecency rather than being treated as ancient.
func MRR ¶ added in v1.0.0
MRR is the reciprocal rank of the first relevant identifier (1-based), or 0 if none is relevant.
func NDCGAtK ¶ added in v1.0.0
NDCGAtK is the normalized discounted cumulative gain at k with binary relevance: DCG over the top k divided by the ideal DCG (all relevant ranked first). 0 when there is nothing relevant.
func PrecisionAtK ¶ added in v1.0.0
PrecisionAtK is the fraction of the top k that is relevant. 0 when nothing was retrieved.
func RecallAtK ¶ added in v1.0.0
RecallAtK is the fraction of the relevant set found in the top k. 0 when there is nothing relevant (recall is undefined; callers exclude such cases).
func SameSpace ¶
func SameSpace(colls []*Collection) error
SameSpace enforces space coherence across a set of collections: their vectors are directly comparable only if every collection shares one EmbeddingSpace. It is the precondition for any cross-collection retrieval — feeding one collection's vectors into another (query --from-collection) or merging hits from several (multi-collection ask/query) — and returns ErrSpaceMismatch naming the first offending collection (and both spaces) on a divergence. Zero or one collection trivially shares a space.
func SupportRate ¶ added in v1.0.0
SupportRate is the fraction of claims that are supported (0..1). No claims is vacuously faithful (1.0); unsupported and uncited claims both lower it.
func ValidateCollectionName ¶
ValidateCollectionName reports whether name is non-empty, filesystem- and shell-safe, and at most 64 chars. It is the shared rule behind NewCollection and the import path, which reconstructs a (possibly renamed) collection from an artifact and must validate the target name without building a full collection.
Types ¶
type Attachment ¶
type Attachment struct {
MediaType string // e.g. "image/png", "application/pdf"
Name string // original filename, for display/citation; optional
Data []byte
}
Attachment is raw content handed to a Generator alongside retrieved chunks — an image or document the model reads directly. Unlike ingested content it is ephemeral: never chunked, embedded, or stored. How it is encoded for a provider, and whether the provider accepts it, are the Generator adapter's concern.
func NewAttachment ¶
func NewAttachment(mediaType, name string, data []byte) (Attachment, error)
NewAttachment validates and constructs an Attachment. Name may be empty.
type Chunk ¶
type Chunk struct {
ID ChunkID
DocumentID DocumentID
Seq int
Text string
// HeadingPath is the document section a chunk came from, joined with " > "
// (e.g. "Auth > Keys > Rotation"). Set by structure-aware chunkers; empty for
// formats or strategies without headings. It is provenance for display and
// inspection, not part of the chunk's identity.
HeadingPath string
}
Chunk is the unit of retrieval. It belongs to exactly one Document (deleting the Document deletes its Chunks).
type ChunkHit ¶
type ChunkHit struct {
Chunk Chunk
Score float64
Source string // source URI of the chunk's document
// Collection names the collection the chunk came from. It is empty for
// single-collection retrieval (where it is implied by the request) and set
// only for cross-collection results (multi-collection query/ask), so the
// merged hits stay attributable to their origin.
Collection string
RerankScore *float64
// Metadata is the chunk's document-level attributes, attached at hydration for
// display (--json, human output). Empty unless the document carried metadata.
Metadata Metadata
// IngestedAt is when the chunk's document was ingested, attached at hydration.
// It is the recency fallback (see HitTime) when the document carries no date
// metadata; the zero value means unknown.
IngestedAt time.Time
}
ChunkHit is a hydrated retrieval result: the chunk itself, its similarity score, and the URI of the source document it came from (provenance for display and citation). RerankScore is set only after a cross-encoder rerank — nil means the hit was never reranked, so it serializes additively (rerank_score omitted) and the original Score is always preserved alongside it.
func CapPerSource ¶ added in v1.0.0
CapPerSource caps the number of hits kept per source document to max, preserving the input order (assumed already ranked). A document that dominates the ranking cannot then sweep the result set. max <= 0 is a no-op.
func DecayByRecency ¶ added in v1.0.0
DecayByRecency reorders hits by relevance blended with an exponential time decay, then returns the top k (all of them when k <= 0). Each hit's cosine Score is multiplied by 2^(-age/halfLife), where age is now minus the hit's timestamp (HitTime); the hits are stable-sorted by this adjusted score. A hit with no known timestamp, or one dated in the future, keeps its full score (decay 1.0) — only known-older hits are demoted, so retrieval never buries an undated chunk on a guess. The cosine Score is preserved for display; only the order changes (mirroring rerank/MMR). halfLife <= 0 is a no-op reorder.
func SelectMMR ¶ added in v1.0.0
func SelectMMR(candidates []MMRCandidate, lambda float64, k int) []ChunkHit
SelectMMR reorders candidates by Maximal Marginal Relevance, greedily picking the candidate that maximizes lambda*relevance - (1-lambda)*maxSimilarityToSelected, where relevance is the hit's (cosine) Score and similarity is cosine between candidate vectors. lambda in [0,1] trades relevance (1.0) against diversity (0.0); ~0.5 is a balanced default. It returns up to k selected hits in selection order; k <= 0 selects all. Ties break by ChunkID for determinism.
Relevance (Score) and the similarity penalty are both cosine-scaled, so they combine meaningfully; under --rerank the rerank score is a different scale and is deliberately not used here (cosine relevance keeps MMR's two terms comparable).
type ChunkID ¶
type ChunkID string
ChunkID is deterministic, derived from (DocumentID, Seq), so re-chunking an unchanged document yields identical identities, keeping ingestion idempotent.
func DeriveChunkID ¶
func DeriveChunkID(docID DocumentID, seq int) ChunkID
DeriveChunkID computes the deterministic identity of a chunk.
type ChunkResult ¶
type ChunkResult struct {
Text string
// EmbedText is the text to embed when it should differ from the stored Text —
// e.g. a heading-path context prefix prepended so the embedding captures the
// chunk's place in the document. Empty means embed Text as-is; either way the
// stored Text (what citations and inspection show) is the original, never the
// prefixed form.
EmbedText string
// HeadingPath is the document section the chunk came from (e.g.
// "Auth > Keys > Rotation"), set by structure-aware chunkers; empty otherwise.
HeadingPath string
}
ChunkResult is one chunk a Chunker produced: the text to store and cite, plus any section metadata. Identity (ChunkID, Seq) is assigned by the ingestor, not the chunker, since only the ingestor knows the owning Document.
func (ChunkResult) TextToEmbed ¶
func (r ChunkResult) TextToEmbed() string
TextToEmbed returns the text that should be embedded for this chunk: the EmbedText override when set, otherwise the stored Text.
type Chunker ¶
type Chunker interface {
Chunk(doc ParsedDoc) ([]ChunkResult, error)
}
Chunker splits a parsed document into ordered chunks. Implementations are deterministic and pure: same input → identical output, no I/O, no map-iteration-order dependence. A token-aware strategy receives a token-count func at construction rather than importing a tokenizer, so stdlib-only domain stays clean.
type ChunkerSpec ¶
type ChunkerSpec struct {
Strategy string // "structure" | "fixed"
Version int // strategy algorithm version; bump when output could change for the same input
Size int // target chunk size (tokens for structure, words for fixed)
Overlap int // overlap between adjacent chunks, same unit as Size
Tokenizer string // sizing tokenizer identity, e.g. "o200k_base" (structure) or "words" (fixed)
ContextPrefix bool // whether a heading-path context line is prepended to the embedded text
}
ChunkerSpec identifies the chunking configuration a Collection is pinned to: the strategy, its algorithm version, the size/overlap parameters, the tokenizer used for sizing, and whether a heading-path context prefix is embedded. Any of these changing alters chunk output (boundaries, count, or embedded text) for the same input, so a Collection records its spec at creation and refuses re-ingestion under a different one — the chunker analogue of space coherence. It is comparable with ==.
func NewChunkerSpec ¶
func NewChunkerSpec(strategy string, version, size, overlap int, tokenizer string, contextPrefix bool) (ChunkerSpec, error)
NewChunkerSpec validates and constructs a ChunkerSpec.
func (ChunkerSpec) IsZero ¶
func (s ChunkerSpec) IsZero() bool
IsZero reports whether the spec is uninitialized — the state of a Collection created before chunker pinning existed.
func (ChunkerSpec) String ¶
func (s ChunkerSpec) String() string
String renders the spec for human and error output, e.g. "structure/v1 size=512 overlap=64 tok=o200k_base prefix=on".
func (ChunkerSpec) Validate ¶
func (s ChunkerSpec) Validate() error
Validate reports whether the spec is well-formed.
type Citation ¶
type Citation struct {
ChunkID ChunkID
Source string // source URI of the chunk's document
Seq int // the chunk's position within that document
// Collection names the chunk's collection, set only for cross-collection
// answers (multi-collection ask) so a citation stays attributable to its
// origin; empty for single-collection answers.
Collection string
}
Citation references a chunk an answer was grounded in, carrying the provenance needed to display it: the source document's URI and the chunk's position within it.
type Claim ¶ added in v1.0.0
type Claim struct {
Text string
CitedChunks []ChunkID
Verdict ClaimVerdict
Rationale string
}
Claim is one sentence of an answer with the chunks it cites and its verdict. A cited claim starts with an empty Verdict (the Verifier fills it); an uncited claim is VerdictUncited from segmentation.
func SegmentClaims ¶ added in v1.0.0
SegmentClaims splits an answer into claims (sentences), extracts the chunk IDs each cites (keeping only those present in citations — hallucinated IDs are dropped), and strips the citation markers from the claim text. A sentence with no letters is list structure or a stray number ("1." enumerators split as "1"), not a claim, and is dropped. A sentence with no marker of its own inherits the citations of its block — generators cite once at the end of a multi-sentence point, and the point's earlier sentences are grounded in the same chunks. Only a sentence whose whole block cites nothing is marked VerdictUncited; every other claim is left unjudged for the Verifier. Empty/whitespace-only answers yield no claims.
type ClaimVerdict ¶ added in v1.0.0
type ClaimVerdict string
ClaimVerdict is the faithfulness verdict for one claim (sentence) of an answer.
const ( // VerdictSupported: the claim is entailed by the chunk(s) it cites. VerdictSupported ClaimVerdict = "supported" // VerdictUnsupported: the claim cites chunks but is not entailed by them. VerdictUnsupported ClaimVerdict = "unsupported" // VerdictUncited: the claim cites no chunk in the grounding set, so it cannot // be verified — flagged rather than trusted. VerdictUncited ClaimVerdict = "uncited" )
type Collection ¶
type Collection struct {
Name string
Space EmbeddingSpace
Chunker ChunkerSpec
CreatedAt time.Time
// Sources are the paths ingested into this collection, recorded by add and
// sync so `lore sync` can replay them without a path argument.
Sources []string
}
Collection is the aggregate root: a named corpus bound to exactly one EmbeddingSpace, and pinned to exactly one ChunkerSpec, for its entire lifetime.
func NewCollection ¶
func NewCollection(name string, space EmbeddingSpace, chunker ChunkerSpec, now time.Time) (*Collection, error)
NewCollection validates identity, space, and chunker spec, and constructs a Collection. The clock is injected so the domain stays deterministic and testable. A new collection must be pinned to a valid ChunkerSpec; collections loaded from storage that predate chunker pinning carry a zero spec (built as a literal by the repository, not through this constructor).
func (*Collection) AcceptsChunker ¶
func (c *Collection) AcceptsChunker(spec ChunkerSpec) error
AcceptsChunker enforces chunker coherence: a collection may be (re-)ingested only by the chunker it was pinned to. Mixing chunker configurations within a collection would silently leave it holding chunks of two incompatible layouts (unchanged documents fast-skip re-chunking), so a mismatch is refused — the collection must be rebuilt under the new chunker. A collection that predates chunker pinning (zero spec) is read-only: queryable, but not re-ingestable.
func (*Collection) AcceptsSpace ¶
func (c *Collection) AcceptsSpace(s EmbeddingSpace) error
AcceptsSpace enforces space coherence: vectors may enter the collection only if they were produced in the collection's own space.
type ContentHash ¶
type ContentHash string
ContentHash is the SHA-256 of document content, hex-encoded. Hash equality is what makes ingestion idempotent.
func HashContent ¶
func HashContent(content []byte) ContentHash
HashContent computes the ContentHash of raw content.
type CorpusSnapshot ¶ added in v1.0.0
type CorpusSnapshot struct {
// Digest is the hex sha256 over the corpus's (SourceURI, Hash) pairs.
Digest ContentHash
// LastIngest is the maximum Document.IngestedAt, or the zero time when the
// corpus is empty.
LastIngest time.Time
}
CorpusSnapshot is a content-derived identity for a collection's document set. Its Digest changes if and only if the set of (source, content-hash) pairs changes — any addition, removal, or edit — and is therefore the field a provenance trail should stamp, unlike Collection.CreatedAt, which is a birth/ rebuild marker that a sync leaves untouched. LastIngest names when the most recently (re)ingested document entered the corpus.
The snapshot is space- and chunker-independent by design: it identifies what was ingested, not how it was embedded, mirroring CollectionDiff.
func SnapshotOf ¶ added in v1.0.0
func SnapshotOf(docs []*Document) CorpusSnapshot
SnapshotOf computes the CorpusSnapshot of docs. The Digest is order- independent (the pairs are hashed in SourceURI order) and unambiguous: each field is NUL-terminated, so neither a URI nor a hash can straddle a boundary — the same framing guarantee DeriveDocumentID relies on.
type Document ¶
type Document struct {
ID DocumentID
Collection string
SourceURI string
Hash ContentHash
IngestedAt time.Time
// Fingerprint is a cheap source-side signature (e.g. size + sampled-content
// hash) used to skip re-reading unchanged files before extraction. Unlike
// Hash it is a heuristic, not an identity; empty means "unknown".
Fingerprint string
// Metadata holds the document's structured attributes (user-supplied --meta
// pairs, extracted front-matter, path/mtime-derived fields). It is provenance
// for display and the substrate for --where filtering; it is not part of the
// document's identity (Hash) and may change without re-chunking.
Metadata Metadata
}
Document is source content with identity. Whether its content *changed* is decided by Hash (hash equality => ingestion is a no-op).
func NewDocument ¶
NewDocument constructs a Document with its deterministic ID.
func (*Document) Unchanged ¶
func (d *Document) Unchanged(hash ContentHash) bool
Unchanged reports whether content with the given hash would be a no-op re-ingestion of this document.
type DocumentID ¶
type DocumentID string
DocumentID is deterministic, derived from (collection, source URI): re-ingesting the same source addresses the same identity, which is what makes `lore add` an upsert rather than an append.
func DeriveDocumentID ¶
func DeriveDocumentID(collection, sourceURI string) DocumentID
DeriveDocumentID computes the deterministic identity of a source within a collection. The NUL separator prevents ambiguity between (a,bc) and (ab,c).
type EmbeddingSpace ¶
EmbeddingSpace identifies the vector space a Collection is bound to: the embedding model plus its output dimensionality. Two vectors are comparable only if they come from the same space.
func NewEmbeddingSpace ¶
func NewEmbeddingSpace(model string, dimensions int) (EmbeddingSpace, error)
NewEmbeddingSpace validates and constructs an EmbeddingSpace.
func (EmbeddingSpace) Equal ¶
func (s EmbeddingSpace) Equal(other EmbeddingSpace) bool
Equal reports whether two spaces are the same (and therefore whether their vectors are comparable).
func (EmbeddingSpace) IsZero ¶
func (s EmbeddingSpace) IsZero() bool
IsZero reports whether the space is uninitialized.
func (EmbeddingSpace) String ¶
func (s EmbeddingSpace) String() string
type FixedChunker ¶
type FixedChunker struct {
// contains filtered or unexported fields
}
FixedChunker emits fixed-size, overlapping windows measured in whitespace words — the legacy chunking behavior, preserved verbatim as the `fixed` strategy and the default fallback. Word sizing is dependency-free and deterministic; the structure-aware strategies use real token counts instead. Chunk text is whitespace-normalized as a side effect.
Construct with NewFixedChunker; the zero value is not usable.
func NewFixedChunker ¶
func NewFixedChunker(size, overlap int) (FixedChunker, error)
NewFixedChunker returns a FixedChunker that emits chunks of at most size words, with consecutive chunks sharing overlap words. It requires size > 0 and 0 <= overlap < size, so every window advances.
func (FixedChunker) Chunk ¶
func (c FixedChunker) Chunk(doc ParsedDoc) ([]ChunkResult, error)
Chunk implements Chunker by windowing the document text. ContentType is ignored — fixed sizing is format-agnostic.
func (FixedChunker) Split ¶
func (c FixedChunker) Split(text string) []string
Split divides text into chunks in document order. Consecutive chunks share up to overlap words. Empty or whitespace-only input yields no chunks, and no chunk is ever empty.
type MMRCandidate ¶ added in v1.0.0
MMRCandidate is a hit paired with its embedding vector, the input to Maximal Marginal Relevance selection. The hit's Score is used as its relevance to the query; the vector is used for the redundancy penalty against already-selected hits.
type MarkdownChunker ¶
type MarkdownChunker struct {
// contains filtered or unexported fields
}
MarkdownChunker splits markdown into token-sized chunks that respect the document's heading hierarchy: each chunk is a section (the content under a heading), carrying the full heading path as metadata. It never breaks inside a fenced code block; oversized sections split at paragraph (then sentence, then word) boundaries, and undersized adjacent sections merge up to the target size. Deterministic and pure.
Construct with NewMarkdownChunker; the zero value is not usable.
func NewMarkdownChunker ¶
func NewMarkdownChunker(size, overlap int, contextPrefix bool, countTokens func(string) int) (MarkdownChunker, error)
NewMarkdownChunker returns a MarkdownChunker targeting size tokens per chunk with overlap tokens shared between size-driven sub-splits. When contextPrefix is true, each chunk's embedded text is prefixed with its heading path so the embedding captures the chunk's place in the document (the stored text is unchanged). It requires size > 0, 0 <= overlap < size, and a non-nil counter.
func (MarkdownChunker) Chunk ¶
func (c MarkdownChunker) Chunk(doc ParsedDoc) ([]ChunkResult, error)
Chunk splits the document into heading-aware, token-sized chunks.
type Metadata ¶ added in v1.0.0
Metadata is a small, flat set of structured attributes attached to a Document and carried on its chunks' index entries for retrieval filtering. Values are stored canonically as strings; the typed comparison semantics (numeric, date, glob, tag membership) live in Predicate, not in the storage. Keys are caller-defined: user-supplied --meta pairs, extracted front-matter, or path/mtime-derived fields.
func ParseFrontMatter ¶ added in v1.0.0
ParseFrontMatter extracts a leading YAML-style front-matter block — a `---` fence, `key: value` lines, then a closing `---` fence — into Metadata, and returns the document body with that block removed. It is a deliberately small parser, not full YAML: each line is a single `key: value` scalar; a value wrapped in matching quotes is unquoted, and a `[a, b, c]` bracket list is flattened to a comma-joined string (so tag membership via the ~ operator works). Blank lines, `#` comments, and lines without a colon are ignored.
If text does not begin with a `---` fence, or the block is never closed, the text is returned unchanged with nil metadata — front matter is opt-in, never guessed. An empty block strips cleanly and yields nil metadata.
type Operator ¶ added in v1.0.0
type Operator string
Operator is the comparison in a --where Condition.
const ( OpEqual Operator = "=" OpNotEqual Operator = "!=" OpLess Operator = "<" OpLessEqual Operator = "<=" OpGreater Operator = ">" OpGreaterEqual Operator = ">=" OpMatch Operator = "~" )
The supported operators. Ordered/equality comparisons coerce both sides (numeric, then date, then string); ~ is a case-insensitive glob with tag-list membership. The grammar is deliberately small — a filter, not a query language.
type ParsedDoc ¶
ParsedDoc is the input to a Chunker: the extracted text of one document plus the context a strategy may need. ContentType lets the Registry dispatch to a per-format strategy; SourceURI is carried for diagnostics.
type Predicate ¶ added in v1.0.0
type Predicate struct {
Conditions []Condition
}
Predicate is a conjunction (AND) of metadata Conditions — the parsed form of the repeatable --where flag. The zero Predicate has no conditions and matches every document, so an absent --where filters nothing.
func ParseWhere ¶ added in v1.0.0
ParseWhere parses repeatable --where clauses into a conjunctive Predicate. Each clause is one `key op value` (whitespace around each part is trimmed); the operators are =, !=, <, <=, >, >=, and ~. No clauses yields the zero predicate. A clause with no operator, an empty key, or an empty value is ErrInvalidArgument.
type RankedID ¶ added in v1.0.0
RankedID is a chunk identity with its fusion score, best (highest) first.
func FuseRRF ¶ added in v1.0.0
FuseRRF combines several ranked lists of chunk IDs by Reciprocal Rank Fusion: each list contributes 1/(k + rank) to an ID's score (rank is 1-based, best first), summed across the lists it appears in; the result is sorted by score descending, ties broken by ID for determinism. A duplicate ID within a single list counts only at its best (first) rank. Rank-based fusion needs no score normalization, which is why it is the default merge of the (cosine) vector and (BM25) lexical result lists — their score scales are not comparable, but their ranks are.
type Registry ¶
type Registry struct {
// contains filtered or unexported fields
}
Registry selects a Chunker by content type, falling back to a default. It is how per-format strategies (markdown, plain text, ...) plug in without the ingestor knowing which is which; a future code-aware strategy is just another registered entry (though a tree-sitter strategy could not be pure-domain). It also carries the ChunkerSpec the active configuration corresponds to, so the use cases can pin it on new collections and refuse re-ingest under a different one. Construct with NewRegistry; the zero value is not usable.
func NewRegistry ¶
NewRegistry builds a Registry routing each content type in byType to its Chunker and everything else to def, identified by spec. It requires a valid spec and a non-nil default, and rejects nil entries; content-type keys are normalized so dispatch is case- and parameter-insensitive.
func (Registry) Chunk ¶
func (r Registry) Chunk(doc ParsedDoc) ([]ChunkResult, error)
Chunk dispatches to the chunker registered for the document's content type, or the default if none matches.
func (Registry) Spec ¶
func (r Registry) Spec() ChunkerSpec
Spec returns the ChunkerSpec the registry's active configuration corresponds to — what new collections are pinned to and re-ingest is checked against.
type SheetChunker ¶ added in v1.1.0
type SheetChunker struct {
// contains filtered or unexported fields
}
SheetChunker splits tabular text — one record per line — into token-sized chunks that stay readable on their own. A table's header row is the only thing naming its columns, and a sheet's tab name the only thing naming the table, so both are repeated at the top of every chunk cut from that table. Without this a chunk from the middle of a workbook retrieves as bare cells whose columns the reader (and the model) cannot recover.
Unlike MarkdownChunker's context prefix, the repetition goes into the stored Text, not just EmbedText: the header is genuinely absent from the interior of a table, so a reader of the cited chunk needs it as much as the embedding does.
Rows are never split across chunks and never duplicated between them; the header is the shared context instead of an overlap window. The first line of each table is taken to be its header, which is wrong for a workbook with banner rows above the real header — a limitation, not a heuristic to grow.
Deterministic and pure. Construct with NewSheetChunker; the zero value is not usable.
func NewSheetChunker ¶ added in v1.1.0
func NewSheetChunker(size, overlap int, countTokens func(string) int) (SheetChunker, error)
NewSheetChunker returns a SheetChunker targeting size tokens per chunk. The overlap applies only when a single row is itself too large to fit and has to be hard-split. It requires size > 0, 0 <= overlap < size, and a non-nil counter.
func (SheetChunker) Chunk ¶ added in v1.1.0
func (c SheetChunker) Chunk(doc ParsedDoc) ([]ChunkResult, error)
Chunk splits the document into per-table, header-carrying chunks.
type TextChunker ¶
type TextChunker struct {
// contains filtered or unexported fields
}
TextChunker splits plain text into token-sized chunks at paragraph (then sentence, then word) boundaries, never mid-sentence where avoidable. It has no heading awareness: it is the structure strategy's chunker for plain text and the default fallback for formats without their own structure-aware chunker (docx paragraphs; best-effort pdf/xlsx text). Deterministic and pure.
Construct with NewTextChunker; the zero value is not usable.
func NewTextChunker ¶
func NewTextChunker(size, overlap int, countTokens func(string) int) (TextChunker, error)
NewTextChunker returns a TextChunker targeting size tokens per chunk with overlap tokens shared between size-driven splits. It requires size > 0, 0 <= overlap < size, and a non-nil token counter.
func (TextChunker) Chunk ¶
func (c TextChunker) Chunk(doc ParsedDoc) ([]ChunkResult, error)
Chunk packs the document text into token-sized chunks. There is no heading path; ContentType is ignored.
type VectorMatch ¶
VectorMatch is what a VectorIndex returns: an identity and a similarity score (higher is more similar), not yet hydrated with chunk content.