history

package
v0.10.0 Latest Latest
Warning

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

Go to latest
Published: Aug 30, 2026 License: Apache-2.0 Imports: 10 Imported by: 0

Documentation

Overview

Package history defines provider-neutral conversation history contracts and model middleware.

Reader, Writer, Clearer, and Store use core/chat protocol values directly. WindowStore is an explicit read-side retention decorator. It merges system messages and retains only complete user-led turns, so assistant Tool calls, Tool results, reasoning, and final text cannot be split at the read boundary. Optional cross-conversation and replacement capabilities remain separate interfaces. The zero-value-ready reference implementation lives in core/history/inmemory.

Conversation IDs are runtime scope carried with WithConversationID, not serialized request metadata. Middleware binds that scope to model calls.

Writes preserve message order within one call. Conversation listing is an optional capability and returns unique IDs in lexical order. Concurrent writes and writes through distinct Store instances have no common ordering guarantee unless a backend documents one.

Persistent backends live in independent leaf modules so database drivers do not enter Core:

historystores/postgres/  — PostgreSQL (pgx + JSONB)
historystores/redis/     — Redis (RPUSH / LRANGE lists)
historystores/mongodb/   — MongoDB (document per message)
historystores/cassandra/ — Cassandra (TIMEUUID clustering key)
historystores/neo4j/     — Neo4j (node per message)
historystores/cosmosdb/  — Azure Cosmos DB (NoSQL API)

Every backend reads and writes only the current core/chat tagged JSON wire. Backend data migration is an explicit application operation, not a library runtime branch.

Example
package main

import (
	"fmt"

	"github.com/Tangerg/scope/core/history"
)

func main() {
	conversationID, err := history.NewConversationID("customer-42")
	if err != nil {
		panic(err)
	}
	fmt.Println(conversationID)
}
Output:
customer-42

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	ErrInvalidWindow  = errors.New("history: invalid message window")
	ErrWindowTooSmall = errors.New("history: message window too small")
)
View Source
var ErrInvalidConversationID = errors.New("history: invalid conversation ID")
View Source
var ErrNilStore = errors.New("history: nil store")
View Source
var ErrNilStream = errors.New("history: middleware: nil stream sequence")

Functions

func WithConversationID

func WithConversationID(ctx context.Context, conversationID ConversationID) context.Context

WithConversationID returns a child context carrying the history partition key for one model call. An empty ID deliberately shadows and disables an ID inherited from a parent context. As with context.WithValue, ctx must not be nil.

Types

type Clearer

type Clearer interface {
	// Clear removes the complete conversation and is idempotent when it is
	// already absent. Implementations must honor ctx.
	Clear(ctx context.Context, conversationID ConversationID) error
}

Clearer removes every message for one conversation.

type ConversationID

type ConversationID string

ConversationID identifies one history partition. Its zero value is invalid. Use NewConversationID when converting runtime input; string constants may be converted directly when the value is known at compile time.

func ConversationIDFromContext

func ConversationIDFromContext(ctx context.Context) (ConversationID, bool)

ConversationIDFromContext returns the ID carried by ctx. Empty values behave as absent so middleware can transparently skip history for unbound calls.

func NewConversationID

func NewConversationID(value string) (ConversationID, error)

func (ConversationID) String

func (c ConversationID) String() string

func (ConversationID) Validate

func (c ConversationID) Validate() error

type Lister

type Lister interface {
	// Conversations returns detached, unique identifiers in lexical order. An
	// empty store yields a non-nil empty slice; concurrent writes may appear or
	// not according to the backend's snapshot boundary.
	Conversations(ctx context.Context) ([]ConversationID, error)
}

Lister enumerates unique conversation IDs in lexical order. Implementations return a non-nil empty slice when no conversations exist. Concurrent mutations may affect the result.

type Middleware

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

Middleware replays and persists history around synchronous and streaming chat capabilities. It is immutable after construction and safe for concurrent use when its Store is safe for concurrent use.

func NewMiddleware

func NewMiddleware(store ReadWriter) (Middleware, error)

func (Middleware) Call

func (m Middleware) Call(next chat.Model) chat.Model

Call is a chat.CallMiddleware. The response result is the canonical assistant message persisted to history.

func (Middleware) Stream

func (m Middleware) Stream(next chat.Streamer) chat.Streamer

Stream is a chat.StreamMiddleware. History I/O remains lazy: no read occurs until the returned sequence is iterated. Fresh input and the accumulated assistant response are persisted only after natural, error-free completion.

type ReadWriter

type ReadWriter interface {
	Reader
	Writer
}

ReadWriter combines the capabilities required by components that replay and append history without owning retention or deletion policy.

type Reader

type Reader interface {
	// Read returns a detached snapshot in stored order. Unknown conversations
	// yield a non-nil empty slice; implementations honor ctx and never expose
	// mutable backing storage.
	Read(ctx context.Context, conversationID ConversationID) ([]chat.Message, error)
}

Reader returns the messages to replay for one conversation. Implementations return a non-nil empty slice for an unknown conversation and transfer ownership of returned protocol values to the caller.

type Store

type Store interface {
	ReadWriter
	Clearer
}

Store is the ordinary per-conversation read/write/clear contract. Optional cross-conversation or retention capabilities remain separate interfaces.

type WindowStore

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

WindowStore projects reads to at most limit messages while preserving a merged system message followed by a suffix of complete conversation turns. A user message starts a turn; every following assistant and tool message remains in that turn until the next user message. Writes and clears pass through to the authoritative Store. Read returns ErrWindowTooSmall rather than splitting the newest complete turn, and the merged system message counts toward the configured limit.

func NewWindowStore

func NewWindowStore(store Store, limit int) (WindowStore, error)

func (WindowStore) Clear

func (w WindowStore) Clear(ctx context.Context, conversationID ConversationID) error

func (WindowStore) Read

func (w WindowStore) Read(ctx context.Context, conversationID ConversationID) ([]chat.Message, error)

func (WindowStore) Write

func (w WindowStore) Write(ctx context.Context, conversationID ConversationID, messages ...chat.Message) error

type Writer

type Writer interface {
	// Write validates and snapshots the full argument batch before appending it
	// in argument order. A returned error must not conceal a partially accepted
	// prefix unless the concrete store documents an external atomicity limit.
	Write(ctx context.Context, conversationID ConversationID, messages ...chat.Message) error
}

Writer appends messages to one conversation. Implementations preserve the order of messages within each call, validate and snapshot them before returning, and prevent later caller mutation from altering stored history. The relative order of concurrent calls and writes issued through distinct Store instances is implementation-defined.

Directories

Path Synopsis
Package inmemory provides a zero-value-ready in-process history store.
Package inmemory provides a zero-value-ready in-process history store.
Package storetest provides reusable conformance checks for history stores.
Package storetest provides reusable conformance checks for history stores.

Jump to

Keyboard shortcuts

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