memorylayer

package
v0.0.2 Latest Latest
Warning

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

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

Documentation

Overview

Package memorylayer stores chat threads and transcripts in MemoryLayer instead of on local disk, so every process that shares a MemoryLayer sees the same conversation — the agent worker and any number of attached frontends.

Its chat/catalog codec stays local because the ecosystem messaging spec already owns the lossless generic-map conversion. Request delivery is pluggable: direct HTTP for standalone deployments, or a MemoryLayer SDK Transport for front doors such as Aether proxy_http.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type AgentSpecificationProvider

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

AgentSpecificationProvider maps MemoryLayer's typed current heads to the OSS subagent definition contract. MemoryLayer remains authoritative: this adapter neither caches nor falls back to a filesystem catalog.

func NewAgentSpecificationProvider

func NewAgentSpecificationProvider(cfg Config, providerOptions ...AgentSpecificationProviderOption) (*AgentSpecificationProvider, error)

func (*AgentSpecificationProvider) LoadWorkspace

func (p *AgentSpecificationProvider) LoadWorkspace(ctx context.Context, workspaceID string) ([]subagent.Definition, error)

type AgentSpecificationProviderOption

type AgentSpecificationProviderOption func(*agentSpecificationProviderConfig)

func WithAgentSpecificationTransport

func WithAgentSpecificationTransport(transport memorylayersdk.Transport) AgentSpecificationProviderOption

WithAgentSpecificationTransport routes requests over a MemoryLayer SDK transport such as the Aether proxy transport.

type CatalogProvider

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

CatalogProvider loads a workspace's enabled skills and launchable MCP servers from MemoryLayer into the harness's protocol-neutral catalog types. Tools are intentionally empty: MemoryLayer has no tools-list endpoint; tools continue to come from local registration, MCP discovery, or another provider.

func NewCatalogProvider

func NewCatalogProvider(cfg Config) (*CatalogProvider, error)

func (*CatalogProvider) Load

Load satisfies catalog.Provider using the configured default workspace.

func (*CatalogProvider) LoadWorkspace

func (p *CatalogProvider) LoadWorkspace(ctx context.Context, workspace string) (catalog.Catalog, error)

LoadWorkspace loads a catalog for one logical workspace. It is additive to catalog.Provider so multi-workspace hosts can resolve the catalog per turn without sharing one project's skills or MCP configuration with another.

type Config

type Config struct {
	// BaseURL is the MemoryLayer server root, e.g. http://127.0.0.1:61001.
	// It is optional when Transport is set.
	BaseURL string
	// Transport routes requests through a non-HTTP front door such as Aether's
	// proxy_http service transport. It takes precedence over BaseURL.
	Transport memorylayersdk.Transport
	// APIKey is sent as a bearer token when set. A local OSS MemoryLayer needs
	// none.
	APIKey string
	// Workspace scopes threads and messages.
	Workspace string
	// Ownership is "workspace" (default) or "user".
	Ownership string
	// Window caps messages loaded per thread.
	Window int
	// HTTPClient overrides the default client (timeouts, transport, tracing).
	HTTPClient *http.Client
}

Config configures the MemoryLayer-backed store.

type PromptNoteProvider

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

PromptNoteProvider loads the current, workspace-scoped prompt-note heads via MemoryLayer's typed Go SDK. The server remains the sole authority; this adapter neither caches nor falls back to local files.

func NewPromptNoteProvider

func NewPromptNoteProvider(cfg Config, providerOptions ...PromptNoteProviderOption) (*PromptNoteProvider, error)

NewPromptNoteProvider constructs a typed MemoryLayer prompt-note adapter.

func (*PromptNoteProvider) LoadWorkspace

func (p *PromptNoteProvider) LoadWorkspace(ctx context.Context, workspaceID string) ([]promptnotes.Note, error)

LoadWorkspace retrieves all current heads within a bounded five-page window. Exceeding that operational bound is explicit rather than silently truncating authoritative guidance.

