// 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")
