chunkservice

package
v0.16.1 Latest Latest
Warning

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

Go to latest
Published: Oct 14, 2026 License: MIT Imports: 6 Imported by: 0

Documentation

Overview

Package chunkservice owns the request-level chunking orchestration over the chunking engine: request validation, strategy dispatch (including a strict semantic path), legacy preflight token budgets, post-strategy token ceilings, per-chunk embedding attachment, batch envelopes, and the wire projection of results. Applications (CLIs, HTTP servers) wire providers and presentation; this package decides how a request becomes chunks.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func EmbeddingsUnavailable

func EmbeddingsUnavailable() error

EmbeddingsUnavailable returns the request-validation error reported when include_embeddings is requested while no embedding configuration exists. The flag needs a provider; failing clearly beats silently omitting vectors.

func IsRequestValidationError

func IsRequestValidationError(err error) bool

IsRequestValidationError reports whether err came from Request.Validate. Callers use this boundary to distinguish safe client errors from internal failures without coupling transport status codes to error-message text.

func SemanticOptsFrom

func SemanticOptsFrom(o *SemanticOptions) chunking.SemanticOpts

SemanticOptsFrom maps wire semantic options to the library type. Zero fields stay zero: the library applies its own defaults for unset values.

func SemanticUnavailable

func SemanticUnavailable() error

SemanticUnavailable returns the request-validation error reported when the semantic strategy is requested while no embedding configuration exists. The semantic strategy needs an embedder; without one, an explicit request must fail clearly, not silently fall back.

func ValidStrategy

func ValidStrategy(s chunking.Strategy) bool

ValidStrategy reports whether s names a strategy the service dispatches. The zero value is valid (it means "use the default").

Types

type BatchRequest

type BatchRequest struct {
	Texts             []string          `json:"texts"`
	ChunkSize         int               `json:"chunk_size"`
	Strategy          chunking.Strategy `json:"strategy,omitempty"`
	Overlap           int               `json:"overlap,omitempty"`
	TokenEncoding     TokenEncoding     `json:"token_encoding,omitempty"`
	SeparatorProfile  SeparatorProfile  `json:"separator_profile,omitempty"`
	Semantic          *SemanticOptions  `json:"semantic,omitempty"`
	MaxTokens         int               `json:"max_tokens,omitempty"`
	IncludeEmbeddings bool              `json:"include_embeddings,omitempty"`
}

BatchRequest chunks many texts under one shared parameter set. Each text is processed independently: item-level failures (for example an empty text) surface as per-item error results, while batch-level problems (bad shared params, missing texts) fail the whole request.

func (BatchRequest) ToChunkRequest

func (r BatchRequest) ToChunkRequest(text string) Request

ToChunkRequest converts the shared parameters plus one text into a single chunk request — the exact transformation batch processing applies per item.

func (BatchRequest) Validate

func (r BatchRequest) Validate() error

Validate checks the batch shape and the shared parameters once. The probe text is non-empty so only shared fields are exercised; per-text validity (empty text) is an item-level result, not a whole-batch failure.

type BatchResponse

type BatchResponse struct {
	Results []BatchResult `json:"results"`
}

BatchResponse is the batch result: one entry per input text, in request order.

type BatchResult

type BatchResult struct {
	Index    int       `json:"index"`
	Response *Response `json:"response,omitempty"`
	Error    string    `json:"error,omitempty"`
}

BatchResult carries exactly one of Response or Error for one input text, keyed by its index in the request — no partial-failure ambiguity.

type Chunk

type Chunk struct {
	ID         int    `json:"id"`
	StartChar  int    `json:"start_char"`
	EndChar    int    `json:"end_char"`
	Text       string `json:"text"`
	CharCount  int    `json:"char_count"`
	WordCount  int    `json:"word_count"`
	TokenCount int    `json:"token_count,omitempty"`
	// Path is the heading breadcrumb ("H1 Title" → "Subsection") for
	// heading-aware strategies; omitted otherwise.
	Path []string `json:"path,omitempty"`
	// Metadata carries strategy-produced annotations (for example
	// markdown_aware's heading_level, language, line_count); omitted when the
	// strategy produces none.
	Metadata map[string]string `json:"metadata,omitempty"`
	// ContentHash is the first 16 hex characters of SHA-256(Text).
	ContentHash string `json:"content_hash"`
	// Embedding is the chunk text's embedding vector, present only when the
	// request set include_embeddings.
	Embedding []float32 `json:"embedding,omitempty"`
}

