// Package embed turns text into vectors. G2 ships an Ollama-backed // Provider (local model on :11434, no network call to a hosted // service); the Provider interface keeps the door open for OpenAI / // Voyage / etc. without per-call switching at the HTTP boundary. // // Vectors are float32 throughout the system (matches vectord + // coder/hnsw types). Ollama returns float64; we convert at this // package's boundary so callers don't have to think about it. package embed import ( "context" "errors" ) // Provider is the embed boundary. Embed takes a list of input // texts and returns the same number of vectors, in input order, // using the named model. Empty model = use the Provider's default. type Provider interface { Embed(ctx context.Context, texts []string, model string) (Result, error) } // Result is the per-call response shape. Model echoes which model // was actually used (after default-resolution); Dimension is the // vector dimension reported by the model. The Provider guarantees // every Vector in Vectors has Dimension components. type Result struct { Model string `json:"model"` Dimension int `json:"dimension"` Vectors [][]float32 `json:"vectors"` } // ErrEmptyTexts is returned when the caller passed no inputs. // Empty-batch is an error because returning an empty result // silently wastes the round trip and hides caller bugs. var ErrEmptyTexts = errors.New("embed: empty texts") // ErrModelMismatch is returned when one call to the upstream // returns a different vector dimension than the previous call in // the same batch — only possible if the model actually switched // mid-batch (load swap on the server). Surfaced as a 502 by // callers because the upstream's behavior was inconsistent. var ErrModelMismatch = errors.New("embed: dimension changed mid-batch")