chat

package
v0.21.0 Latest Latest
Warning

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

Go to latest
Published: Sep 12, 2026 License: Apache-2.0 Imports: 13 Imported by: 0

Documentation

Overview

Package chat composes retrieval with chat models through the rag domain contracts. It owns query transforms, expansion, model-backed ranking, contextual prompts, and retrieval preparation for chat requests. Chat history and prompt policy remain here; queries, candidates, citations, and generation input retain their owners in rag.

Index

Examples

Constants

View Source
const DefaultMultiQueryCount = 3

DefaultMultiQueryCount is the variant count used when MultiQueryExpanderConfig.NumberOfQueries is unset.

Variables

View Source
var (
	// ErrNilResponse identifies a successful model call with no response.
	ErrNilResponse = errors.New("rag: chat model returned a nil response")
	// ErrNilStreamSequence identifies a streaming implementation that did
	// not return the required iterator.
	ErrNilStreamSequence = errors.New("rag: chat streamer returned a nil sequence")
	// ErrNoFinalUserMessage rejects requests whose active retrieval query is
	// ambiguous.
	ErrNoFinalUserMessage = errors.New("rag: chat request must end with a user message")
)
View Source
var ErrEmptyModelOutput = errors.New("rag: model returned empty query text")

ErrEmptyModelOutput rejects completed text that becomes empty after trimming. Missing response text and unsuccessful completion preserve chatclient errors.

View Source
var ErrInvalidContextBudget = errors.New("rag: invalid context token budget")

ErrInvalidContextBudget identifies an invalid context window or token measurement.

Functions

func HistoryValueKey

func HistoryValueKey() rag.ValueKey[[]corechat.Message]

HistoryValueKey returns the typed query slot for the immutable history snapshot produced by Preparer before the active user turn.

Types

type CompressionTransformer

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

CompressionTransformer turns conversation history and a follow-up into one self-contained query.

func NewCompressionTransformer

func NewCompressionTransformer(config CompressionTransformerConfig) (*CompressionTransformer, error)

NewCompressionTransformer validates and freezes the model-backed compression boundary.

func (*CompressionTransformer) Transform

func (c *CompressionTransformer) Transform(ctx context.Context, query rag.Query) (rag.Query, error)

Transform asks the LLM for a self-contained version of the query. Returns a clone of the input with Text replaced by the LLM output.

type CompressionTransformerConfig

type CompressionTransformerConfig struct {
	// Model performs the compression. Required.
	Model corechat.Model

	// PromptTemplate is the LLM prompt. Defaults to
	// [compressionDefaultTemplate]. Custom templates must declare
	// {{.History}} and {{.Query}}.
	PromptTemplate *chatclient.Template
}

CompressionTransformerConfig binds a chat model and token budget to one history-aware query compression policy.

type ContextualAugmenter

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

ContextualAugmenter folds retrieved documents into a contextual query.

Example
package main

import (
	"context"
	"fmt"

	"github.com/Tangerg/scope/core/document"
	"github.com/Tangerg/scope/rag"

	ragchat "github.com/Tangerg/scope/rag/chat"
)

func main() {
	augmenter, err := ragchat.NewContextualAugmenter(ragchat.ContextualAugmenterConfig{})
	if err != nil {
		panic(err)
	}
	query, err := rag.NewQuery("What does Scope provide?")
	if err != nil {
		panic(err)
	}
	doc, err := document.NewDocument("Scope provides AI infrastructure.", nil)
	if err != nil {
		panic(err)
	}
	doc.ID = "scope"
	result, err := augmenter.Augment(context.Background(), query, rag.Candidates{{Document: doc, Score: 1}})
	if err != nil {
		panic(err)
	}
	citation := result.Citations()[0]
	fmt.Println(citation.Marker(), citation.Candidate.Document.ID)
}
Output:
[1] scope

func NewContextualAugmenter

func NewContextualAugmenter(config ContextualAugmenterConfig) (*ContextualAugmenter, error)

NewContextualAugmenter validates the complete context policy before retrieval results are admitted.

func (*ContextualAugmenter) Augment

func (c *ContextualAugmenter) Augment(ctx context.Context, query rag.Query, candidates rag.Candidates) (rag.Augmentation, error)

Augment keeps retrieved content in citation-labeled JSON so evidence remains distinguishable from prompt instructions. A bounded context contains only complete candidates; it never truncates a document into ambiguous evidence.

type ContextualAugmenterConfig