type PromptNoteProviderOption

type PromptNoteProviderOption func(*promptNoteProviderConfig)

PromptNoteProviderOption configures the typed prompt-note client without changing the legacy chat/catalog Config used elsewhere in this package.

func WithPromptNoteTransport

func WithPromptNoteTransport(transport memorylayersdk.Transport) PromptNoteProviderOption

WithPromptNoteTransport routes prompt-note requests over a MemoryLayer SDK transport such as the Aether proxy transport. When set, Config.BaseURL is not used for request delivery.

type Recaller

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

Recaller is the semantic-memory half of the MemoryLayer integration: it searches the memories MemoryLayer distilled from past conversations, so a turn can be given what the agent already knows without that content sitting in the thread's transcript.

Memories are not written here. MemoryLayer decomposes stored chat threads into memories on its own schedule, and Store already persists the transcript — so the write path is "save the conversation", and extraction is the server's job. See AppendThreadMessages for why its half of the seam is a no-op.

func NewRecaller

func NewRecaller(cfg Config) (*Recaller, error)

NewRecaller builds a recaller against the same MemoryLayer as a Store.

func (*Recaller) AppendThreadMessages

func (r *Recaller) AppendThreadMessages(_ context.Context, _ tools.MemoryAuthority, _, _, _ string, _ []protocol.ChatMessage) error

AppendThreadMessages is a deliberate no-op.

The seam exists because a distribution may commit the turn to its memory backend separately from persisting the transcript — sahara does, because its history store is local and MemoryLayer only ever sees the auto-commit. Here the history store IS MemoryLayer, so the transcript has already been written by the time this would run; doing it again would duplicate every message.

func (*Recaller) EnsureThread

func (r *Recaller) EnsureThread(ctx context.Context, _ tools.MemoryAuthority, spec turn.ThreadSpec) (string, error)

EnsureThread implements turn.ThreadRegistrar against MemoryLayer's native chat-thread hierarchy. An empty ThreadID asks MemoryLayer to mint a canonical id while atomically recording parent_thread; the caller must adopt the returned id. MemoryLayer intentionally does not expose caller-owned ids, so a non-empty ThreadID can only ensure an already-existing thread.

auth is ignored for the same reason as Recall: the OSS server has no OBO grant issuer. Proprietary integrations can carry authority through their own ThreadRegistrar while sharing the runner's canonical-id behavior.

func (*Recaller) MemoryProviderName

func (*Recaller) MemoryProviderName() string

MemoryProviderName labels content-free recall transparency events.

func (*Recaller) Recall

func (r *Recaller) Recall(ctx context.Context, _ tools.MemoryAuthority, workspace, query string, limit int) ([]tools.MemoryHit, error)

Recall returns memories relevant to query. An empty query is not an error — it asks for the most relevant memories with nothing to match on, which the server answers with recency — but it is rarely useful, so callers that want query-driven recall must pass the turn's input.

auth is accepted to satisfy the MemoryService seam and ignored: the OSS distribution has no authority-grant issuer, so there is no on-behalf-of context to forward (see D7 in the design doc).

type RefinementRecordStore

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

RefinementRecordStore adapts the neutral append-only refinement.Store to MemoryLayer's typed resource API. It does not apply proposals or mirror live Aether task state.

func NewRefinementRecordStore

func NewRefinementRecordStore(cfg Config, storeOptions ...RefinementRecordStoreOption) (*RefinementRecordStore, error)

func (*RefinementRecordStore) Append

func (s *RefinementRecordStore) Append(ctx context.Context, workspaceID, operationID string, request refinement.AppendRequest) (refinement.AppendResult, error)

func (*RefinementRecordStore) Get

func (s *RefinementRecordStore) Get(ctx context.Context, workspaceID, recordID string) (refinement.Record, error)

func (*RefinementRecordStore) Query

func (s *RefinementRecordStore) Query(ctx context.Context, workspaceID string, query refinement.Query) (refinement.Page, error)

