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 (*InMemory) Append ¶
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 ¶
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 ¶
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.