db

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Jun 7, 2026 License: MIT Imports: 8 Imported by: 0

Documentation

Overview

Package db es la capa de persistencia de nem: modelos GORM sobre SQLite (glebarez/sqlite, Go puro, sin cgo) más una capa FTS5 en SQL crudo para búsqueda full-text con ranking BM25.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Chat

type Chat struct {
	ID          string `gorm:"primaryKey"`
	Title       string
	Source      string `gorm:"index"` // "codex" | "claude" | "manual"
	CreatedAt   int64  // unix seconds, autocompletado por GORM
	SessionPath string

	Messages []Message `gorm:"foreignKey:ChatID;constraint:OnDelete:CASCADE"`
}

Chat representa una conversación ingestada desde un agente (codex, claude) o creada manualmente. Es el contenedor de mensajes y commits.

type Commit

type Commit struct {
	Hash      string `gorm:"primaryKey"`
	ChatID    string `gorm:"index"`
	Branch    string `gorm:"default:main"`
	Message   string // mensaje del commit, escrito por el agente o el humano
	MsgFrom   string // id del primer mensaje del rango
	MsgTo     string // id del último mensaje del rango
	Snapshot  string // JSON con el texto copiado de los mensajes (inmutable)
	CreatedAt int64
}

Commit es un snapshot INMUTABLE de un rango de mensajes. Copia el texto en Snapshot (JSON) al momento de commitear, de modo que reingestar o editar mensajes nunca altera lo que un commit ya capturó: "tu agente olvida, nem no".

type Config

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

Config contiene la configuración para abrir un Store.

type Memory

type Memory struct {
	ID         string `gorm:"primaryKey"`
	ChatID     string `gorm:"index"`
	Content    string
	CommitHash string // commit que respalda este recuerdo (evidencia)
	CreatedAt  int64
	UpdatedAt  int64
}

Memory es la capa MUTABLE sobre el registro inmutable: un hecho/decisión destilado que el agente lee al empezar una sesión. Puede actualizarse, y referencia el commit que lo respalda como evidencia.

type Message

type Message struct {
	ID         string `gorm:"primaryKey"`
	ChatID     string `gorm:"index"`
	Role       string // "user" | "assistant" | "tool" | "system"
	Content    string
	Timestamp  int64
	TokenCount int
	Seq        int64 `gorm:"index"` // orden dentro del chat
}

Message es un turno individual dentro de un chat. El campo Seq da orden determinístico dentro del chat (los timestamps pueden colisionar).

type Option

type Option func(*Config) error

Option configura la apertura de un Store.

func WithPath

func WithPath(path string) Option

WithPath fija la ruta del archivo SQLite. Usar ":memory:" para tests.

func WithVerbose

func WithVerbose(verbose bool) Option

WithVerbose habilita el logging de queries de GORM (debug).

type SearchHit

type SearchHit struct {
	Message
	ChatTitle  string
	ChatSource string
	Score      float64
}

SearchHit es un resultado de búsqueda: el mensaje más metadata del chat y el score BM25 (menor = más relevante).

type Staging

type Staging struct {
	ID        string `gorm:"primaryKey"`
	ChatID    string `gorm:"index;uniqueIndex:idx_staging_chat_msg"`
	MsgID     string `gorm:"uniqueIndex:idx_staging_chat_msg"`
	Seq       int64  // copia del Seq del mensaje para ordenar el rango
	CreatedAt int64
}

Staging es el index git-like: los mensajes marcados con `nem add` que esperan ser commiteados. Una fila por mensaje staged del chat activo.

type Store

type Store interface {
	// Migrate aplica el esquema (modelos + FTS5). Es idempotente.
	Migrate() error
	// Close libera la conexión subyacente.
	Close() error

	// UpsertChat inserta el chat o actualiza su metadata si ya existe.
	UpsertChat(chat *Chat) error
	// InsertMessages inserta mensajes ignorando los que ya existen (por id).
	// Devuelve cuántos se insertaron realmente (idempotente).
	InsertMessages(msgs []Message) (int64, error)
	// CountMessages cuenta los mensajes de un chat.
	CountMessages(chatID string) (int64, error)
	// LastMessages devuelve los últimos n mensajes del chat por orden Seq,
	// filtrando por roles (vacío/nil = todos). El filtro se aplica ANTES del
	// límite: "los últimos n de los roles elegidos".
	LastMessages(chatID string, n int, roles []string) ([]Message, error)
	// GetChat devuelve un chat por id (nil, nil si no existe).
	GetChat(id string) (*Chat, error)
	// ListChats devuelve todos los chats (para resolver scopes).
	ListChats() ([]Chat, error)
	// MessageByID devuelve un mensaje por id dentro de un chat.
	MessageByID(chatID, msgID string) (*Message, error)
	// MessagesBySeqRange devuelve los mensajes del chat con Seq en [from,to],
	// filtrando por roles (vacío/nil = todos).
	MessagesBySeqRange(chatID string, fromSeq, toSeq int64, roles []string) ([]Message, error)
	// SearchMessages busca full-text (FTS5/BM25) y devuelve los mejores hits.
	// roles filtra por rol de mensaje; chatIDs limita a esos chats (scope).
	// Ambos vacíos/nil = sin filtro.
	SearchMessages(query string, limit int, roles, chatIDs []string) ([]SearchHit, error)

	// StageMessages agrega mensajes al staging del chat (idempotente por msg).
	// Devuelve cuántos quedaron staged nuevos.
	StageMessages(chatID string, msgs []Message) (int64, error)
	// StagedMessages devuelve los mensajes staged del chat, ordenados por Seq.
	StagedMessages(chatID string) ([]Message, error)
	// CountStaged cuenta los mensajes staged del chat.
	CountStaged(chatID string) (int64, error)
	// ClearStaging vacía el staging del chat.
	ClearStaging(chatID string) error

	// CreateCommit persiste un commit inmutable.
	CreateCommit(c *Commit) error
	// HeadCommit devuelve el commit más reciente del chat (nil si no hay).
	HeadCommit(chatID string) (*Commit, error)
	// GetCommit devuelve un commit por hash (acepta prefijo único).
	GetCommit(hash string) (*Commit, error)
	// ListCommits lista los commits del chat, del más nuevo al más viejo.
	ListCommits(chatID string) ([]Commit, error)
	// ListAllCommits lista todos los commits (para exportar en sync).
	ListAllCommits() ([]Commit, error)
}

Store es la interface de acceso a datos de nem. Toda la app depende de esta abstracción, no de GORM directamente, para que los comandos sean testeables con un mock.

func New

func New(options ...Option) (Store, error)

New abre (o crea) el Store en la ruta configurada y aplica la migración. Devuelve error si falta la ruta o si la conexión/migración fallan.

Ejemplo:

s, err := db.New(db.WithPath("/home/me/.nem/nem.db"))
if err != nil {
    log.Fatal(err)
}
defer s.Close()

Jump to

Keyboard shortcuts

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