Documentation
¶
Index ¶
- type Client
- type EntityResolver
- type EntityResult
- type FactAction
- type FactExtractor
- type FactResolver
- type FactResult
- type MockGraphClient
- func (m *MockGraphClient) AppendEpisode(_ context.Context, factID, episodeID string) error
- func (m *MockGraphClient) AppendMemoryToFact(_ context.Context, factID, memoryID string) error
- func (m *MockGraphClient) Close() error
- func (m *MockGraphClient) CreateEpisode(_ context.Context, episode models.Episode) error
- func (m *MockGraphClient) EnsureSchema(_ context.Context, _ int) error
- func (m *MockGraphClient) GetEntity(_ context.Context, id string) (*models.Entity, error)
- func (m *MockGraphClient) GetEpisodes() []models.Episode
- func (m *MockGraphClient) GetEpisodesForMemory(_ context.Context, memoryID string) ([]models.Episode, error)
- func (m *MockGraphClient) GetFactsBetween(_ context.Context, sourceID, targetID string) ([]models.Fact, error)
- func (m *MockGraphClient) GetFactsForEntity(_ context.Context, entityID string) ([]models.Fact, error)
- func (m *MockGraphClient) GetMemoryFacts(_ context.Context, memoryID string) ([]models.Fact, error)
- func (m *MockGraphClient) Healthy(_ context.Context) bool
- func (m *MockGraphClient) InvalidateFact(_ context.Context, id string, expiredAt, invalidAt time.Time) error
- func (m *MockGraphClient) RecallByGraph(_ context.Context, _ string, _ []float32, _ int) ([]string, error)
- func (m *MockGraphClient) SearchEntities(_ context.Context, query string, _ []float32, _ string, limit int) ([]EntityResult, error)
- func (m *MockGraphClient) SearchFacts(_ context.Context, _ string, _ []float32, limit int) ([]FactResult, error)
- func (m *MockGraphClient) UpsertEntity(_ context.Context, entity models.Entity) error
- func (m *MockGraphClient) UpsertFact(_ context.Context, fact models.Fact) error
- type SearchFunc
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Client ¶
type Client interface {
// EnsureSchema creates indexes and constraints if they don't exist.
// vectorDim is injected into the vector index DDL (e.g. 768 for nomic-embed-text).
EnsureSchema(ctx context.Context, vectorDim int) error
// UpsertEntity creates or updates an entity node.
UpsertEntity(ctx context.Context, entity models.Entity) error
// SearchEntities finds entities by fulltext + embedding similarity.
SearchEntities(ctx context.Context, query string, embedding []float32, project string, limit int) ([]EntityResult, error)
// GetEntity retrieves a single entity by ID.
GetEntity(ctx context.Context, id string) (*models.Entity, error)
// UpsertFact creates a RELATES_TO edge between two entities.
UpsertFact(ctx context.Context, fact models.Fact) error
// SearchFacts finds facts by hybrid search (BM25 + cosine + BFS).
SearchFacts(ctx context.Context, query string, embedding []float32, limit int) ([]FactResult, error)
// InvalidateFact sets ExpiredAt and InvalidAt on a fact (never deletes).
InvalidateFact(ctx context.Context, id string, expiredAt, invalidAt time.Time) error
// GetFactsBetween returns all active facts between two entities.
GetFactsBetween(ctx context.Context, sourceID, targetID string) ([]models.Fact, error)
// GetFactsForEntity returns all active facts involving an entity.
GetFactsForEntity(ctx context.Context, entityID string) ([]models.Fact, error)
// AppendEpisode adds an episode/session ID to a fact's episodes list.
AppendEpisode(ctx context.Context, factID, episodeID string) error
// AppendMemoryToFact adds a memory ID to a fact's source_memory_ids.
AppendMemoryToFact(ctx context.Context, factID, memoryID string) error
// GetMemoryFacts returns all facts derived from a given memory.
GetMemoryFacts(ctx context.Context, memoryID string) ([]models.Fact, error)
// RecallByGraph returns memory IDs relevant to a query via graph traversal.
RecallByGraph(ctx context.Context, query string, embedding []float32, limit int) ([]string, error)
// CreateEpisode stores an episode node in the graph.
CreateEpisode(ctx context.Context, episode models.Episode) error
// GetEpisodesForMemory returns all episodes linked to a given memory ID.
GetEpisodesForMemory(ctx context.Context, memoryID string) ([]models.Episode, error)
// Healthy returns true if the graph database is reachable.
Healthy(ctx context.Context) bool
// Close releases resources.
Close() error
}
Client defines the interface for graph storage operations. Resolution logic lives in EntityResolver and FactResolver (separate types), matching the pattern where ConflictDetector is separate from Store.
type EntityResolver ¶
type EntityResolver struct {
// contains filtered or unexported fields
}
EntityResolver implements three-stage entity resolution: 1. Candidate retrieval via graph search 2. Deterministic fast-path (exact name, alias, embedding cosine) 3. Claude Haiku fallback for ambiguous cases
func NewEntityResolver ¶
func NewEntityResolver(graph Client, client llm.LLMClient, model string, threshold float64, maxCands int, logger *slog.Logger) *EntityResolver
NewEntityResolver creates a new EntityResolver. If client is nil, stage 3 (Claude fallback) is disabled and ambiguous entities are treated as new.
func (*EntityResolver) Resolve ¶
func (r *EntityResolver) Resolve(ctx context.Context, extracted models.Entity, embedding []float32, conversationContext string) (string, bool, error)
Resolve performs three-stage entity resolution and returns (resolvedID, isNew, err). If the entity matches an existing one, resolvedID is the existing entity's ID and isNew is false. Otherwise, resolvedID is the extracted entity's ID and isNew is true.
type EntityResult ¶
type EntityResult struct {
ID string `json:"id"`
Name string `json:"name"`
Type string `json:"type"`
Score float64 `json:"score"`
}
EntityResult is a search result from the graph entity index.
type FactAction ¶
type FactAction string
FactAction represents the resolution outcome for a new fact.
const ( FactActionInsert FactAction = "insert" // new fact, no duplicates FactActionSkip FactAction = "skip" // exact duplicate, append episode FactActionInvalidate FactAction = "invalidate" // contradicts existing, invalidate old )
type FactExtractor ¶
type FactExtractor struct {
// contains filtered or unexported fields
}
FactExtractor extracts relationship facts from conversation text using Claude.
func NewFactExtractor ¶
NewFactExtractor creates a new fact extractor backed by the Claude API.
func (*FactExtractor) Extract ¶
func (e *FactExtractor) Extract(ctx context.Context, content string, entityNames []string) ([]models.Fact, error)
Extract extracts relationship facts from conversation text. entityNames is the list of known entity names from the extraction step. On API error it logs a warning and returns (nil, nil) for graceful degradation.
NOTE: The returned facts have SourceEntityID and TargetEntityID set to entity NAMES (not UUIDs). The caller is responsible for resolving names to IDs after extraction, since Claude returns names and the ID mapping is external.
type FactResolver ¶
type FactResolver struct {
// contains filtered or unexported fields
}
FactResolver determines whether a new fact is a duplicate, contradiction, or new by comparing it against existing facts between the same entity pair.
func NewFactResolver ¶
func NewFactResolver(graph Client, client llm.LLMClient, model string, logger *slog.Logger) *FactResolver
NewFactResolver creates a new FactResolver. If client is nil, the resolver will treat all facts as new (graceful degradation).
type FactResult ¶
type FactResult struct {
ID string `json:"id"`
Fact string `json:"fact"`
SourceEntityID string `json:"source_entity_id"`
TargetEntityID string `json:"target_entity_id"`
SourceMemoryIDs []string `json:"source_memory_ids"`
Score float64 `json:"score"`
}
FactResult is a search result from the graph fact index.
func HybridSearch ¶
func HybridSearch(ctx context.Context, fns []SearchFunc, limit int) ([]FactResult, error)
HybridSearch runs multiple search functions in parallel and merges with RRF.
func RRFMerge ¶
func RRFMerge(lists [][]FactResult, limit int) []FactResult
RRFMerge implements Reciprocal Rank Fusion across multiple ranked lists. Each list contains FactResults sorted by their individual method score. Returns merged results sorted by combined RRF score, deduped by ID.
type MockGraphClient ¶
type MockGraphClient struct {
// contains filtered or unexported fields
}
MockGraphClient implements Client with in-memory maps for testing.
func NewMockGraphClient ¶
func NewMockGraphClient() *MockGraphClient
NewMockGraphClient creates a new MockGraphClient.
func (*MockGraphClient) AppendEpisode ¶
func (m *MockGraphClient) AppendEpisode(_ context.Context, factID, episodeID string) error
func (*MockGraphClient) AppendMemoryToFact ¶
func (m *MockGraphClient) AppendMemoryToFact(_ context.Context, factID, memoryID string) error
func (*MockGraphClient) Close ¶
func (m *MockGraphClient) Close() error
func (*MockGraphClient) CreateEpisode ¶ added in v0.8.0
CreateEpisode stores an episode in the mock.
func (*MockGraphClient) EnsureSchema ¶
func (m *MockGraphClient) EnsureSchema(_ context.Context, _ int) error
func (*MockGraphClient) GetEpisodes ¶ added in v0.8.0
func (m *MockGraphClient) GetEpisodes() []models.Episode
GetEpisodes returns all stored episodes (test helper).
func (*MockGraphClient) GetEpisodesForMemory ¶ added in v0.8.0
func (m *MockGraphClient) GetEpisodesForMemory(_ context.Context, memoryID string) ([]models.Episode, error)
GetEpisodesForMemory returns all episodes that reference the given memory ID.
func (*MockGraphClient) GetFactsBetween ¶
func (*MockGraphClient) GetFactsForEntity ¶
func (*MockGraphClient) GetMemoryFacts ¶
func (*MockGraphClient) InvalidateFact ¶
func (*MockGraphClient) RecallByGraph ¶
func (*MockGraphClient) SearchEntities ¶
func (m *MockGraphClient) SearchEntities(_ context.Context, query string, _ []float32, _ string, limit int) ([]EntityResult, error)
func (*MockGraphClient) SearchFacts ¶
func (m *MockGraphClient) SearchFacts(_ context.Context, _ string, _ []float32, limit int) ([]FactResult, error)
func (*MockGraphClient) UpsertEntity ¶
func (*MockGraphClient) UpsertFact ¶
type SearchFunc ¶
type SearchFunc func(ctx context.Context, limit int) ([]FactResult, error)
SearchFunc is a function that returns a ranked list of fact results.