memory

package
v0.1.0-p8a.1 Latest Latest
Warning

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

Go to latest
Published: Aug 10, 2026 License: MIT Imports: 20 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func IsCommittedAppendError

func IsCommittedAppendError(err error) bool

IsCommittedAppendError reports whether err preserves a committed append.

func IsIndeterminateAppendError

func IsIndeterminateAppendError(err error) bool

IsIndeterminateAppendError reports whether err is unsafe to retry without first recovering canonical history.

func MigrateFromJSON

func MigrateFromJSON(
	ctx context.Context, sessionsDir string, store Store,
) (int, error)

MigrateFromJSON reads legacy sessions/*.json files from sessionsDir, writes them into the Store, and renames each migrated file to .json.migrated as a backup. Returns the number of sessions migrated.

Files that fail to parse are logged and skipped. Already-migrated files (.json.migrated) are ignored, making the function idempotent.

Types

type CommittedAppendError

type CommittedAppendError struct {
	Err error
}

CommittedAppendError reports that the JSONL record was durably appended, but a later close or metadata-finalization step failed. Callers must recover from the canonical history instead of blindly retrying the append.

func (*CommittedAppendError) Error

func (e *CommittedAppendError) Error() string

func (*CommittedAppendError) Unwrap

func (e *CommittedAppendError) Unwrap() error

type HistoryRevision

type HistoryRevision struct {
	Revision  uint64
	Count     int
	Skip      int
	Dirty     bool
	FileSize  int64
	ModTimeNS int64
}

HistoryRevision identifies the canonical visible history for a session. Dirty is durable evidence that a multi-file history mutation did not finish and consumers must rebuild from the canonical store before trusting a cache.

type HistoryRevisionStore

type HistoryRevisionStore interface {
	GetHistoryRevision(ctx context.Context, sessionKey string) (HistoryRevision, error)
}

HistoryRevisionStore is implemented by stores that can expose a cheap, durable identity for their canonical session history.

type IndeterminateAppendError

type IndeterminateAppendError struct {
	Err error
}

IndeterminateAppendError reports that writing began, but file or directory durability could not be confirmed. The append must not be published as durable, and retrying it may duplicate a record that survived the failure.

func (*IndeterminateAppendError) Error

func (e *IndeterminateAppendError) Error() string

func (*IndeterminateAppendError) Unwrap

func (e *IndeterminateAppendError) Unwrap() error

type JSONLStore

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

JSONLStore implements Store using append-only JSONL files.

Each session is stored as two files:

{sanitized_key}.jsonl      — one JSON-encoded message per line, append-only
{sanitized_key}.meta.json  — session metadata (summary, logical truncation offset)

Messages are never physically deleted from the JSONL file. Instead, TruncateHistory records a "skip" offset in the metadata file and GetHistory ignores lines before that offset. This keeps all writes append-only, which is both fast and crash-safe.

func NewJSONLStore

func NewJSONLStore(dir string) (*JSONLStore, error)

NewJSONLStore creates a new JSONL-backed store rooted at dir.

func (*JSONLStore) AddFullMessage

func (s *JSONLStore) AddFullMessage(
	ctx context.Context, sessionKey string, msg providers.Message,
) error

func (*JSONLStore) AddMessage

func (s *JSONLStore) AddMessage(
	ctx context.Context, sessionKey, role, content string,
) error

func (*JSONLStore) Close

func (s *JSONLStore) Close() error

func (*JSONLStore) Compact

func (s *JSONLStore) Compact(
	_ context.Context, sessionKey string,
) error

Compact physically rewrites the JSONL file, dropping all logically skipped lines. This reclaims disk space that accumulates after repeated TruncateHistory calls.

It is safe to call at any time; if there is nothing to compact (skip == 0) the method returns immediately.

func (*JSONLStore) GetHistory

func (s *JSONLStore) GetHistory(
	_ context.Context, sessionKey string,
) ([]providers.Message, error)

func (*JSONLStore) GetHistoryRevision

func (s *JSONLStore) GetHistoryRevision(
	_ context.Context,
	sessionKey string,
) (HistoryRevision, error)

GetHistoryRevision returns a cheap durable identity while holding the same per-session lock used by writers, so callers never observe an in-process mutation halfway through.

func (*JSONLStore) GetSessionMeta

func (s *JSONLStore) GetSessionMeta(_ context.Context, sessionKey string) (SessionMeta, error)

GetSessionMeta returns the current metadata snapshot for sessionKey.

func (*JSONLStore) GetSummary

func (s *JSONLStore) GetSummary(
	_ context.Context, sessionKey string,
) (string, error)

func (*JSONLStore) ListSessions

func (s *JSONLStore) ListSessions() []string

ListSessions returns all known session keys by reading .meta.json files.

func (*JSONLStore) PromoteAliasHistory

func (s *JSONLStore) PromoteAliasHistory(
	_ context.Context,
	sessionKey string,
	scope json.RawMessage,
	aliases []string,
) (bool, error)

PromoteAliasHistory atomically promotes the first non-empty alias session into the canonical session when the canonical session is still empty.

Main-session aliases (e.g. "agent:main:main" or its opaque form) are skipped during promotion. The main session is a shared global fallback and promoting its history into individual sessions would attach stale messages to every new Web UI session (issue #2972).

func (*JSONLStore) ResolveSessionKey

func (s *JSONLStore) ResolveSessionKey(_ context.Context, sessionKey string) (string, bool, error)

ResolveSessionKey returns the canonical session key for a candidate key. It short-circuits direct canonical keys when possible, then scans metadata once to resolve aliases or canonical metadata keys.

func (*JSONLStore) SetHistory

func (s *JSONLStore) SetHistory(
	_ context.Context,
	sessionKey string,
	history []providers.Message,
) error

func (*JSONLStore) SetSummary

func (s *JSONLStore) SetSummary(
	_ context.Context, sessionKey, summary string,
) error

func (*JSONLStore) TruncateHistory

func (s *JSONLStore) TruncateHistory(
	_ context.Context, sessionKey string, keepLast int,
) error

func (*JSONLStore) UpsertSessionMeta

func (s *JSONLStore) UpsertSessionMeta(
	_ context.Context,
	sessionKey string,
	scope json.RawMessage,
	aliases []string,
) error

UpsertSessionMeta stores structured session metadata while preserving summary/count/skip timestamps maintained by the core JSONL store.

type SessionMeta

type SessionMeta struct {
	Key       string          `json:"key"`
	Summary   string          `json:"summary"`
	Skip      int             `json:"skip"`
	Count     int             `json:"count"`
	CreatedAt time.Time       `json:"created_at"`
	UpdatedAt time.Time       `json:"updated_at"`
	Scope     json.RawMessage `json:"scope,omitempty"`
	Aliases   []string        `json:"aliases,omitempty"`
	// HistoryRevision changes whenever the visible canonical history changes.
	// HistoryDirty remains set across crashes during multi-file mutations.
	HistoryRevision      uint64 `json:"history_revision,omitempty"`
	HistoryDirty         bool   `json:"history_dirty,omitempty"`
	HistoryHasPrevious   bool   `json:"history_has_previous,omitempty"`
	HistoryPreviousCount int    `json:"history_previous_count,omitempty"`
	HistoryPreviousSkip  int    `json:"history_previous_skip,omitempty"`
	HistoryTargetDigest  string `json:"history_target_digest,omitempty"`
}

SessionMeta holds per-session metadata stored in a .meta.json file.

Scope is stored as raw JSON so pkg/memory can stay decoupled from the higher-level session package while still preserving structured scope data.

type Store

type Store interface {
	// AddMessage appends a simple text message to a session.
	AddMessage(ctx context.Context, sessionKey, role, content string) error

	// AddFullMessage appends a complete message (with tool calls, etc.) to a session.
	AddFullMessage(ctx context.Context, sessionKey string, msg providers.Message) error

	// GetHistory returns all messages for a session in insertion order.
	// Returns an empty slice (not nil) if the session does not exist.
	GetHistory(ctx context.Context, sessionKey string) ([]providers.Message, error)

	// GetSummary returns the conversation summary for a session.
	// Returns an empty string if no summary exists.
	GetSummary(ctx context.Context, sessionKey string) (string, error)

	// SetSummary updates the conversation summary for a session.
	SetSummary(ctx context.Context, sessionKey, summary string) error

	// TruncateHistory removes all but the last keepLast messages from a session.
	// If keepLast <= 0, all messages are removed.
	TruncateHistory(ctx context.Context, sessionKey string, keepLast int) error

	// SetHistory replaces all messages in a session with the provided history.
	SetHistory(ctx context.Context, sessionKey string, history []providers.Message) error

	// Compact reclaims storage by physically removing logically truncated
	// data. Backends that do not accumulate dead data may return nil.
	Compact(ctx context.Context, sessionKey string) error

	// ListSessions returns all known session keys.
	ListSessions() []string

	// Close releases any resources held by the store.
	Close() error
}

Store defines an interface for persistent session storage. Each method is an atomic operation — there is no separate Save() call.

Jump to

Keyboard shortcuts

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