type ContextualAugmenterConfig struct {
	// PromptTemplate is the augmentation template. Defaults to
	// [contextualDefaultTemplate]. Custom templates must declare
	// {{.Context}} and {{.Query}}.
	PromptTemplate *chatclient.Template

	// EmptyContextPromptTemplate is the response template used when no
	// documents are retrieved AND AllowEmptyContext is false. Defaults
	// to [contextualEmptyContextTemplate].
	EmptyContextPromptTemplate *chatclient.Template

	// AllowEmptyContext, when true, returns the user's query unchanged
	// if no documents were retrieved instead of synthesizing the
	// empty-context fallback. Defaults to false.
	AllowEmptyContext bool

	// Formatter renders each retrieved document. The default [rag.TextFormatter]
	// rejects media with [rag.ErrUnsupportedMedia].
	Formatter rag.DocumentFormatter

	// MaxContextTokens limits the encoded evidence block. Zero leaves context
	// unbounded. A positive value requires TokenCounter. Only complete
	// candidates are included, in retrieval order.
	MaxContextTokens int

	// TokenCounter measures the exact encoded evidence block against
	// MaxContextTokens.
	TokenCounter tokenizer.TextCounter
}

ContextualAugmenterConfig fixes formatting, citation, and token-budget policy for generation context.

type Evidence added in v0.20.0

type Evidence struct {
	Candidates rag.Candidates
	Citations  rag.Citations
}

Evidence is the retrieval result for one prepared request. It belongs to RAG and remains available independently of model success or stream consumption.

type MultiQueryExpander

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

MultiQueryExpander asks a model for alternate query phrasings.

func NewMultiQueryExpander

func NewMultiQueryExpander(config MultiQueryExpanderConfig) (*MultiQueryExpander, error)

NewMultiQueryExpander validates query-count bounds and freezes model prompt policy.

func (*MultiQueryExpander) Expand

func (m *MultiQueryExpander) Expand(ctx context.Context, query rag.Query) ([]rag.Query, error)

Expand asks the LLM for distinct variants and turns them into rag.Query values. Empty, duplicate, and original-query entries do not consume the configured result limit. No usable variant returns rag.ErrEmptyExpansion.

type MultiQueryExpanderConfig

type MultiQueryExpanderConfig struct {
	// Model produces the variants. Required.
	Model corechat.Model

	// IncludeOriginal prepends the original query to the variant list.
	// Defaults to false.
	IncludeOriginal bool

	// NumberOfQueries is the variant count requested from the model.
	// Defaults to [DefaultMultiQueryCount]. Must be ≥ 0.
	NumberOfQueries int

	// PromptTemplate is the LLM prompt. Defaults to
	// [multiExpanderDefaultTemplate]. Custom templates must declare
	// {{.Number}} and {{.Query}}.
	PromptTemplate *chatclient.Template
}

MultiQueryExpanderConfig binds one chat model to a bounded alternative-query policy.

type PreparedRequest added in v0.19.0

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

PreparedRequest owns an immutable augmented request and its retrieval evidence. Its zero value is invalid. Prepare once, then pass the complete model or tool orchestration to Call or Stream; downstream continuations never retrieve again.

func (PreparedRequest) Call added in v0.19.0

Call runs the prepared request through next. Evidence remains on the prepared request; this call never retrieves again, including on a model failure.

func (PreparedRequest) Evidence added in v0.20.0

func (p PreparedRequest) Evidence() Evidence

Evidence returns independently owned candidates and their ordered citations. Complete documents are never added to model response metadata implicitly.

func (PreparedRequest) Stream added in v0.19.0

Stream starts model work lazily. Evidence remains on the prepared request. Preparation has already completed; stopping iteration synchronously releases the downstream stream through its normal iterator contract.

type Preparer added in v0.19.0

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

Preparer owns retrieval and augmentation at the start of a user turn. It is immutable after construction and safe for concurrent use when its Retriever and Augmenter are safe for concurrent use. Unchanged augmentation preserves every user Part. Text rewrites require exactly one text Part and preserve all other Parts and their relative positions; ambiguous rewrites fail with rag.ErrInvalidAugmentation before calling the model.

Example
preparer, err := ragchat.NewPreparer(ragchat.PreparerConfig{
	Retriever: rag.RetrieverFunc(func(context.Context, rag.Query) (rag.Candidates, error) {
		return rag.Candidates{{Document: &document.Document{Text: "Scope provides AI infrastructure."}}}, nil
	}),
	Augmenter: rag.IdentityAugmenter(),
})
if err != nil {
	panic(err)
}
ctx := context.Background()
request, err := chat.NewRequest(chat.NewUserMessage(chat.NewTextPart("What is Scope?")))
if err != nil {
	panic(err)
}
prepared, err := preparer.Prepare(ctx, request)
if err != nil {
	panic(err)
}
model := chat.ModelFunc(func(context.Context, *chat.Request) (*chat.Response, error) {
	return textResponse("AI infrastructure"), nil
})
response, err := prepared.Call(ctx, model)
if err != nil {
	panic(err)
}
candidates := prepared.Evidence().Candidates
fmt.Println(response.Text(), len(candidates))
Output:
AI infrastructure 1

