Documentation
¶
Overview ¶
Package graph provides a knowledge graph store (entities and relations) for agent memory. The store is interface-driven so backends can be swapped (in-memory now; Milvus, Trigo, or SQLite later). When persistence is configured, the in-memory implementation snapshots to ~/.genie/<agent>/memory.bin.zst (gob+zstd).
Index ¶
- Constants
- Variables
- func DataDirForAgent(agentName string) string
- func PendingGraphLearnPath(agentName string) string
- type Config
- type Entity
- type GetEntityRequest
- type GetEntityResponse
- type GraphQueryRequest
- type GraphQueryResponse
- type IStore
- type InMemoryStore
- func (s *InMemoryStore) AddEntity(ctx context.Context, e Entity) error
- func (s *InMemoryStore) AddRelation(ctx context.Context, r Relation) error
- func (s *InMemoryStore) Close(ctx context.Context) error
- func (s *InMemoryStore) GetEntity(ctx context.Context, id string) (*Entity, error)
- func (s *InMemoryStore) Neighbors(ctx context.Context, id string, limit int) ([]Neighbor, error)
- func (s *InMemoryStore) RelationsIn(ctx context.Context, id string) ([]Relation, error)
- func (s *InMemoryStore) RelationsOut(ctx context.Context, id string) ([]Relation, error)
- func (s *InMemoryStore) ShortestPath(ctx context.Context, sourceID, targetID string) ([]string, error)
- type InMemoryStoreOption
- type Neighbor
- type Relation
- type ShortestPathRequest
- type ShortestPathResponse
- type StoreEntityRequest
- type StoreEntityResponse
- type StoreRelationRequest
- type StoreRelationResponse
- type ToolProvider
Constants ¶
const ( StoreEntityToolName = "graph_store_entity" StoreRelationToolName = "graph_store_relation" GraphQueryToolName = "graph_query" GetEntityToolName = "graph_get_entity" ShortestPathToolName = "graph_shortest_path" )
const GraphLearnPendingFilename = "graph_learn_pending"
GraphLearnPendingFilename is the name of the file written by setup when the user opts into "build knowledge graph from data"; when present, the app runs one graph-learn pass after the first successful data sources sync.
Variables ¶
var ErrInvalidInput = errors.New("invalid input: required fields missing")
ErrInvalidInput is returned when a tool request is missing required fields.
Functions ¶
func DataDirForAgent ¶
DataDirForAgent returns a directory path suitable for graph persistence for the given agent name: ~/.genie/<sanitized_agent>/ (or ~/.genie/genie/ if agentName is empty). Callers can pass this as Config.DataDir.
func PendingGraphLearnPath ¶
PendingGraphLearnPath returns the path to the graph-learn pending flag file for the given agent. Setup writes this file when the user opts in; the app removes it after running the one-time graph-learn pass.
Types ¶
type Config ¶
type Config struct {
// Disabled turns off the knowledge graph and graph_* tools. When true, no
// graph store is created and no graph tools are registered.
Disabled bool `yaml:"disabled,omitempty" toml:"disabled,omitempty"`
// DataDir is the directory for persistence (e.g. ~/.genie/<agent>). The
// in-memory implementation writes memory.bin.zst (gob+zstd) here. Empty means no persistence.
DataDir string `yaml:"data_dir,omitempty" toml:"data_dir,omitempty"`
}
Config holds configuration for the knowledge graph store. When Disabled is false and DataDir is set, the in-memory store persists to DataDir/memory.bin.zst (gob+zstd). Empty DataDir means no persistence (in-memory only). The implementation is interface-driven so DataDir can be ignored by a future backend (e.g. Milvus).
func DefaultConfig ¶
func DefaultConfig() Config
DefaultConfig returns a config with the graph enabled by default (Disabled: false) and no DataDir (no persistence). Callers typically set DataDir from GenieConfig (e.g. DataDir = filepath.Join(GenieDir(), SanitizeForFilename(agentName))) when persistence is desired.
type Entity ¶
type Entity struct {
ID string `json:"id"`
Type string `json:"type"`
Attrs map[string]string `json:"attrs,omitempty"`
}
Entity represents a node in the knowledge graph with an id, type, and optional JSON attributes. Used for people, repos, issues, documents, etc.
type GetEntityRequest ¶
type GetEntityRequest struct {
EntityID string `json:"entity_id" jsonschema:"description=ID of the entity to look up,required"`
}
GetEntityRequest is the input for the graph_get_entity tool.
type GetEntityResponse ¶
type GetEntityResponse struct {
Entity *Entity `json:"entity,omitempty" jsonschema:"description=The entity if found"`
Found bool `json:"found" jsonschema:"description=Whether the entity exists"`
}
GetEntityResponse is the output for the graph_get_entity tool.
type GraphQueryRequest ¶
type GraphQueryRequest struct {
EntityID string `json:"entity_id" jsonschema:"description=ID of the entity to query from,required"`
Limit int `json:"limit,omitempty" jsonschema:"description=Max number of neighbors to return (default 20)"`
}
GraphQueryRequest is the input for the graph_query tool.
type GraphQueryResponse ¶
GraphQueryResponse is the output for the graph_query tool.
type IStore ¶
type IStore interface {
// AddEntity stores an entity by id; overwrites if id exists.
AddEntity(ctx context.Context, e Entity) error
// AddRelation stores a directed relation; idempotent (same triple is a no-op).
AddRelation(ctx context.Context, r Relation) error
// GetEntity returns the entity by id, or nil if not found.
GetEntity(ctx context.Context, id string) (*Entity, error)
// RelationsOut returns relations where subject_id equals id (outgoing edges).
RelationsOut(ctx context.Context, id string) ([]Relation, error)
// RelationsIn returns relations where object_id equals id (incoming edges).
RelationsIn(ctx context.Context, id string) ([]Relation, error)
// Neighbors returns entities reachable in one hop from id (outgoing and
// incoming), with the connecting predicate and direction. Limit caps the
// total number of neighbors returned.
Neighbors(ctx context.Context, id string, limit int) ([]Neighbor, error)
// ShortestPath returns the shortest path of entity IDs from source to target.
// Returns nil path and nil error if no path exists. Returns an error if
// source or target vertex does not exist. Not all implementations may support
// this; they may return an error.
ShortestPath(ctx context.Context, sourceID, targetID string) ([]string, error)
// Close releases resources (e.g. flush snapshot, close connection).
Close(ctx context.Context) error
}
IStore is the interface for the knowledge graph store. All callers use this interface so the implementation can be swapped (in-memory, Milvus, Trigo, SQLite, etc.) without changing tool or app code.
type InMemoryStore ¶
type InMemoryStore struct {
// contains filtered or unexported fields
}
InMemoryStore implements IStore using github.com/dominikbraun/graph for the in-memory structure and algorithms. Persistence is gob+zstd to memory.bin.zst. Use ShortestPath for path finding between entities.
func NewInMemoryStore ¶
func NewInMemoryStore(opts ...InMemoryStoreOption) (*InMemoryStore, error)
NewInMemoryStore creates an in-memory graph store backed by dominikbraun/graph. When persistence dir is set, state is loaded from memory.bin.zst if present and saved on Add and Close (gob+zstd only).
func (*InMemoryStore) AddEntity ¶
func (s *InMemoryStore) AddEntity(ctx context.Context, e Entity) error
func (*InMemoryStore) AddRelation ¶
func (s *InMemoryStore) AddRelation(ctx context.Context, r Relation) error
func (*InMemoryStore) RelationsIn ¶
func (*InMemoryStore) RelationsOut ¶
func (*InMemoryStore) ShortestPath ¶
func (s *InMemoryStore) ShortestPath(ctx context.Context, sourceID, targetID string) ([]string, error)
ShortestPath returns the shortest path of entity IDs from source to target using unweighted edges. Returns nil path and nil error if no path exists. Returns an error if source or target vertex does not exist. Uses dominikbraun/graph's BFS-based path.
type InMemoryStoreOption ¶
type InMemoryStoreOption func(*InMemoryStore)
InMemoryStoreOption configures the in-memory store.
func WithPersistenceDir ¶
func WithPersistenceDir(dir string) InMemoryStoreOption
WithPersistenceDir sets the directory for the snapshot file (e.g. ~/.genie/<agent>). When set, load is called from NewInMemoryStore and save is called on Close and after writes.
type Neighbor ¶
type Neighbor struct {
Entity Entity `json:"entity"`
Predicate string `json:"predicate"`
Outgoing bool `json:"outgoing"` // true = from subject to this entity, false = from this entity to object
}
Neighbor is an entity reachable from a given node (1-hop) with the predicate that connects them. Used for graph_query tool results.
type Relation ¶
type Relation struct {
SubjectID string `json:"subject_id"`
Predicate string `json:"predicate"`
ObjectID string `json:"object_id"`
}
Relation represents a directed edge: subject --[predicate]--> object. Example: ("person-1", "WORKED_ON", "issue-2").
type ShortestPathRequest ¶
type ShortestPathRequest struct {
SourceID string `json:"source_id" jsonschema:"description=ID of the starting entity,required"`
TargetID string `json:"target_id" jsonschema:"description=ID of the destination entity,required"`
}
ShortestPathRequest is the input for the graph_shortest_path tool.
type ShortestPathResponse ¶
type ShortestPathResponse struct {
Path []string `json:"path" jsonschema:"description=Ordered list of entity IDs from source to target, empty if no path"`
Found bool `json:"found" jsonschema:"description=Whether a path exists"`
}
ShortestPathResponse is the output for the graph_shortest_path tool.
type StoreEntityRequest ¶
type StoreEntityRequest struct {
ID string `json:"id" jsonschema:"description=Unique identifier for the entity,required"`
Type string `json:"type" jsonschema:"description=Entity type (e.g. person, repo, issue, document),required"`
Attrs map[string]string `json:"attrs,omitempty" jsonschema:"description=Optional key-value attributes"`
}
StoreEntityRequest is the input for the graph_store_entity tool.
type StoreEntityResponse ¶
type StoreEntityResponse struct {
Message string `json:"message"`
}
StoreEntityResponse is the output for the graph_store_entity tool.
type StoreRelationRequest ¶
type StoreRelationRequest struct {
SubjectID string `json:"subject_id" jsonschema:"description=ID of the subject entity,required"`
Predicate string `json:"predicate" jsonschema:"description=Relation type (e.g. WORKED_ON, OWNS, MENTIONS),required"`
ObjectID string `json:"object_id" jsonschema:"description=ID of the object entity,required"`
}
StoreRelationRequest is the input for the graph_store_relation tool.
type StoreRelationResponse ¶
type StoreRelationResponse struct {
Message string `json:"message"`
}
StoreRelationResponse is the output for the graph_store_relation tool.
type ToolProvider ¶
type ToolProvider struct {
// contains filtered or unexported fields
}
ToolProvider wraps an IStore and satisfies the tools.ToolProviders interface so graph tools can be passed to tools.NewRegistry. Pass a non-nil store only when the graph is enabled; when store is nil, GetTools returns no tools (callers should not register the provider when graph is disabled).
func NewToolProvider ¶
func NewToolProvider(store IStore) *ToolProvider
NewToolProvider creates a ToolProvider for the graph tools. store must be non-nil when the graph is enabled; otherwise do not register this provider.
func (*ToolProvider) GetTools ¶
func (p *ToolProvider) GetTools() []tool.Tool
GetTools returns graph_store_entity, graph_store_relation, graph_query, graph_get_entity, and graph_shortest_path when store is non-nil. Returns nil when store is nil so that disabled graph does not add tools.