storage

package
v0.5.2 Latest Latest
Warning

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

Go to latest
Published: Apr 6, 2026 License: Apache-2.0 Imports: 3 Imported by: 0

Documentation

Overview

Package storage provides Storage implementations for the goagent memory system.

Storage is responsible solely for persisting and loading the full message slice. It has no knowledge of which messages to discard or how to filter them — that responsibility belongs to the Policy layer.

Example

Example demonstrates creating an InMemory storage, saving a message slice, and loading it back.

package main

import (
	"context"
	"fmt"
	"log"

	"github.com/Germanblandin1/goagent"
	"github.com/Germanblandin1/goagent/memory/storage"
)

func main() {
	s := storage.NewInMemory()
	ctx := context.Background()

	msgs := []goagent.Message{
		goagent.UserMessage("hello"),
		goagent.AssistantMessage("hi"),
	}
	if err := s.Save(ctx, msgs); err != nil {
		log.Fatal(err)
	}

	loaded, err := s.Load(ctx)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(len(loaded))
	fmt.Println(loaded[0].TextContent())
}
Output:
2
hello

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type InMemory

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

InMemory is a thread-safe, in-process Storage backed by a slice. It retains all messages without any limit or eviction policy. Use InMemory when the Policy layer is responsible for deciding which messages to surface (e.g. FixedWindow, TokenWindow).

Copy semantics

Both Load and Save perform a shallow copy of each Message: the Content []ContentBlock slice is copied so that callers may freely append to or reassign the returned Content field without affecting the stored state. However, the binary payloads inside ImageData.Data and DocumentData.Data are NOT deep-copied — those []byte values point to the same underlying memory. Callers must not mutate the bytes of images or documents.

InMemory is safe for concurrent use from multiple goroutines.

func NewInMemory

func NewInMemory() *InMemory

NewInMemory returns an empty InMemory storage.

func (*InMemory) Append

func (s *InMemory) Append(_ context.Context, msgs ...goagent.Message) error

Append adds msgs to the end of the stored history without loading or replacing the existing state. This is O(len(msgs)) regardless of how many messages are already stored. The same copy semantics as Save apply — Content slices are copied, binary payloads are shared.

func (*InMemory) Load

func (s *InMemory) Load(_ context.Context) ([]goagent.Message, error)

Load returns all stored messages in chronological order. The returned slice is a defensive copy; see the type-level doc for the exact copy semantics (Content slice is copied; binary bytes are shared).

func (*InMemory) Save

func (s *InMemory) Save(_ context.Context, msgs []goagent.Message) error

Save replaces the stored message history with msgs. It stores a defensive copy of the provided slice; see the type-level doc for the exact copy semantics (Content slice is copied; binary bytes are shared).

Example

ExampleInMemory_Save shows that Save replaces the entire history — calling Save twice keeps only the second batch.

package main

import (
	"context"
	"fmt"
	"log"

	"github.com/Germanblandin1/goagent"
	"github.com/Germanblandin1/goagent/memory/storage"
)

func main() {
	s := storage.NewInMemory()
	ctx := context.Background()

	_ = s.Save(ctx, []goagent.Message{
		goagent.UserMessage("first"),
	})

	second := []goagent.Message{
		goagent.UserMessage("second"),
		goagent.AssistantMessage("ok"),
	}
	if err := s.Save(ctx, second); err != nil {
		log.Fatal(err)
	}

	loaded, err := s.Load(ctx)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(len(loaded))
	fmt.Println(loaded[0].TextContent())
}
Output:
2
second

type Storage

type Storage interface {
	Load(ctx context.Context) ([]goagent.Message, error)
	Save(ctx context.Context, msgs []goagent.Message) error
	Append(ctx context.Context, msgs ...goagent.Message) error
}

Storage persists and loads the complete message history without any filtering logic. Load always returns all stored messages. Save replaces the entire stored state — the caller decides what subset to save. Append adds messages to the existing history without loading the full state. Implementations must be safe for concurrent use.

Jump to

Keyboard shortcuts

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