func NewPreparer added in v0.19.0

func NewPreparer(config PreparerConfig) (*Preparer, error)

NewPreparer freezes the retrieval and augmentation policies.

func (*Preparer) Prepare added in v0.19.0

func (p *Preparer) Prepare(ctx context.Context, request *corechat.Request) (PreparedRequest, error)

Prepare snapshots request and retrieves evidence for its final user message. Retrieval and augmentation finish before any model or tool execution begins.

type PreparerConfig added in v0.19.0

type PreparerConfig struct {
	// Retriever fetches documents for the latest user message. Required.
	Retriever rag.Retriever

	// Augmenter folds retrieved documents into the outgoing user message.
	// Required; use [rag.IdentityAugmenter] for retrieval without prompt changes.
	Augmenter rag.Augmenter
}

PreparerConfig makes retrieval and augmentation independently replaceable while requiring both policies explicitly.

type Reranker

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

Reranker reorders candidates using a chat model's native structured output and replaces provider-specific retrieval scores with normalized relevance scores.

func NewReranker

func NewReranker(config RerankerConfig) (*Reranker, error)

NewReranker validates ranking policy and freezes model options.

func (*Reranker) Refine

func (r *Reranker) Refine(ctx context.Context, query rag.Query, candidates rag.Candidates) (rag.Candidates, error)

Refine ranks every candidate. Empty input is returned without a model call; non-empty model output must cover each input index exactly once.

type RerankerConfig

type RerankerConfig struct {
	// Model ranks candidates. Required.
	Model corechat.Model

	// PromptTemplate defaults to [chatRerankerDefaultTemplate]. Custom
	// templates must declare {{.Query}} and {{.Candidates}}.
	PromptTemplate *chatclient.Template

	// Formatter renders candidate content. The default [rag.TextFormatter]
	// rejects media with [rag.ErrUnsupportedMedia].
	Formatter rag.DocumentFormatter
}

RerankerConfig binds explicit prompt, output, and candidate limits to a provider-neutral chat model.

type RewriteTransformer

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

RewriteTransformer tightens a query for a configured search target.

func NewRewriteTransformer

func NewRewriteTransformer(config RewriteTransformerConfig) (*RewriteTransformer, error)

NewRewriteTransformer freezes options while preserving query-scoped values.

func (*RewriteTransformer) Transform

func (r *RewriteTransformer) Transform(ctx context.Context, query rag.Query) (rag.Query, error)

Transform asks the LLM to rewrite the query and returns a clone with Text replaced by the model output.

type RewriteTransformerConfig

type RewriteTransformerConfig struct {
	// Model performs the rewrite. Required.
	Model corechat.Model

	// TargetSearchSystem names the downstream search engine — "vector
	// store", "web search engine", "database", etc. Required.
	TargetSearchSystem string

	// PromptTemplate is the LLM prompt. Defaults to
	// [rewriteDefaultTemplate]. Custom templates must declare
	// {{.Target}} and {{.Query}}.
	PromptTemplate *chatclient.Template
}

RewriteTransformerConfig binds one model and prompt policy to query rewriting.

type TranslationTransformer

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

TranslationTransformer translates queries into a configured language.

func NewTranslationTransformer

func NewTranslationTransformer(config TranslationTransformerConfig) (*TranslationTransformer, error)

NewTranslationTransformer validates target-language and model policy once.

func (*TranslationTransformer) Transform

func (t *TranslationTransformer) Transform(ctx context.Context, query rag.Query) (rag.Query, error)

Transform asks the LLM to translate the query and returns a clone with Text replaced by the model output.

type TranslationTransformerConfig

type TranslationTransformerConfig struct {
	// Model performs the translation. Required.
	Model corechat.Model

	// TargetLanguage is the language the embedding model expects —
	// "English", "Chinese", "Spanish", etc. Required.
	TargetLanguage string

	// PromptTemplate is the LLM prompt. Defaults to
	// [translationDefaultTemplate]. Custom templates must declare
	// {{.Target}} and {{.Query}}.
	PromptTemplate *chatclient.Template
}

TranslationTransformerConfig binds one model and target language without changing retrieval-scoped query values.

Jump to

Keyboard shortcuts

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