memory

package
v0.13.0 Latest Latest
Warning

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

Go to latest
Published: Mar 1, 2026 License: MIT Imports: 11 Imported by: 0

Documentation

Overview

detail_level.go provides shared constants and parsing for the detail_level parameter used across memory and SDD tools.

Three verbosity levels enable progressive disclosure (Anthropic, 2025):

  • summary: minimal tokens — IDs, titles, metadata only
  • standard: default behavior — truncated content snippets
  • full: complete untruncated content for deep analysis

Package memory implements the persistent memory engine for SDD-Hoffy.

It uses SQLite with FTS5 full-text search to store and retrieve observations from AI coding sessions. Adapted from Engram's store (github.com/Gentleman-Programming/engram) with full feature parity.

Index

Constants

View Source
const (
	DetailSummary  = "summary"
	DetailStandard = "standard"
	DetailFull     = "full"
)

Detail level constants.

View Source
const SummaryFooter = "\n---\n💡 Use detail_level: standard or full for more detail."

SummaryFooter is appended to summary-mode responses to guide the AI toward progressive disclosure — fetch more detail only when needed.

Variables

This section is empty.

Functions

func BudgetFooter added in v0.9.0

func BudgetFooter(tokensUsed, budget, shown, total int) string

BudgetFooter returns a footer indicating that a response was truncated due to a token budget constraint. Includes tokens used, budget, and items shown vs total.

func ClassifyTool

func ClassifyTool(toolName string) string

ClassifyTool returns the observation type for a given tool name.

func DetailLevelValues added in v0.9.0

func DetailLevelValues() []string

DetailLevelValues returns the enum values for MCP tool definitions. Use this to avoid duplicating the list across tool definitions.

func EstimateTokens added in v0.9.0

func EstimateTokens(text string) int

EstimateTokens approximates the token count for a text string using the chars/4 heuristic (standard approximation for GPT/Claude tokenizers). Returns 0 for empty strings, at least 1 for non-empty strings. This is O(1) — uses len() only, no iteration.

func ExtractLearnings

func ExtractLearnings(text string) []string

ExtractLearnings parses structured learning items from text. Looks for "## Key Learnings:" or "## Aprendizajes Clave:" sections and extracts numbered or bullet items.

func NavigationHint(showing, total int, hint string) string

NavigationHint returns a one-line footer when results are capped by a limit. Returns an empty string when all results fit (showing >= total) or total is 0. The hint parameter provides tool-specific guidance (e.g., "Use mem_get_observation #ID for full content.").

func Now

func Now() string

Now returns the current time formatted for SQLite.

func ParseDetailLevel added in v0.9.0

func ParseDetailLevel(s string) string

ParseDetailLevel normalizes a detail_level string, defaulting to "standard" for empty or unrecognized values.

func SuggestTopicKey

func SuggestTopicKey(typ, title, content string) string

SuggestTopicKey generates a stable topic key suggestion from type/title/content.

func TokenFooter added in v0.9.0

func TokenFooter(estimatedTokens int) string

TokenFooter returns a one-line footer with the estimated token count for a tool response. Appended to all read-heavy tool responses to give the AI visibility into context cost.

func Truncate

func Truncate(s string, max int) string

Truncate shortens a string to max length with ellipsis.

Types

type AddObservationParams

type AddObservationParams struct {
	SessionID string `json:"session_id"`
	Type      string `json:"type"`
	Title     string `json:"title"`
	Content   string `json:"content"`
	ToolName  string `json:"tool_name,omitempty"`
	Project   string `json:"project,omitempty"`
	Scope     string `json:"scope,omitempty"`
	TopicKey  string `json:"topic_key,omitempty"`
	Namespace string `json:"namespace,omitempty"`
}

AddObservationParams holds the input for creating a new observation.

type AddPromptParams

type AddPromptParams struct {
	SessionID string `json:"session_id"`
	Content   string `json:"content"`
	Project   string `json:"project,omitempty"`
	Namespace string `json:"namespace,omitempty"`
}

AddPromptParams holds the input for saving a user prompt.

type AddRelationParams added in v0.7.0

type AddRelationParams struct {
	FromID        int64  `json:"from_id"`
	ToID          int64  `json:"to_id"`
	Type          string `json:"type"`
	Note          string `json:"note,omitempty"`
	Bidirectional bool   `json:"bidirectional,omitempty"`
}

AddRelationParams holds input for creating a new relation.

type CompactParams added in v0.9.0

type CompactParams struct {
	IDs            []int64 `json:"ids"`
	SummaryTitle   string  `json:"summary_title,omitempty"`
	SummaryContent string  `json:"summary_content,omitempty"`
	Project        string  `json:"project,omitempty"`
	Scope          string  `json:"scope,omitempty"`
	SessionID      string  `json:"session_id,omitempty"`
}

