index

package
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 5, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Overview

Package index stores the corpus and answers questions against it.

Retrieval sits behind a narrow contract with one implementation over SQLite FTS5. The contract is worth its hour: it lets a vector retriever be measured against the identical path later without either dirtying this one or building it twice, and it keeps the benchmark harness depending on an interface rather than on a database.

Index

Constants

View Source
const MaxQueryTerms = 32

MaxQueryTerms bounds a query built from a question.

Somebody pasting a stack trace or a whole config file into a channel should get a search, not a database pathology. The bound is generous — real questions are a dozen words — and terms past it are dropped rather than the question being refused, because a long question is still a question.

Variables

This section is empty.

Functions

func BuildQuery

func BuildQuery(question string) string

BuildQuery turns a natural question into an FTS5 expression.

A question is not a query. FTS5 MATCH takes its own expression language, and ordinary questions are full of characters that mean something in it: passing user text through unchanged does not merely risk odd results, it fails — "how do I hot-reload config?" errors with "no such column: reload", and an apostrophe is a syntax error. "col:value" reaches the column-filter syntax, which makes the query language addressable from a Discord message.

So nothing from the question survives as syntax. The text is broken into word tokens, each is quoted as a literal term, and the terms are joined with OR. Quoting is what makes an operator word like AND an ordinary search term rather than an instruction.

OR rather than AND because BM25 is doing the ranking: requiring every term would turn one unusual word in a question into no results at all, where scoring lets the documents matching more of the rare terms rise.

Types

type Document

type Document struct {
	SourcePath string
	RepoPath   string
	SiteURL    string
	Title      string
	Kind       corpus.Kind
	CommitSHA  string
	ContentSHA string
	Chunks     []corpus.Chunk
}

Document is one indexed file and its chunks.

type FTS

type FTS struct {
	// contains filtered or unexported fields
}

FTS retrieves with SQLite FTS5 and BM25.

func NewFTS

func NewFTS(db *store.DB) *FTS

NewFTS builds a retriever over an open database.

func (*FTS) Retrieve

func (f *FTS) Retrieve(ctx context.Context, question string, limit int) ([]Result, error)

Retrieve scores the corpus against a question.

The question is rebuilt into an FTS5 expression rather than passed through: see BuildQuery. A question with nothing searchable in it returns no results rather than a query that matches everything.

type Result

type Result struct {
	Text  string
	Score float64

	Heading     string
	HeadingPath string

	// URL is the citation, section anchor included.
	URL string

	SourcePath string
	RepoPath   string
	CommitSHA  string
	IndexedAt  time.Time
}

Result is one retrieved passage with everything needed to cite it.

type Retriever

type Retriever interface {
	Retrieve(ctx context.Context, question string, limit int) ([]Result, error)
}

Retriever finds passages relevant to a question.

Query in, scored provenance-carrying results out. Deliberately narrow: it is the seam a vector retriever would arrive through, and the one the benchmark measures.

type Source

type Source struct {
	Path    string
	SiteURL string
	RepoURL string
	Verdict corpus.Verdict
}

Source is a repository the corpus predicate has considered.

type Writer

type Writer struct {
	// contains filtered or unexported fields
}

Writer populates the index.

func NewWriter

func NewWriter(db *store.DB) *Writer

NewWriter builds a writer over an open database.

func (*Writer) PutDocument

func (w *Writer) PutDocument(ctx context.Context, d Document) error

PutDocument indexes a document, replacing whatever was there before.

The whole document is written in one transaction, and its chunks are deleted before the new ones are inserted. Without the replacement a refresh would accumulate every previous version of a page and happily cite prose that has since been rewritten — a citation that resolves, to text that no longer says what the answer claimed.

func (*Writer) PutSource

func (w *Writer) PutSource(ctx context.Context, s Source) error

PutSource records a source and the verdict that admitted or rejected it.

Rejected sources are kept deliberately: an operator asking why something is not indexed should get the clause that decided it rather than silence.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL