embed

package
v2.2.0 Latest Latest
Warning

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

Go to latest
Published: Apr 23, 2026 License: MIT Imports: 14 Imported by: 0

Documentation

Overview

Package embed defines embedder interfaces and a deterministic test fixture.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type ContextualEmbedder

type ContextualEmbedder interface {
	Embedder
	EmbedDocumentChunks(ctx context.Context, fullDoc string, chunks []string) ([][]float64, error)
}

ContextualEmbedder extends Embedder with an optional chunk-aware entry point that sees the full source document alongside the chunk texts, enabling late-chunking or other context-aware strategies. The embedding of Embedder makes the relationship explicit in the type system: every ContextualEmbedder is an Embedder, and the index's runtime type assertion from an Embedder value to a ContextualEmbedder is a superset upgrade rather than a separate disjoint implementation.

type Embedder

type Embedder interface {
	Fingerprint() string
	Dimension(ctx context.Context) (int, error)
	EmbedDocuments(ctx context.Context, texts []string) ([][]float64, error)
	EmbedQueries(ctx context.Context, texts []string) ([][]float64, error)
}

Embedder generates embeddings for stored records and live queries.

type Fixture

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

Fixture is a deterministic embedder for tests and offline use.

Safe for concurrent use by multiple goroutines once constructed: Fixture is immutable post-NewFixture and every embed path operates on local state only.

func NewFixture

func NewFixture(model string, dimensions int) (*Fixture, error)

NewFixture returns a deterministic hash-based embedder.

func (*Fixture) Dimension

func (f *Fixture) Dimension(ctx context.Context) (int, error)

Dimension reports the embedding dimensionality.

func (*Fixture) EmbedDocuments

func (f *Fixture) EmbedDocuments(ctx context.Context, texts []string) ([][]float64, error)

EmbedDocuments returns deterministic embeddings for indexed document texts.

func (*Fixture) EmbedQueries

func (f *Fixture) EmbedQueries(ctx context.Context, texts []string) ([][]float64, error)

EmbedQueries returns deterministic embeddings for query texts.

func (*Fixture) Fingerprint

func (f *Fixture) Fingerprint() string

Fingerprint returns a stable identifier for the fixture configuration.

type OpenAI

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

OpenAI implements Embedder against an OpenAI-compatible HTTP embeddings API.

Safe for concurrent use by multiple goroutines once constructed: the cached dimension is guarded by a sync.Mutex, and http.Client is goroutine-safe by contract. Callers may share a single *OpenAI across a long-lived service without additional synchronization.

func NewOpenAI

func NewOpenAI(cfg OpenAIConfig) *OpenAI

NewOpenAI returns an OpenAI-compatible embedder bound to cfg.

func (*OpenAI) Config

func (e *OpenAI) Config() OpenAIConfig

Config returns the normalized embedder config.

func (*OpenAI) Dimension

func (e *OpenAI) Dimension(ctx context.Context) (int, error)

Dimension probes the upstream on first use and then reuses the cached value.

func (*OpenAI) EmbedDocuments

func (e *OpenAI) EmbedDocuments(ctx context.Context, texts []string) ([][]float64, error)

EmbedDocuments generates embeddings for indexed document texts.

func (*OpenAI) EmbedQueries

func (e *OpenAI) EmbedQueries(ctx context.Context, texts []string) ([][]float64, error)

EmbedQueries generates embeddings for query texts.

func (*OpenAI) Fingerprint

func (e *OpenAI) Fingerprint() string

Fingerprint returns a deterministic identifier for the endpoint, model, and input-preparation strategy.

func (*OpenAI) Unconfigured

func (e *OpenAI) Unconfigured() bool

Unconfigured reports whether the embedder is missing a base URL or model.

type OpenAIConfig