CompactParams holds the input for batch compaction of observations.

type CompactResult added in v0.9.0

type CompactResult struct {
	DeletedCount int    `json:"deleted_count"`
	SummaryID    *int64 `json:"summary_id,omitempty"`
	TotalBefore  int    `json:"total_before"`
	TotalAfter   int    `json:"total_after"`
}

CompactResult holds the output of a compaction operation.

type Config

type Config struct {
	DataDir              string
	MaxObservationLength int
	MaxContextResults    int
	MaxSearchResults     int
	DedupeWindow         time.Duration
}

Config holds memory store configuration.

func DefaultConfig

func DefaultConfig() Config

DefaultConfig returns the default configuration for the memory store.

type ContextFormatOptions added in v0.9.0

type ContextFormatOptions struct {
	// DetailLevel controls verbosity: "summary", "standard", or "full".
	// Defaults to "standard" if empty.
	DetailLevel string
	// Limit overrides the number of observations to retrieve.
	// 0 means use the configured default (MaxContextResults).
	Limit int
	// Namespace filters observations to a specific sub-agent namespace.
	// Empty means no namespace filter (see all).
	Namespace string
	// MaxTokens sets a token budget cap. When > 0, the response is built
	// incrementally and stops adding items when the budget would be exceeded.
	// 0 means no budget cap (default — return everything).
	MaxTokens int
}

ContextFormatOptions controls verbosity and limits for FormatContextDetailed.

type ContextNode added in v0.7.0

type ContextNode struct {
	ID           int64  `json:"id"`
	Title        string `json:"title"`
	Type         string `json:"type"`
	Project      string `json:"project,omitempty"`
	CreatedAt    string `json:"created_at"`
	RelationType string `json:"relation_type"`
	Direction    string `json:"direction"` // "outgoing" or "incoming"
	Note         string `json:"note,omitempty"`
	Depth        int    `json:"depth"`
}

ContextNode represents one node in a graph traversal result.

type ContextResult added in v0.7.0

type ContextResult struct {
	Root       Observation   `json:"root"`
	Connected  []ContextNode `json:"connected"`
	TotalNodes int           `json:"total_nodes"`
	MaxDepth   int           `json:"max_depth"`
}

ContextResult holds the full graph traversal output.

type ExportData

type ExportData struct {
	Version      string        `json:"version"`
	ExportedAt   string        `json:"exported_at"`
	Sessions     []Session     `json:"sessions"`
	Observations []Observation `json:"observations"`
	Prompts      []Prompt      `json:"prompts"`
}

ExportData is the full serializable dump of the memory database.

type ImportResult

type ImportResult struct {
	SessionsImported     int `json:"sessions_imported"`
	ObservationsImported int `json:"observations_imported"`
	PromptsImported      int `json:"prompts_imported"`
}

ImportResult holds counts of imported records.

type Observation

type Observation struct {
	ID             int64   `json:"id"`
	SessionID      string  `json:"session_id"`
	Type           string  `json:"type"`
	Title          string  `json:"title"`
	Content        string  `json:"content"`
	ToolName       *string `json:"tool_name,omitempty"`
	Project        *string `json:"project,omitempty"`
	Scope          string  `json:"scope"`
	TopicKey       *string `json:"topic_key,omitempty"`
	Namespace      *string `json:"namespace,omitempty"`
	RevisionCount  int     `json:"revision_count"`
	DuplicateCount int     `json:"duplicate_count"`
	LastSeenAt     *string `json:"last_seen_at,omitempty"`
	CreatedAt      string  `json:"created_at"`
	UpdatedAt      string  `json:"updated_at"`
	DeletedAt      *string `json:"deleted_at,omitempty"`
}

Observation represents a single memory entry — a decision, pattern, bug fix, etc.

type PassiveCaptureParams

type PassiveCaptureParams struct {
	SessionID string `json:"session_id"`
	Content   string `json:"content"`
	Project   string `json:"project,omitempty"`
	Source    string `json:"source,omitempty"`
}

PassiveCaptureParams holds the input for passive memory capture.

type PassiveCaptureResult

type PassiveCaptureResult struct {
	Extracted  int `json:"extracted"`
	Saved      int `json:"saved"`
	Duplicates int `json:"duplicates"`
}

PassiveCaptureResult holds the output of passive memory capture.

type Prompt

type Prompt struct {
	ID        int64  `json:"id"`
	SessionID string `json:"session_id"`
	Content   string `json:"content"`
	Project   string `json:"project,omitempty"`
	CreatedAt string `json:"created_at"`
}

Prompt represents a saved user prompt.

type Relation added in v0.7.0

type Relation struct {
	ID        int64  `json:"id"`
	FromID    int64  `json:"from_id"`
	ToID      int64  `json:"to_id"`
	Type      string `json:"type"`
	Note      string `json:"note,omitempty"`
	CreatedAt string `json:"created_at"`
}