type RefinementRecordStoreOption

type RefinementRecordStoreOption func(*refinementRecordStoreConfig)

func WithRefinementRecordTransport

func WithRefinementRecordTransport(transport memorylayersdk.Transport) RefinementRecordStoreOption

type RefinementResourceEditor

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

RefinementResourceEditor applies conflict-checked prompt-note, memory, agent-specification, and skill-manifest edits against MemoryLayer's revisioned native resource APIs.

func NewRefinementResourceEditor

func NewRefinementResourceEditor(cfg Config, editorOptions ...RefinementResourceEditorOption) (*RefinementResourceEditor, error)

func (*RefinementResourceEditor) Apply

func (e *RefinementResourceEditor) Apply(ctx context.Context, workspaceID, operationID string, edit refinement.Edit) (refinement.Mutation, error)

type RefinementResourceEditorOption

type RefinementResourceEditorOption func(*refinementResourceEditorConfig)

func WithRefinementResourceTransport

func WithRefinementResourceTransport(transport memorylayersdk.Transport) RefinementResourceEditorOption

type Store

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

Store keeps chat threads and transcripts in MemoryLayer. It satisfies both the history-store seam (LoadHistory/SaveHistory/DeleteHistory) and the thread-index seam (List/Create/Touch/Rename/Delete), so a UI wired to it shares one conversation with every other process on the same MemoryLayer.

func New

func New(cfg Config) (*Store, error)

New builds a MemoryLayer-backed store.

func (*Store) Create

func (s *Store) Create() (threadindex.Session, error)

Create makes a new thread. The id comes from the server, which mints its own and ignores any the client supplies.

func (*Store) CreateWorkspaceThread

func (s *Store) CreateWorkspaceThread(workspaceID string) (threadindex.Session, error)

CreateWorkspaceThread creates and caches a server-minted thread in one workspace.

func (*Store) Delete

func (s *Store) Delete(id string) error

Delete removes the thread and its transcript.

func (*Store) DeleteHistory

func (s *Store) DeleteHistory(ctx context.Context, threadID string) error

DeleteHistory clears a thread's transcript, message by message. Deleting the thread instead would drop it from the switcher, and "clear" means an empty conversation rather than a vanished one.

func (*Store) DeleteWorkspaceHistory

func (s *Store) DeleteWorkspaceHistory(ctx context.Context, workspaceID, threadID string) error

DeleteWorkspaceHistory clears only the addressed workspace/thread transcript.

func (*Store) DeleteWorkspaceThread

func (s *Store) DeleteWorkspaceThread(workspaceID, id string) error

DeleteWorkspaceThread removes only the addressed workspace's thread.

func (*Store) EnsureWorkspace

func (s *Store) EnsureWorkspace(ctx context.Context, workspaceID string) error

EnsureWorkspace makes a logical workspace available for adjacent typed resources (for example workspace views) without requiring a chat write first.

func (*Store) List

func (s *Store) List() []threadindex.Session

List returns the known threads, most recently updated first. It serves the cached snapshot: it is called from UI render paths that must not block on the network.

func (*Store) ListWorkspace

func (s *Store) ListWorkspace(workspaceID string) []threadindex.Session

ListWorkspace returns the cached threads for workspaceID without network I/O.

func (*Store) LoadHistory

func (s *Store) LoadHistory(ctx context.Context, threadID string) ([]protocol.ChatMessage, error)

LoadHistory returns the thread's transcript in chronological order. A thread MemoryLayer does not know about is empty rather than an error, matching the filesystem store: the first turn of a new thread reads before it writes.

func (*Store) LoadWorkspaceHistory

func (s *Store) LoadWorkspaceHistory(ctx context.Context, workspaceID, threadID string) ([]protocol.ChatMessage, error)

LoadWorkspaceHistory loads a transcript under the composite workspace/thread identity. The explicit workspace wins over the configured default.

func (*Store) LookupWorkspaceThread