type OpenAIConfig struct {
	BaseURL string
	Model   string

	// Timeout bounds a single embeddings HTTP attempt. With
	// MaxRetries=0 this is also the total wall-clock budget for a
	// single-batch call. With MaxRetries > 0 the wall-clock extends
	// beyond Timeout: each attempt is still bounded by Timeout, but
	// retries and Retry-After / backoff waits stack on top — see
	// MaxRetries for details.
	//
	// For multi-batch calls the embedder schedules a safety-net
	// parent deadline of approximately:
	//
	//   batches * ((MaxRetries+1) * Timeout + MaxRetries * 30s)
	//
	// where batches = ceil(len(texts)/MaxBatchSize) and 30s is the
	// embed-side cap on each inter-retry Retry-After / backoff wait.
	// Each sub-request keeps a full per-attempt window even when an
	// earlier batch retried through a rate limit, so a slow or
	// retrying early batch cannot starve later batches. The formula
	// saturates at math.MaxInt64 nanoseconds on overflow.
	//
	// A zero or negative value selects defaultOpenAITimeout (15s) at
	// NewOpenAI time. Callers that need a hard global cap should pass
	// a ctx with their own deadline; the embedder honors whichever
	// deadline trips first.
	Timeout  time.Duration
	APIToken string

	// MaxRetries caps the number of retry attempts after a retryable
	// failure (429, 5xx, connection reset, timeout). Zero disables
	// retries. A negative value is normalized to zero at NewOpenAI
	// time so a config typo or bad env parse cannot silently
	// short-circuit every request. Retry-After is always honoured
	// when present, up to an embed-side cap of embedMaxRetryAfter
	// (30s) per gap. Mirrors chat.OpenAIConfig.MaxRetries semantics
	// so consumers that swap between chat and embed get the same
	// retry surface.
	//
	// Retries replay the embeddings POST unchanged — no idempotency
	// key is sent — so on ambiguous transport failures (timeout,
	// connection reset) an upstream that already processed the first
	// attempt may bill both. Self-hosted gateways generally have no
	// billing concern; callers hitting real OpenAI with cost ceilings
	// should leave this at zero or cap it tightly.
	MaxRetries int

	// MaxBatchSize caps how many inputs are sent in a single embeddings
	// request. EmbedDocuments and EmbedQueries chunk their input into
	// sub-requests of at most this size and concatenate the results in
	// order. Zero or negative values select defaultOpenAIMaxBatchSize
	// (512), which is conservative for self-hosted gateways; real OpenAI
	// accepts up to 2048 per request, and operators who know their
	// upstream can raise this explicitly.
	MaxBatchSize int
}

OpenAIConfig configures an OpenAI-compatible embedder.

APIToken is redacted from every log/display representation — String, GoString, and slog.LogValuer all render the token as "[REDACTED]". Direct field access still yields the raw value so the embedder itself can sign requests; redaction is defense-in-depth against accidental fmt.Printf / slog.Info / log line disclosure.

json.Marshal and encoding.TextMarshaler deliberately stay canonical: OpenAIConfig is a public configuration type, so overriding either would silently break any caller persisting or round-tripping the config (credential would vanish on encode, and TextMarshaler also redirects json.Marshal output through its redacted form). Callers that need a redacted view should marshal cfg.String() or build a dedicated view type.

func (OpenAIConfig) Enabled

func (c OpenAIConfig) Enabled() bool

Enabled reports whether the config is usable for requests.

func (OpenAIConfig) GoString

func (c OpenAIConfig) GoString() string

GoString returns a redacted Go-syntax rendering of the config for %#v. Without this, %#v falls back to reflection and surfaces the raw APIToken field value. Timeout is formatted as time.Duration(ns) so the result stays a valid Go composite literal a reader could paste back into source (Duration's default %s form "2s" is human-readable but not Go-parseable).

func (OpenAIConfig) LogValue

func (c OpenAIConfig) LogValue() slog.Value

LogValue implements slog.LogValuer so slog handlers — including the default JSONHandler — render the config with APIToken redacted. slog consults LogValuer before falling back to json.Marshal, so this covers the structured-logging path without hijacking json.Marshal itself (which stays canonical for callers that round-trip the config through JSON).

func (OpenAIConfig) String

func (c OpenAIConfig) String() string

String returns a redacted, human-readable rendering of the config. fmt verbs %v and %s route through this method.

Jump to

Keyboard shortcuts

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