Relation represents a typed directional edge between two observations.

type SearchOptions

type SearchOptions struct {
	Type      string `json:"type,omitempty"`
	Project   string `json:"project,omitempty"`
	Scope     string `json:"scope,omitempty"`
	Namespace string `json:"namespace,omitempty"`
	Limit     int    `json:"limit,omitempty"`
}

SearchOptions holds filters for FTS5 search queries.

type SearchResult

type SearchResult struct {
	Observation
	Rank float64 `json:"rank"`
}

SearchResult embeds an Observation with FTS5 rank score.

type Session

type Session struct {
	ID        string  `json:"id"`
	Project   string  `json:"project"`
	Directory string  `json:"directory"`
	StartedAt string  `json:"started_at"`
	EndedAt   *string `json:"ended_at,omitempty"`
	Summary   *string `json:"summary,omitempty"`
}

Session represents a coding session with start/end timestamps.

type SessionSummary

type SessionSummary struct {
	ID               string  `json:"id"`
	Project          string  `json:"project"`
	StartedAt        string  `json:"started_at"`
	EndedAt          *string `json:"ended_at,omitempty"`
	Summary          *string `json:"summary,omitempty"`
	ObservationCount int     `json:"observation_count"`
}

SessionSummary is a compact view of a session with observation count.

type Stats

type Stats struct {
	TotalSessions     int      `json:"total_sessions"`
	TotalObservations int      `json:"total_observations"`
	TotalPrompts      int      `json:"total_prompts"`
	Projects          []string `json:"projects"`
}

Stats holds aggregate memory statistics.

type Store

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

Store is the persistent memory engine backed by SQLite + FTS5.

func New

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

New creates a new Store with the given configuration. It creates the data directory if needed, opens SQLite with WAL mode, and runs migrations.

func (*Store) AddObservation

func (s *Store) AddObservation(p AddObservationParams) (int64, error)

AddObservation creates a new observation with topic_key upsert and deduplication.

func (*Store) AddPrompt

func (s *Store) AddPrompt(p AddPromptParams) (int64, error)

AddPrompt saves a user prompt to persistent memory.

func (*Store) AddRelation added in v0.7.0

func (s *Store) AddRelation(p AddRelationParams) ([]int64, error)

AddRelation creates a typed directional edge between two observations. If Bidirectional is true, both directions are created atomically. Returns the IDs of created relations (1 or 2).

func (*Store) BuildContext added in v0.7.0

func (s *Store) BuildContext(observationID int64, maxDepth int) (*ContextResult, error)

BuildContext traverses the relation graph from a starting observation using BFS. It returns a compact context tree with observation metadata (no full content). Default depth is 2, max is 5. Cycle detection prevents infinite loops.

func (*Store) Close

func (s *Store) Close() error

Close closes the underlying database connection.

func (*Store) CompactObservations added in v0.9.0

func (s *Store) CompactObservations(p CompactParams) (*CompactResult, error)

CompactObservations batch soft-deletes the given observation IDs and optionally creates a summary observation as a replacement. The entire operation is atomic — if the summary insert fails, the soft-deletes are rolled back.

func (*Store) CountObservations added in v0.9.0

func (s *Store) CountObservations(project, scope, namespace string) (int, error)

CountObservations returns the total number of non-deleted observations matching the given project, scope, and namespace filters. Used for "Showing X of Y" navigation hints when results are capped by a limit.

func (*Store) CountSearchResults added in v0.9.0

func (s *Store) CountSearchResults(query string, opts SearchOptions) (int, error)

CountSearchResults returns the total number of observations matching an FTS5 query and filters, without applying a LIMIT. Used for "Showing X of Y" navigation hints in mem_search responses.

func (*Store) CreateSession

func (s *Store) CreateSession(id, project, directory string) error

CreateSession registers a new coding session.

func (*Store) DeleteObservation

func (s *Store) DeleteObservation(id int64, hardDelete bool) error

DeleteObservation soft-deletes (or hard-deletes) an observation by ID.

func (*Store) EndSession

func (s *Store) EndSession(id string, summary string) error

EndSession marks a session as completed with an optional summary.

func (*Store) Export

func (s *Store) Export() (*ExportData, error)

Export dumps the entire memory database as a serializable struct.

func (*Store) FindByTopicKey added in v0.7.0

func (s *Store) FindByTopicKey(topicKey, project, scope string) (*Observation, error)

FindByTopicKey returns the latest non-deleted observation matching the given topic_key, project, and scope. Returns nil (not an error) when no matching observation exists.

func (*Store) FindStaleObservations added in v0.9.0

func (s *Store) FindStaleObservations(project, scope, namespace string, olderThanDays, limit int) ([]Observation, error)

