Documentation
¶
Overview ¶
Package embed provides text-to-vector embedding via Ollama's local HTTP API. Vector embeddings power the `similarity` CEL variable and the `search_semantic` MCP tool (PR for issue #151).
Ollama is the only embedding source supported in v1 — it's the canonical local-model runner, exposes a stable HTTP API on localhost:11434, and lets the user pick the model via one-time `ollama pull <name>`. No SDK, no CGo, no bundled model.
The Embedder interface is small enough that other embedding sources (OpenAI API, llama.cpp HTTP, etc.) can plug in later without rewiring callers — same Embed(ctx, text) shape.
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ErrNoModel = errors.New("no embedding model configured (pass --embedding-model or per-call 'model')")
ErrNoModel is returned by Embed when no model has been configured (neither at server startup nor per-call). Surfaces cleanly in MCP responses as "no embedding model configured".
var ErrNoServer = errors.New("no embedding server configured")
ErrNoServer is returned by Embed when no server URL has been configured. Practically rare since OllamaEmbedder defaults to localhost:11434, but defensive against an empty override.
Functions ¶
func Cosine ¶
Cosine returns the cosine similarity of two vectors, in [-1, 1]. Returns 0 when either vector is empty OR their lengths disagree — defensive against partially-populated cache entries. Vectors don't need to be pre-normalised; the function divides by the L2 norms itself. For pre-normalised vectors, prefer Dot which skips the norm computation.
Types ¶
type Embedder ¶
type Embedder interface {
// Embed returns the embedding vector for the given text. Honours
// ctx; HTTP-backed implementations route ctx through
// http.NewRequestWithContext so cancellation propagates.
Embed(ctx context.Context, text string) ([]float32, error)
// Model returns the model identifier the embedder is configured
// to use. Used in error messages and telemetry.
Model() string
}
Embedder turns text into a fixed-size embedding vector. Implementations are expected to be safe for concurrent Embed calls (the OllamaEmbedder uses an *http.Client which is concurrency-safe).
type OllamaEmbedder ¶
type OllamaEmbedder struct {
// contains filtered or unexported fields
}
OllamaEmbedder calls Ollama's local /api/embed endpoint. Lazy connect — the first Embed call performs the only HTTP round-trip needed to detect Ollama-not-running / model-not-pulled. Server construction does no network I/O.
Wire shape (Ollama 0.1.34+):
POST /api/embed
{"model": "<name>", "input": "..."}
200
{"embeddings": [[float32, ...]], ...}
func NewOllama ¶
func NewOllama(server, model string) *OllamaEmbedder
NewOllama returns an embedder pointed at the given Ollama server. server is the base URL (e.g. "http://localhost:11434"); model is the embedding model name (e.g. "nomic-embed-text"). Empty strings surface as errors on the first Embed call rather than at construction time — callers can pass partial config from MCP startup flags + per-call overrides without preflight checks.
func (*OllamaEmbedder) Embed ¶
Embed POSTs the text to Ollama's /api/embed endpoint and returns the embedding vector. The returned vector is NOT pre-normalised — callers should call Normalize before storing or comparing if they want cosine-similarity semantics.
Errors surface from three places: missing configuration (ErrNoModel / ErrNoServer), transport (the HTTP call itself — server unreachable, timeout, etc.), and protocol (non-200 response, empty embedding array). Each carries a wrapped underlying error so callers can errors.Is past the wrapper.
func (*OllamaEmbedder) Model ¶
func (o *OllamaEmbedder) Model() string