Chunk is one chunked span of the request text. StartChar/EndChar are rune offsets into Text of the request.

func FromLibChunk

func FromLibChunk(source string, c chunking.Chunk) Chunk

FromLibChunk projects a library chunk into the wire DTO, preserving the strategy-produced annotations: Path (heading breadcrumb), Metadata (markdown block annotations), and ContentHash (16-hex SHA-256 of Text). start_char/end_char are converted from the library's authoritative byte span into rune offsets against source; unmappable spans normalize to (0,0).

func FromLibChunks

func FromLibChunks(source string, in []chunking.Chunk) []Chunk

FromLibChunks maps a slice of library chunks to wire DTOs against source.

type Metadata

type Metadata struct {
	TotalChunks   int               `json:"total_chunks"`
	TotalChars    int               `json:"total_chars"`
	TotalTokens   int               `json:"total_tokens,omitempty"`
	StrategyUsed  chunking.Strategy `json:"strategy_used"`
	TokenEncoding TokenEncoding     `json:"token_encoding,omitempty"`
	// MaxTokens reports the token ceiling that was enforced, set only when
	// the request asked for one.
	MaxTokens int `json:"max_tokens,omitempty"`
	// SeparatorProfile reports the recursive separator cascade in effect,
	// set only when the request specified one.
	SeparatorProfile SeparatorProfile `json:"separator_profile,omitempty"`
	// EmbeddingModel names the provider model that produced the chunk
	// embeddings; set only when the request set include_embeddings.
	EmbeddingModel string `json:"embedding_model,omitempty"`
	// EmbeddingDimensions is the vector length of the chunk embeddings;
	// set only when the request set include_embeddings.
	EmbeddingDimensions int `json:"embedding_dimensions,omitempty"`
}

Metadata summarizes one chunking run for callers: totals, the strategy actually applied, and the option echoes that changed behavior.

type Request

type Request struct {
	Text      string            `json:"text"`
	ChunkSize int               `json:"chunk_size"`
	Strategy  chunking.Strategy `json:"strategy,omitempty"`
	Overlap   int               `json:"overlap,omitempty"`
	// TokenEncoding names the tiktoken encoding used for token_based
	// chunking and the MaxTokens ceiling (default cl100k_base).
	TokenEncoding TokenEncoding `json:"token_encoding,omitempty"`
	// SeparatorProfile selects the recursive strategy's separator cascade:
	// "default_text" (empty) or "cjk_thai". Only valid with strategy=recursive.
	SeparatorProfile SeparatorProfile `json:"separator_profile,omitempty"`
	// Semantic tunes the semantic strategy; zero fields fall back to library
	// defaults. Only valid with strategy=semantic.
	Semantic *SemanticOptions `json:"semantic,omitempty"`
	// MaxTokens caps every chunk's token count (measured with TokenEncoding,
	// default cl100k_base) after the base strategy runs. 0 disables the cap.
	// Chunks that exceed it are split further (sentence, then word, then
	// hard cut), so strategies can stay semantic while honoring LLM context
	// limits. It is independent of chunk_size: chunk_size bounds characters
	// (tokens for token_based); max_tokens bounds tokens on every strategy.
	MaxTokens int `json:"max_tokens,omitempty"`
	// IncludeEmbeddings attaches an embedding vector to every chunk via the
	// configured embedding provider. Works with any strategy; requires
	// embedding configuration on the service (a clear validation error
	// otherwise). Unlike the semantic strategy, a mid-request embedding
	// failure fails the request rather than falling back: the caller
	// explicitly asked for vectors.
	IncludeEmbeddings bool `json:"include_embeddings,omitempty"`
	// PreflightCounter applies a caller-supplied token budget while chunking
	// (the legacy "preflight" pipeline): boundary strategies chunk with
	// token awareness and semantic output is split where the counter says a
	// chunk exceeds budget. Unlike MaxTokens it needs no tiktoken encoding;
	// callers bring their own counter. nil disables it.
	PreflightCounter chunking.TokenCounter `json:"-"`
}