FindStaleObservations returns non-deleted observations older than the specified number of days, filtered by project and scope. Results are ordered oldest-first so the caller can prioritize the stalest entries.

func (*Store) FormatContext

func (s *Store) FormatContext(project, scope string) (string, error)

FormatContext returns a markdown-formatted summary of recent memory. This is the backward-compatible wrapper that always uses standard detail.

func (*Store) FormatContextDetailed added in v0.9.0

func (s *Store) FormatContextDetailed(project, scope string, opts ContextFormatOptions) (string, error)

FormatContextDetailed returns a markdown-formatted summary of recent memory with configurable verbosity (summary/standard/full) and observation limit.

func (*Store) GetObservation

func (s *Store) GetObservation(id int64) (*Observation, error)

GetObservation retrieves a single observation by ID (excludes soft-deleted).

func (*Store) GetRelations added in v0.7.0

func (s *Store) GetRelations(observationID int64) ([]Relation, error)

GetRelations returns all relations where the observation is either source or target.

func (*Store) GetSession

func (s *Store) GetSession(id string) (*Session, error)

GetSession retrieves a session by ID.

func (*Store) Import

func (s *Store) Import(data *ExportData) (*ImportResult, error)

Import loads exported data into the memory database.

func (*Store) PassiveCapture

func (s *Store) PassiveCapture(p PassiveCaptureParams) (*PassiveCaptureResult, error)

PassiveCapture extracts learnings from text and saves them as observations.

func (*Store) RecentObservations

func (s *Store) RecentObservations(project, scope, namespace string, limit int) ([]Observation, error)

RecentObservations returns recent observations filtered by project, scope, and namespace.

func (*Store) RecentPrompts

func (s *Store) RecentPrompts(project string, limit int) ([]Prompt, error)

RecentPrompts returns recent user prompts filtered by project.

func (*Store) RecentSessions

func (s *Store) RecentSessions(project string, limit int) ([]SessionSummary, error)

RecentSessions returns recent sessions with observation counts.

func (*Store) RemoveRelation added in v0.7.0

func (s *Store) RemoveRelation(id int64) error

RemoveRelation hard-deletes a relation by its ID.

func (*Store) Search

func (s *Store) Search(query string, opts SearchOptions) ([]SearchResult, error)

Search performs full-text search across observations with filters. If the query is empty or whitespace-only, falls back to returning recent observations.

func (*Store) SearchPrompts

func (s *Store) SearchPrompts(query string, project string, limit int) ([]Prompt, error)

SearchPrompts searches user prompts using FTS5.

func (*Store) Stats

func (s *Store) Stats() (*Stats, error)

Stats returns aggregate memory statistics.

func (*Store) Timeline

func (s *Store) Timeline(observationID int64, before, after int) (*TimelineResult, error)

Timeline provides chronological context around a specific observation. Progressive disclosure pattern: search → timeline → get_observation.

func (*Store) UpdateObservation

func (s *Store) UpdateObservation(id int64, p UpdateObservationParams) (*Observation, error)

UpdateObservation partially updates an observation by ID.

type TimelineEntry

type TimelineEntry struct {
	ID             int64   `json:"id"`
	SessionID      string  `json:"session_id"`
	Type           string  `json:"type"`
	Title          string  `json:"title"`
	Content        string  `json:"content"`
	ToolName       *string `json:"tool_name,omitempty"`
	Project        *string `json:"project,omitempty"`
	Scope          string  `json:"scope"`
	TopicKey       *string `json:"topic_key,omitempty"`
	Namespace      *string `json:"namespace,omitempty"`
	RevisionCount  int     `json:"revision_count"`
	DuplicateCount int     `json:"duplicate_count"`
	LastSeenAt     *string `json:"last_seen_at,omitempty"`
	CreatedAt      string  `json:"created_at"`
	UpdatedAt      string  `json:"updated_at"`
	DeletedAt      *string `json:"deleted_at,omitempty"`
	IsFocus        bool    `json:"is_focus"`
}

TimelineEntry is an observation in a timeline with a focus flag.

type TimelineResult

type TimelineResult struct {
	Focus        Observation     `json:"focus"`
	Before       []TimelineEntry `json:"before"`
	After        []TimelineEntry `json:"after"`
	SessionInfo  *Session        `json:"session_info"`
	TotalInRange int             `json:"total_in_range"`
}

TimelineResult holds the progressive disclosure result around a focus observation.

type UpdateObservationParams

type UpdateObservationParams struct {
	Type     *string `json:"type,omitempty"`
	Title    *string `json:"title,omitempty"`
	Content  *string `json:"content,omitempty"`
	Project  *string `json:"project,omitempty"`
	Scope    *string `json:"scope,omitempty"`
	TopicKey *string `json:"topic_key,omitempty"`
}

UpdateObservationParams holds partial update fields for an observation.

Jump to

Keyboard shortcuts

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