func (s *Store) LookupWorkspaceThread(ctx context.Context, workspaceID, id string) (threadindex.Session, bool, error)

LookupWorkspaceThread reads one thread directly from MemoryLayer and updates the local list cache when it exists. A missing thread is not an error: a scheduled task can be durable in Aether before its first transcript write has caused MemoryLayer to create the addressed thread.

func (*Store) Refresh

func (s *Store) Refresh(ctx context.Context) error

Refresh ensures the workspace exists and reloads the thread list. Call it once at startup; List serves the cached snapshot afterwards.

func (*Store) RefreshWorkspace

func (s *Store) RefreshWorkspace(ctx context.Context, workspaceID string) error

RefreshWorkspace ensures and reloads one workspace's thread-list cache.

func (*Store) Rename

func (s *Store) Rename(id, titleText string) error

Rename sets a stable display title.

func (*Store) RenameWorkspaceThread

func (s *Store) RenameWorkspaceThread(workspaceID, id, titleText string) error

RenameWorkspaceThread sets a title within one workspace.

func (*Store) SaveHistory

func (s *Store) SaveHistory(ctx context.Context, threadID string, messages []protocol.ChatMessage) error

SaveHistory persists any messages the thread does not already hold. The harness hands over the full transcript each turn while MemoryLayer's API appends, so this diffs by message id and sends only what is new.

func (*Store) SaveWorkspaceHistory

func (s *Store) SaveWorkspaceHistory(ctx context.Context, workspaceID, threadID string, messages []protocol.ChatMessage) error

SaveWorkspaceHistory appends only messages not already observed in the composite workspace/thread cache.

func (*Store) Touch

func (s *Store) Touch(id, firstUserText string) error

Touch bumps the thread's updated time and derives an initial title from the first user message, mirroring the filesystem index.

func (*Store) TouchWorkspaceThread

func (s *Store) TouchWorkspaceThread(workspaceID, id, firstUserText string) error

TouchWorkspaceThread updates one workspace's cached/server thread metadata.

type WorkspaceBindingValidator

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

WorkspaceBindingValidator reads MemoryLayer's durable workspace-view and observer heads. It deliberately applies no principal policy: Aether (or the standalone same-window adapter) decides who may bind the exact resource.

func NewWorkspaceBindingValidator

func NewWorkspaceBindingValidator(cfg Config) (*WorkspaceBindingValidator, error)

NewWorkspaceBindingValidator constructs the read-only MemoryLayer authority adapter used by enterprise compositions. It does not create workspaces or publish observations.

func (*WorkspaceBindingValidator) ValidateExecutionBinding

func (v *WorkspaceBindingValidator) ValidateExecutionBinding(ctx context.Context, binding spec.ExecutionBinding) error

ValidateExecutionBinding verifies the durable view and latest exact observer/host mapping. It never substitutes another observer, host, root, or revision for the binding supplied by the caller.

type WorkspaceViewPublisher

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

WorkspaceViewPublisher stores the durable identity and latest observation of local Sahara workspace views in MemoryLayer.

func NewWorkspaceViewPublisher

func NewWorkspaceViewPublisher(cfg Config, store *Store) (*WorkspaceViewPublisher, error)

NewWorkspaceViewPublisher constructs the typed workspace-view adapter. store is used to ensure a logical workspace exists before its first view is written.

func (*WorkspaceViewPublisher) AuthorizeExecutionBinding

AuthorizeExecutionBinding verifies the durable view and the latest observer-specific host mapping. It never accepts a different host/root as a fallback, even when another observation for the same logical view exists.

func (*WorkspaceViewPublisher) PublishWorkspaceView

func (p *WorkspaceViewPublisher) PublishWorkspaceView(
	ctx context.Context,
	view workspacepkg.View,
	observation workspacepkg.ViewObservation,
) error

PublishWorkspaceView upserts the durable view descriptor and then publishes the observer's monotonic latest-state cursor.

Jump to

Keyboard shortcuts

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