Request is one chunking job: a text plus the parameters that shape it. Zero-value optionals mean "use the engine default". It backs both wire APIs and programmatic callers.

func (Request) Validate

func (r Request) Validate() error

Validate enforces request invariants that the engine cannot express: required fields, range bounds, and strategy-coupled options.

type Response

type Response struct {
	Chunks   []Chunk  `json:"chunks"`
	Metadata Metadata `json:"metadata"`
}

Response is the chunking result: the ordered chunks plus run metadata.

type SemanticOptions

type SemanticOptions struct {
	BreakSensitivity float64 `json:"break_sensitivity,omitempty"`
	MinChunkChars    int     `json:"min_chunk_chars,omitempty"`
	MaxChunkChars    int     `json:"max_chunk_chars,omitempty"`
	SmoothingWindow  int     `json:"smoothing_window,omitempty"`
	CoherenceWindow  int     `json:"coherence_window,omitempty"`
}

SemanticOptions tunes the semantic strategy. Zero values mean library defaults (see chunking.SemanticOpts): MaxChunkChars 1600, MinChunkChars 200, BreakSensitivity 1.0; smoothing and coherence windows are disabled by default.

type SeparatorProfile

type SeparatorProfile string

SeparatorProfile selects the recursive strategy separator cascade by its wire identifier; the profiles themselves live in the chunking package.

The recursive separator cascade identifiers.

func (SeparatorProfile) IsValid

func (p SeparatorProfile) IsValid() bool

IsValid reports whether p names a supported cascade.

type Service

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

Service chunks text. The optional embedder enables the semantic strategy and include_embeddings payloads; without it, both fail validation clearly.

func New

func New() *Service

New returns a service without an embedder: the semantic strategy and include_embeddings fail validation with a clear error.

func (*Service) Chunks

func (s *Service) Chunks(ctx context.Context, req Request) ([]chunking.Chunk, Metadata, error)

Chunks runs req through the engine and returns the library chunks (byte spans, Path/Metadata/ContentHash annotations intact) plus response metadata, before wire projection. File-oriented callers use it to consume spans and annotations directly. Validation, semantic strictness, the legacy preflight budget, and the post-strategy token ceiling all apply.

func (*Service) Process

func (s *Service) Process(ctx context.Context, req Request) (*Response, error)

Process validates req, runs it through the chunking engine, and projects the result onto the wire DTOs. The semantic strategy is strict: a mid-run embedding failure fails the request instead of silently degrading to boundary chunks, because a result labeled semantic must actually be semantic.

func (*Service) ProcessBatch

func (s *Service) ProcessBatch(ctx context.Context, req BatchRequest) (*BatchResponse, error)

ProcessBatch chunks each text under the batch's shared parameters, sequentially and independently. Item-level failures (empty text, per-text validation) become per-item error results; batch-level failures (shared params, context cancellation) fail the whole call.

func (*Service) WithEmbedder

func (s *Service) WithEmbedder(embedder chunking.BatchEmbedder) *Service

WithEmbedder backs the semantic strategy and include_embeddings payloads with the given embedder. Chainable.

func (*Service) WithEmbeddingModel

func (s *Service) WithEmbeddingModel(model string) *Service

WithEmbeddingModel records the provider model name reported in metadata when responses embed chunk text. Chainable for wiring convenience.

func (*Service) WithLogger

func (s *Service) WithLogger(l *slog.Logger) *Service

WithLogger routes service logs (requests that fail mid-processing, batch item failures) to l. Nil restores the silent default. Chainable.

type TokenEncoding

type TokenEncoding string

TokenEncoding names a tiktoken encoding for token counting.

const (
	EncodingCL100K TokenEncoding = "cl100k_base" // GPT-3.5/GPT-4
	EncodingO200K  TokenEncoding = "o200k_base"  // gpt-5
	EncodingP50K   TokenEncoding = "p50k_base"   // Older models
	EncodingR50K   TokenEncoding = "r50k_base"   // Very old models
)

The supported tiktoken encodings.

func (TokenEncoding) IsValid

func (e TokenEncoding) IsValid() bool

IsValid reports whether e names a supported encoding.

func (TokenEncoding) WithDefault

func (e TokenEncoding) WithDefault() TokenEncoding

WithDefault resolves the effective encoding: unset or unknown values become cl100k_base.

Jump to

Keyboard shortcuts

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