feat(memory): extend sqlc schema and queries for immutable messages, edges, RL, consolidation
This commit is contained in:
parent
89c8f17aa9
commit
fc22914f47
19 changed files with 3316 additions and 72 deletions
|
|
@ -8,6 +8,7 @@ package sqlc
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/ZanzyTHEbar/dragonscale/pkg/ids"
|
"github.com/ZanzyTHEbar/dragonscale/pkg/ids"
|
||||||
"github.com/ZanzyTHEbar/dragonscale/pkg/memory"
|
"github.com/ZanzyTHEbar/dragonscale/pkg/memory"
|
||||||
|
|
@ -76,6 +77,17 @@ type GetArchivalChunkParams struct {
|
||||||
AgentID string `db:"agent_id" json:"agent_id"`
|
AgentID string `db:"agent_id" json:"agent_id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type GetArchivalChunkRow struct {
|
||||||
|
ID ids.UUID `db:"id" json:"id"`
|
||||||
|
RecallID ids.UUID `db:"recall_id" json:"recall_id"`
|
||||||
|
ChunkIndex int64 `db:"chunk_index" json:"chunk_index"`
|
||||||
|
Content string `db:"content" json:"content"`
|
||||||
|
Embedding memory.Embedding `db:"embedding" json:"embedding"`
|
||||||
|
Source string `db:"source" json:"source"`
|
||||||
|
Hash string `db:"hash" json:"hash"`
|
||||||
|
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
||||||
|
}
|
||||||
|
|
||||||
// GetArchivalChunk
|
// GetArchivalChunk
|
||||||
//
|
//
|
||||||
// SELECT ac.id,
|
// SELECT ac.id,
|
||||||
|
|
@ -91,9 +103,9 @@ type GetArchivalChunkParams struct {
|
||||||
// WHERE ac.id = ?1
|
// WHERE ac.id = ?1
|
||||||
// AND ri.agent_id = ?2
|
// AND ri.agent_id = ?2
|
||||||
// LIMIT 1
|
// LIMIT 1
|
||||||
func (q *Queries) GetArchivalChunk(ctx context.Context, arg GetArchivalChunkParams) (ArchivalChunk, error) {
|
func (q *Queries) GetArchivalChunk(ctx context.Context, arg GetArchivalChunkParams) (GetArchivalChunkRow, error) {
|
||||||
row := q.db.QueryRowContext(ctx, GetArchivalChunk, arg.ID, arg.AgentID)
|
row := q.db.QueryRowContext(ctx, GetArchivalChunk, arg.ID, arg.AgentID)
|
||||||
var i ArchivalChunk
|
var i GetArchivalChunkRow
|
||||||
err := row.Scan(
|
err := row.Scan(
|
||||||
&i.ID,
|
&i.ID,
|
||||||
&i.RecallID,
|
&i.RecallID,
|
||||||
|
|
@ -127,6 +139,17 @@ type GetArchivalChunksByIDsParams struct {
|
||||||
AgentID string `db:"agent_id" json:"agent_id"`
|
AgentID string `db:"agent_id" json:"agent_id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type GetArchivalChunksByIDsRow struct {
|
||||||
|
ID ids.UUID `db:"id" json:"id"`
|
||||||
|
RecallID ids.UUID `db:"recall_id" json:"recall_id"`
|
||||||
|
ChunkIndex int64 `db:"chunk_index" json:"chunk_index"`
|
||||||
|
Content string `db:"content" json:"content"`
|
||||||
|
Embedding memory.Embedding `db:"embedding" json:"embedding"`
|
||||||
|
Source string `db:"source" json:"source"`
|
||||||
|
Hash string `db:"hash" json:"hash"`
|
||||||
|
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
||||||
|
}
|
||||||
|
|
||||||
// GetArchivalChunksByIDs
|
// GetArchivalChunksByIDs
|
||||||
//
|
//
|
||||||
// SELECT ac.id,
|
// SELECT ac.id,
|
||||||
|
|
@ -141,7 +164,7 @@ type GetArchivalChunksByIDsParams struct {
|
||||||
// JOIN recall_items ri ON ac.recall_id = ri.id
|
// JOIN recall_items ri ON ac.recall_id = ri.id
|
||||||
// WHERE ac.id IN (/*SLICE:ids*/?)
|
// WHERE ac.id IN (/*SLICE:ids*/?)
|
||||||
// AND ri.agent_id = ?2
|
// AND ri.agent_id = ?2
|
||||||
func (q *Queries) GetArchivalChunksByIDs(ctx context.Context, arg GetArchivalChunksByIDsParams) ([]ArchivalChunk, error) {
|
func (q *Queries) GetArchivalChunksByIDs(ctx context.Context, arg GetArchivalChunksByIDsParams) ([]GetArchivalChunksByIDsRow, error) {
|
||||||
query := GetArchivalChunksByIDs
|
query := GetArchivalChunksByIDs
|
||||||
var queryParams []interface{}
|
var queryParams []interface{}
|
||||||
if len(arg.Ids) > 0 {
|
if len(arg.Ids) > 0 {
|
||||||
|
|
@ -158,9 +181,9 @@ func (q *Queries) GetArchivalChunksByIDs(ctx context.Context, arg GetArchivalChu
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
items := []ArchivalChunk{}
|
items := []GetArchivalChunksByIDsRow{}
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var i ArchivalChunk
|
var i GetArchivalChunksByIDsRow
|
||||||
if err := rows.Scan(
|
if err := rows.Scan(
|
||||||
&i.ID,
|
&i.ID,
|
||||||
&i.RecallID,
|
&i.RecallID,
|
||||||
|
|
@ -218,6 +241,17 @@ type InsertArchivalChunkParams struct {
|
||||||
Hash string `db:"hash" json:"hash"`
|
Hash string `db:"hash" json:"hash"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type InsertArchivalChunkRow struct {
|
||||||
|
ID ids.UUID `db:"id" json:"id"`
|
||||||
|
RecallID ids.UUID `db:"recall_id" json:"recall_id"`
|
||||||
|
ChunkIndex int64 `db:"chunk_index" json:"chunk_index"`
|
||||||
|
Content string `db:"content" json:"content"`
|
||||||
|
Embedding memory.Embedding `db:"embedding" json:"embedding"`
|
||||||
|
Source string `db:"source" json:"source"`
|
||||||
|
Hash string `db:"hash" json:"hash"`
|
||||||
|
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
||||||
|
}
|
||||||
|
|
||||||
// Archival Chunk queries
|
// Archival Chunk queries
|
||||||
//
|
//
|
||||||
// INSERT INTO archival_chunks (
|
// INSERT INTO archival_chunks (
|
||||||
|
|
@ -241,7 +275,7 @@ type InsertArchivalChunkParams struct {
|
||||||
// datetime('now')
|
// datetime('now')
|
||||||
// )
|
// )
|
||||||
// RETURNING id, recall_id, chunk_index, content, embedding, source, hash, created_at
|
// RETURNING id, recall_id, chunk_index, content, embedding, source, hash, created_at
|
||||||
func (q *Queries) InsertArchivalChunk(ctx context.Context, arg InsertArchivalChunkParams) (ArchivalChunk, error) {
|
func (q *Queries) InsertArchivalChunk(ctx context.Context, arg InsertArchivalChunkParams) (InsertArchivalChunkRow, error) {
|
||||||
row := q.db.QueryRowContext(ctx, InsertArchivalChunk,
|
row := q.db.QueryRowContext(ctx, InsertArchivalChunk,
|
||||||
arg.ID,
|
arg.ID,
|
||||||
arg.RecallID,
|
arg.RecallID,
|
||||||
|
|
@ -251,7 +285,7 @@ func (q *Queries) InsertArchivalChunk(ctx context.Context, arg InsertArchivalChu
|
||||||
arg.Source,
|
arg.Source,
|
||||||
arg.Hash,
|
arg.Hash,
|
||||||
)
|
)
|
||||||
var i ArchivalChunk
|
var i InsertArchivalChunkRow
|
||||||
err := row.Scan(
|
err := row.Scan(
|
||||||
&i.ID,
|
&i.ID,
|
||||||
&i.RecallID,
|
&i.RecallID,
|
||||||
|
|
@ -287,6 +321,17 @@ type ListAllArchivalChunksParams struct {
|
||||||
Lim int64 `db:"lim" json:"lim"`
|
Lim int64 `db:"lim" json:"lim"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ListAllArchivalChunksRow struct {
|
||||||
|
ID ids.UUID `db:"id" json:"id"`
|
||||||
|
RecallID ids.UUID `db:"recall_id" json:"recall_id"`
|
||||||
|
ChunkIndex int64 `db:"chunk_index" json:"chunk_index"`
|
||||||
|
Content string `db:"content" json:"content"`
|
||||||
|
Embedding memory.Embedding `db:"embedding" json:"embedding"`
|
||||||
|
Source string `db:"source" json:"source"`
|
||||||
|
Hash string `db:"hash" json:"hash"`
|
||||||
|
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
||||||
|
}
|
||||||
|
|
||||||
// ListAllArchivalChunks
|
// ListAllArchivalChunks
|
||||||
//
|
//
|
||||||
// SELECT ac.id,
|
// SELECT ac.id,
|
||||||
|
|
@ -302,15 +347,15 @@ type ListAllArchivalChunksParams struct {
|
||||||
// WHERE ri.agent_id = ?1
|
// WHERE ri.agent_id = ?1
|
||||||
// ORDER BY ac.created_at DESC
|
// ORDER BY ac.created_at DESC
|
||||||
// LIMIT ?3 OFFSET ?2
|
// LIMIT ?3 OFFSET ?2
|
||||||
func (q *Queries) ListAllArchivalChunks(ctx context.Context, arg ListAllArchivalChunksParams) ([]ArchivalChunk, error) {
|
func (q *Queries) ListAllArchivalChunks(ctx context.Context, arg ListAllArchivalChunksParams) ([]ListAllArchivalChunksRow, error) {
|
||||||
rows, err := q.db.QueryContext(ctx, ListAllArchivalChunks, arg.AgentID, arg.Off, arg.Lim)
|
rows, err := q.db.QueryContext(ctx, ListAllArchivalChunks, arg.AgentID, arg.Off, arg.Lim)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
items := []ArchivalChunk{}
|
items := []ListAllArchivalChunksRow{}
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var i ArchivalChunk
|
var i ListAllArchivalChunksRow
|
||||||
if err := rows.Scan(
|
if err := rows.Scan(
|
||||||
&i.ID,
|
&i.ID,
|
||||||
&i.RecallID,
|
&i.RecallID,
|
||||||
|
|
@ -357,6 +402,17 @@ type ListArchivalChunksParams struct {
|
||||||
Lim int64 `db:"lim" json:"lim"`
|
Lim int64 `db:"lim" json:"lim"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ListArchivalChunksRow struct {
|
||||||
|
ID ids.UUID `db:"id" json:"id"`
|
||||||
|
RecallID ids.UUID `db:"recall_id" json:"recall_id"`
|
||||||
|
ChunkIndex int64 `db:"chunk_index" json:"chunk_index"`
|
||||||
|
Content string `db:"content" json:"content"`
|
||||||
|
Embedding memory.Embedding `db:"embedding" json:"embedding"`
|
||||||
|
Source string `db:"source" json:"source"`
|
||||||
|
Hash string `db:"hash" json:"hash"`
|
||||||
|
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
||||||
|
}
|
||||||
|
|
||||||
// ListArchivalChunks
|
// ListArchivalChunks
|
||||||
//
|
//
|
||||||
// SELECT ac.id,
|
// SELECT ac.id,
|
||||||
|
|
@ -373,15 +429,15 @@ type ListArchivalChunksParams struct {
|
||||||
// AND ri.agent_id = ?2
|
// AND ri.agent_id = ?2
|
||||||
// ORDER BY ac.chunk_index
|
// ORDER BY ac.chunk_index
|
||||||
// LIMIT ?3
|
// LIMIT ?3
|
||||||
func (q *Queries) ListArchivalChunks(ctx context.Context, arg ListArchivalChunksParams) ([]ArchivalChunk, error) {
|
func (q *Queries) ListArchivalChunks(ctx context.Context, arg ListArchivalChunksParams) ([]ListArchivalChunksRow, error) {
|
||||||
rows, err := q.db.QueryContext(ctx, ListArchivalChunks, arg.RecallID, arg.AgentID, arg.Lim)
|
rows, err := q.db.QueryContext(ctx, ListArchivalChunks, arg.RecallID, arg.AgentID, arg.Lim)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
items := []ArchivalChunk{}
|
items := []ListArchivalChunksRow{}
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var i ArchivalChunk
|
var i ListArchivalChunksRow
|
||||||
if err := rows.Scan(
|
if err := rows.Scan(
|
||||||
&i.ID,
|
&i.ID,
|
||||||
&i.RecallID,
|
&i.RecallID,
|
||||||
|
|
|
||||||
210
pkg/memory/sqlc/consolidation.sql.go
Normal file
210
pkg/memory/sqlc/consolidation.sql.go
Normal file
|
|
@ -0,0 +1,210 @@
|
||||||
|
// Code generated by sqlc. DO NOT EDIT.
|
||||||
|
// versions:
|
||||||
|
// sqlc v1.30.0
|
||||||
|
// source: consolidation.sql
|
||||||
|
|
||||||
|
package sqlc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/ZanzyTHEbar/dragonscale/pkg/ids"
|
||||||
|
"github.com/ZanzyTHEbar/dragonscale/pkg/memory"
|
||||||
|
)
|
||||||
|
|
||||||
|
const FindSimilarRecallItems = `-- name: FindSimilarRecallItems :many
|
||||||
|
SELECT ri.id,
|
||||||
|
ri.agent_id,
|
||||||
|
ri.content,
|
||||||
|
ac.embedding as embedding,
|
||||||
|
vector_distance_cosine(ac.embedding, ?1) as distance
|
||||||
|
FROM recall_items ri
|
||||||
|
JOIN archival_chunks ac ON ac.recall_id = ri.id
|
||||||
|
AND ac.chunk_index = 0
|
||||||
|
WHERE ri.agent_id = ?2
|
||||||
|
AND ri.id != ?3
|
||||||
|
AND ac.embedding IS NOT NULL
|
||||||
|
ORDER BY distance ASC
|
||||||
|
LIMIT ?4
|
||||||
|
`
|
||||||
|
|
||||||
|
type FindSimilarRecallItemsParams struct {
|
||||||
|
QueryEmbedding interface{} `db:"query_embedding" json:"query_embedding"`
|
||||||
|
AgentID string `db:"agent_id" json:"agent_id"`
|
||||||
|
ExcludeID ids.UUID `db:"exclude_id" json:"exclude_id"`
|
||||||
|
Lim int64 `db:"lim" json:"lim"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type FindSimilarRecallItemsRow struct {
|
||||||
|
ID ids.UUID `db:"id" json:"id"`
|
||||||
|
AgentID string `db:"agent_id" json:"agent_id"`
|
||||||
|
Content string `db:"content" json:"content"`
|
||||||
|
Embedding memory.Embedding `db:"embedding" json:"embedding"`
|
||||||
|
Distance interface{} `db:"distance" json:"distance"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finds recall items with high cosine similarity to the given embedding.
|
||||||
|
// Uses libSQL's built-in vector similarity if available, otherwise returns
|
||||||
|
// candidates for manual comparison.
|
||||||
|
//
|
||||||
|
// SELECT ri.id,
|
||||||
|
// ri.agent_id,
|
||||||
|
// ri.content,
|
||||||
|
// ac.embedding as embedding,
|
||||||
|
// vector_distance_cosine(ac.embedding, ?1) as distance
|
||||||
|
// FROM recall_items ri
|
||||||
|
// JOIN archival_chunks ac ON ac.recall_id = ri.id
|
||||||
|
// AND ac.chunk_index = 0
|
||||||
|
// WHERE ri.agent_id = ?2
|
||||||
|
// AND ri.id != ?3
|
||||||
|
// AND ac.embedding IS NOT NULL
|
||||||
|
// ORDER BY distance ASC
|
||||||
|
// LIMIT ?4
|
||||||
|
func (q *Queries) FindSimilarRecallItems(ctx context.Context, arg FindSimilarRecallItemsParams) ([]FindSimilarRecallItemsRow, error) {
|
||||||
|
rows, err := q.db.QueryContext(ctx, FindSimilarRecallItems,
|
||||||
|
arg.QueryEmbedding,
|
||||||
|
arg.AgentID,
|
||||||
|
arg.ExcludeID,
|
||||||
|
arg.Lim,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
items := []FindSimilarRecallItemsRow{}
|
||||||
|
for rows.Next() {
|
||||||
|
var i FindSimilarRecallItemsRow
|
||||||
|
if err := rows.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.AgentID,
|
||||||
|
&i.Content,
|
||||||
|
&i.Embedding,
|
||||||
|
&i.Distance,
|
||||||
|
); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
items = append(items, i)
|
||||||
|
}
|
||||||
|
if err := rows.Close(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := rows.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return items, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
const ListRecallItemsForConsolidation = `-- name: ListRecallItemsForConsolidation :many
|
||||||
|
SELECT ri.id,
|
||||||
|
ri.agent_id,
|
||||||
|
ri.session_key,
|
||||||
|
ri.role,
|
||||||
|
ri.sector,
|
||||||
|
ri.importance,
|
||||||
|
ri.salience,
|
||||||
|
ri.decay_rate,
|
||||||
|
ri.content,
|
||||||
|
ri.tags,
|
||||||
|
ri.created_at,
|
||||||
|
ri.updated_at,
|
||||||
|
ac.embedding as embedding
|
||||||
|
FROM recall_items ri
|
||||||
|
LEFT JOIN archival_chunks ac ON ac.recall_id = ri.id
|
||||||
|
AND ac.chunk_index = 0
|
||||||
|
WHERE ri.created_at > ?1
|
||||||
|
AND ri.suppressed_at IS NULL
|
||||||
|
AND (
|
||||||
|
?2 = ''
|
||||||
|
OR ri.agent_id = ?2
|
||||||
|
)
|
||||||
|
ORDER BY ri.created_at DESC
|
||||||
|
LIMIT ?3
|
||||||
|
`
|
||||||
|
|
||||||
|
type ListRecallItemsForConsolidationParams struct {
|
||||||
|
Cutoff time.Time `db:"cutoff" json:"cutoff"`
|
||||||
|
AgentID interface{} `db:"agent_id" json:"agent_id"`
|
||||||
|
Lim int64 `db:"lim" json:"lim"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ListRecallItemsForConsolidationRow struct {
|
||||||
|
ID ids.UUID `db:"id" json:"id"`
|
||||||
|
AgentID string `db:"agent_id" json:"agent_id"`
|
||||||
|
SessionKey string `db:"session_key" json:"session_key"`
|
||||||
|
Role string `db:"role" json:"role"`
|
||||||
|
Sector memory.Sector `db:"sector" json:"sector"`
|
||||||
|
Importance float64 `db:"importance" json:"importance"`
|
||||||
|
Salience float64 `db:"salience" json:"salience"`
|
||||||
|
DecayRate float64 `db:"decay_rate" json:"decay_rate"`
|
||||||
|
Content string `db:"content" json:"content"`
|
||||||
|
Tags string `db:"tags" json:"tags"`
|
||||||
|
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
||||||
|
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
|
||||||
|
Embedding memory.Embedding `db:"embedding" json:"embedding"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Consolidation queries for memory graph maintenance (ADR-004)
|
||||||
|
// Returns recall items created after the cutoff time, joined with their first
|
||||||
|
// archival chunk's embedding for similarity comparison.
|
||||||
|
//
|
||||||
|
// SELECT ri.id,
|
||||||
|
// ri.agent_id,
|
||||||
|
// ri.session_key,
|
||||||
|
// ri.role,
|
||||||
|
// ri.sector,
|
||||||
|
// ri.importance,
|
||||||
|
// ri.salience,
|
||||||
|
// ri.decay_rate,
|
||||||
|
// ri.content,
|
||||||
|
// ri.tags,
|
||||||
|
// ri.created_at,
|
||||||
|
// ri.updated_at,
|
||||||
|
// ac.embedding as embedding
|
||||||
|
// FROM recall_items ri
|
||||||
|
// LEFT JOIN archival_chunks ac ON ac.recall_id = ri.id
|
||||||
|
// AND ac.chunk_index = 0
|
||||||
|
// WHERE ri.created_at > ?1
|
||||||
|
// AND ri.suppressed_at IS NULL
|
||||||
|
// AND (
|
||||||
|
// ?2 = ''
|
||||||
|
// OR ri.agent_id = ?2
|
||||||
|
// )
|
||||||
|
// ORDER BY ri.created_at DESC
|
||||||
|
// LIMIT ?3
|
||||||
|
func (q *Queries) ListRecallItemsForConsolidation(ctx context.Context, arg ListRecallItemsForConsolidationParams) ([]ListRecallItemsForConsolidationRow, error) {
|
||||||
|
rows, err := q.db.QueryContext(ctx, ListRecallItemsForConsolidation, arg.Cutoff, arg.AgentID, arg.Lim)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
items := []ListRecallItemsForConsolidationRow{}
|
||||||
|
for rows.Next() {
|
||||||
|
var i ListRecallItemsForConsolidationRow
|
||||||
|
if err := rows.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.AgentID,
|
||||||
|
&i.SessionKey,
|
||||||
|
&i.Role,
|
||||||
|
&i.Sector,
|
||||||
|
&i.Importance,
|
||||||
|
&i.Salience,
|
||||||
|
&i.DecayRate,
|
||||||
|
&i.Content,
|
||||||
|
&i.Tags,
|
||||||
|
&i.CreatedAt,
|
||||||
|
&i.UpdatedAt,
|
||||||
|
&i.Embedding,
|
||||||
|
); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
items = append(items, i)
|
||||||
|
}
|
||||||
|
if err := rows.Close(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := rows.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return items, nil
|
||||||
|
}
|
||||||
239
pkg/memory/sqlc/immutable_messages.sql.go
Normal file
239
pkg/memory/sqlc/immutable_messages.sql.go
Normal file
|
|
@ -0,0 +1,239 @@
|
||||||
|
// Code generated by sqlc. DO NOT EDIT.
|
||||||
|
// versions:
|
||||||
|
// sqlc v1.30.0
|
||||||
|
// source: immutable_messages.sql
|
||||||
|
|
||||||
|
package sqlc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/ZanzyTHEbar/dragonscale/pkg/ids"
|
||||||
|
)
|
||||||
|
|
||||||
|
const CountImmutableMessages = `-- name: CountImmutableMessages :one
|
||||||
|
SELECT COUNT(*)
|
||||||
|
FROM immutable_messages
|
||||||
|
WHERE session_key = ?1
|
||||||
|
`
|
||||||
|
|
||||||
|
type CountImmutableMessagesParams struct {
|
||||||
|
SessionKey string `db:"session_key" json:"session_key"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// CountImmutableMessages
|
||||||
|
//
|
||||||
|
// SELECT COUNT(*)
|
||||||
|
// FROM immutable_messages
|
||||||
|
// WHERE session_key = ?1
|
||||||
|
func (q *Queries) CountImmutableMessages(ctx context.Context, arg CountImmutableMessagesParams) (int64, error) {
|
||||||
|
row := q.db.QueryRowContext(ctx, CountImmutableMessages, arg.SessionKey)
|
||||||
|
var count int64
|
||||||
|
err := row.Scan(&count)
|
||||||
|
return count, err
|
||||||
|
}
|
||||||
|
|
||||||
|
const GetImmutableMessage = `-- name: GetImmutableMessage :one
|
||||||
|
SELECT id,
|
||||||
|
session_key,
|
||||||
|
role,
|
||||||
|
content,
|
||||||
|
tool_call_id,
|
||||||
|
tool_calls,
|
||||||
|
token_estimate,
|
||||||
|
created_at
|
||||||
|
FROM immutable_messages
|
||||||
|
WHERE id = ?1
|
||||||
|
LIMIT 1
|
||||||
|
`
|
||||||
|
|
||||||
|
type GetImmutableMessageParams struct {
|
||||||
|
ID ids.UUID `db:"id" json:"id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetImmutableMessage
|
||||||
|
//
|
||||||
|
// SELECT id,
|
||||||
|
// session_key,
|
||||||
|
// role,
|
||||||
|
// content,
|
||||||
|
// tool_call_id,
|
||||||
|
// tool_calls,
|
||||||
|
// token_estimate,
|
||||||
|
// created_at
|
||||||
|
// FROM immutable_messages
|
||||||
|
// WHERE id = ?1
|
||||||
|
// LIMIT 1
|
||||||
|
func (q *Queries) GetImmutableMessage(ctx context.Context, arg GetImmutableMessageParams) (ImmutableMessage, error) {
|
||||||
|
row := q.db.QueryRowContext(ctx, GetImmutableMessage, arg.ID)
|
||||||
|
var i ImmutableMessage
|
||||||
|
err := row.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.SessionKey,
|
||||||
|
&i.Role,
|
||||||
|
&i.Content,
|
||||||
|
&i.ToolCallID,
|
||||||
|
&i.ToolCalls,
|
||||||
|
&i.TokenEstimate,
|
||||||
|
&i.CreatedAt,
|
||||||
|
)
|
||||||
|
return i, err
|
||||||
|
}
|
||||||
|
|
||||||
|
const InsertImmutableMessage = `-- name: InsertImmutableMessage :one
|
||||||
|
INSERT INTO immutable_messages (
|
||||||
|
id,
|
||||||
|
session_key,
|
||||||
|
role,
|
||||||
|
content,
|
||||||
|
tool_call_id,
|
||||||
|
tool_calls,
|
||||||
|
token_estimate
|
||||||
|
)
|
||||||
|
VALUES (
|
||||||
|
?1,
|
||||||
|
?2,
|
||||||
|
?3,
|
||||||
|
?4,
|
||||||
|
?5,
|
||||||
|
?6,
|
||||||
|
?7
|
||||||
|
)
|
||||||
|
RETURNING id,
|
||||||
|
session_key,
|
||||||
|
role,
|
||||||
|
content,
|
||||||
|
tool_call_id,
|
||||||
|
tool_calls,
|
||||||
|
token_estimate,
|
||||||
|
created_at
|
||||||
|
`
|
||||||
|
|
||||||
|
type InsertImmutableMessageParams struct {
|
||||||
|
ID ids.UUID `db:"id" json:"id"`
|
||||||
|
SessionKey string `db:"session_key" json:"session_key"`
|
||||||
|
Role string `db:"role" json:"role"`
|
||||||
|
Content string `db:"content" json:"content"`
|
||||||
|
ToolCallID string `db:"tool_call_id" json:"tool_call_id"`
|
||||||
|
ToolCalls string `db:"tool_calls" json:"tool_calls"`
|
||||||
|
TokenEstimate int64 `db:"token_estimate" json:"token_estimate"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Immutable Messages queries (LCM ADR-001: append-only verbatim message store)
|
||||||
|
//
|
||||||
|
// INSERT INTO immutable_messages (
|
||||||
|
// id,
|
||||||
|
// session_key,
|
||||||
|
// role,
|
||||||
|
// content,
|
||||||
|
// tool_call_id,
|
||||||
|
// tool_calls,
|
||||||
|
// token_estimate
|
||||||
|
// )
|
||||||
|
// VALUES (
|
||||||
|
// ?1,
|
||||||
|
// ?2,
|
||||||
|
// ?3,
|
||||||
|
// ?4,
|
||||||
|
// ?5,
|
||||||
|
// ?6,
|
||||||
|
// ?7
|
||||||
|
// )
|
||||||
|
// RETURNING id,
|
||||||
|
// session_key,
|
||||||
|
// role,
|
||||||
|
// content,
|
||||||
|
// tool_call_id,
|
||||||
|
// tool_calls,
|
||||||
|
// token_estimate,
|
||||||
|
// created_at
|
||||||
|
func (q *Queries) InsertImmutableMessage(ctx context.Context, arg InsertImmutableMessageParams) (ImmutableMessage, error) {
|
||||||
|
row := q.db.QueryRowContext(ctx, InsertImmutableMessage,
|
||||||
|
arg.ID,
|
||||||
|
arg.SessionKey,
|
||||||
|
arg.Role,
|
||||||
|
arg.Content,
|
||||||
|
arg.ToolCallID,
|
||||||
|
arg.ToolCalls,
|
||||||
|
arg.TokenEstimate,
|
||||||
|
)
|
||||||
|
var i ImmutableMessage
|
||||||
|
err := row.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.SessionKey,
|
||||||
|
&i.Role,
|
||||||
|
&i.Content,
|
||||||
|
&i.ToolCallID,
|
||||||
|
&i.ToolCalls,
|
||||||
|
&i.TokenEstimate,
|
||||||
|
&i.CreatedAt,
|
||||||
|
)
|
||||||
|
return i, err
|
||||||
|
}
|
||||||
|
|
||||||
|
const ListImmutableMessages = `-- name: ListImmutableMessages :many
|
||||||
|
SELECT id,
|
||||||
|
session_key,
|
||||||
|
role,
|
||||||
|
content,
|
||||||
|
tool_call_id,
|
||||||
|
tool_calls,
|
||||||
|
token_estimate,
|
||||||
|
created_at
|
||||||
|
FROM immutable_messages
|
||||||
|
WHERE session_key = ?1
|
||||||
|
ORDER BY created_at ASC
|
||||||
|
LIMIT ?3 OFFSET ?2
|
||||||
|
`
|
||||||
|
|
||||||
|
type ListImmutableMessagesParams struct {
|
||||||
|
SessionKey string `db:"session_key" json:"session_key"`
|
||||||
|
Off int64 `db:"off" json:"off"`
|
||||||
|
Lim int64 `db:"lim" json:"lim"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListImmutableMessages
|
||||||
|
//
|
||||||
|
// SELECT id,
|
||||||
|
// session_key,
|
||||||
|
// role,
|
||||||
|
// content,
|
||||||
|
// tool_call_id,
|
||||||
|
// tool_calls,
|
||||||
|
// token_estimate,
|
||||||
|
// created_at
|
||||||
|
// FROM immutable_messages
|
||||||
|
// WHERE session_key = ?1
|
||||||
|
// ORDER BY created_at ASC
|
||||||
|
// LIMIT ?3 OFFSET ?2
|
||||||
|
func (q *Queries) ListImmutableMessages(ctx context.Context, arg ListImmutableMessagesParams) ([]ImmutableMessage, error) {
|
||||||
|
rows, err := q.db.QueryContext(ctx, ListImmutableMessages, arg.SessionKey, arg.Off, arg.Lim)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
items := []ImmutableMessage{}
|
||||||
|
for rows.Next() {
|
||||||
|
var i ImmutableMessage
|
||||||
|
if err := rows.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.SessionKey,
|
||||||
|
&i.Role,
|
||||||
|
&i.Content,
|
||||||
|
&i.ToolCallID,
|
||||||
|
&i.ToolCalls,
|
||||||
|
&i.TokenEstimate,
|
||||||
|
&i.CreatedAt,
|
||||||
|
); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
items = append(items, i)
|
||||||
|
}
|
||||||
|
if err := rows.Close(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := rows.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return items, nil
|
||||||
|
}
|
||||||
235
pkg/memory/sqlc/memory_edges.sql.go
Normal file
235
pkg/memory/sqlc/memory_edges.sql.go
Normal file
|
|
@ -0,0 +1,235 @@
|
||||||
|
// Code generated by sqlc. DO NOT EDIT.
|
||||||
|
// versions:
|
||||||
|
// sqlc v1.30.0
|
||||||
|
// source: memory_edges.sql
|
||||||
|
|
||||||
|
package sqlc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/ZanzyTHEbar/dragonscale/pkg/ids"
|
||||||
|
)
|
||||||
|
|
||||||
|
const CountMemoryEdgesForItem = `-- name: CountMemoryEdgesForItem :one
|
||||||
|
SELECT COUNT(*)
|
||||||
|
FROM memory_edges
|
||||||
|
WHERE from_id = ?1
|
||||||
|
OR to_id = ?1
|
||||||
|
`
|
||||||
|
|
||||||
|
type CountMemoryEdgesForItemParams struct {
|
||||||
|
MemoryID ids.UUID `db:"memory_id" json:"memory_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// CountMemoryEdgesForItem
|
||||||
|
//
|
||||||
|
// SELECT COUNT(*)
|
||||||
|
// FROM memory_edges
|
||||||
|
// WHERE from_id = ?1
|
||||||
|
// OR to_id = ?1
|
||||||
|
func (q *Queries) CountMemoryEdgesForItem(ctx context.Context, arg CountMemoryEdgesForItemParams) (int64, error) {
|
||||||
|
row := q.db.QueryRowContext(ctx, CountMemoryEdgesForItem, arg.MemoryID)
|
||||||
|
var count int64
|
||||||
|
err := row.Scan(&count)
|
||||||
|
return count, err
|
||||||
|
}
|
||||||
|
|
||||||
|
const DeleteMemoryEdgesForItem = `-- name: DeleteMemoryEdgesForItem :exec
|
||||||
|
DELETE FROM memory_edges
|
||||||
|
WHERE from_id = ?1
|
||||||
|
OR to_id = ?1
|
||||||
|
`
|
||||||
|
|
||||||
|
type DeleteMemoryEdgesForItemParams struct {
|
||||||
|
MemoryID ids.UUID `db:"memory_id" json:"memory_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteMemoryEdgesForItem
|
||||||
|
//
|
||||||
|
// DELETE FROM memory_edges
|
||||||
|
// WHERE from_id = ?1
|
||||||
|
// OR to_id = ?1
|
||||||
|
func (q *Queries) DeleteMemoryEdgesForItem(ctx context.Context, arg DeleteMemoryEdgesForItemParams) error {
|
||||||
|
_, err := q.db.ExecContext(ctx, DeleteMemoryEdgesForItem, arg.MemoryID)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
const InsertMemoryEdge = `-- name: InsertMemoryEdge :one
|
||||||
|
INSERT INTO memory_edges (from_id, to_id, edge_type, weight)
|
||||||
|
VALUES (
|
||||||
|
?1,
|
||||||
|
?2,
|
||||||
|
?3,
|
||||||
|
?4
|
||||||
|
)
|
||||||
|
RETURNING id,
|
||||||
|
from_id,
|
||||||
|
to_id,
|
||||||
|
edge_type,
|
||||||
|
weight,
|
||||||
|
created_at
|
||||||
|
`
|
||||||
|
|
||||||
|
type InsertMemoryEdgeParams struct {
|
||||||
|
FromID ids.UUID `db:"from_id" json:"from_id"`
|
||||||
|
ToID ids.UUID `db:"to_id" json:"to_id"`
|
||||||
|
EdgeType string `db:"edge_type" json:"edge_type"`
|
||||||
|
Weight float64 `db:"weight" json:"weight"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Memory Graph Edges queries (ADR-004: typed relational memory)
|
||||||
|
//
|
||||||
|
// INSERT INTO memory_edges (from_id, to_id, edge_type, weight)
|
||||||
|
// VALUES (
|
||||||
|
// ?1,
|
||||||
|
// ?2,
|
||||||
|
// ?3,
|
||||||
|
// ?4
|
||||||
|
// )
|
||||||
|
// RETURNING id,
|
||||||
|
// from_id,
|
||||||
|
// to_id,
|
||||||
|
// edge_type,
|
||||||
|
// weight,
|
||||||
|
// created_at
|
||||||
|
func (q *Queries) InsertMemoryEdge(ctx context.Context, arg InsertMemoryEdgeParams) (MemoryEdge, error) {
|
||||||
|
row := q.db.QueryRowContext(ctx, InsertMemoryEdge,
|
||||||
|
arg.FromID,
|
||||||
|
arg.ToID,
|
||||||
|
arg.EdgeType,
|
||||||
|
arg.Weight,
|
||||||
|
)
|
||||||
|
var i MemoryEdge
|
||||||
|
err := row.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.FromID,
|
||||||
|
&i.ToID,
|
||||||
|
&i.EdgeType,
|
||||||
|
&i.Weight,
|
||||||
|
&i.CreatedAt,
|
||||||
|
)
|
||||||
|
return i, err
|
||||||
|
}
|
||||||
|
|
||||||
|
const ListMemoryEdgesByType = `-- name: ListMemoryEdgesByType :many
|
||||||
|
SELECT id,
|
||||||
|
from_id,
|
||||||
|
to_id,
|
||||||
|
edge_type,
|
||||||
|
weight,
|
||||||
|
created_at
|
||||||
|
FROM memory_edges
|
||||||
|
WHERE edge_type = ?1
|
||||||
|
ORDER BY created_at DESC
|
||||||
|
LIMIT ?2
|
||||||
|
`
|
||||||
|
|
||||||
|
type ListMemoryEdgesByTypeParams struct {
|
||||||
|
EdgeType string `db:"edge_type" json:"edge_type"`
|
||||||
|
Lim int64 `db:"lim" json:"lim"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListMemoryEdgesByType
|
||||||
|
//
|
||||||
|
// SELECT id,
|
||||||
|
// from_id,
|
||||||
|
// to_id,
|
||||||
|
// edge_type,
|
||||||
|
// weight,
|
||||||
|
// created_at
|
||||||
|
// FROM memory_edges
|
||||||
|
// WHERE edge_type = ?1
|
||||||
|
// ORDER BY created_at DESC
|
||||||
|
// LIMIT ?2
|
||||||
|
func (q *Queries) ListMemoryEdgesByType(ctx context.Context, arg ListMemoryEdgesByTypeParams) ([]MemoryEdge, error) {
|
||||||
|
rows, err := q.db.QueryContext(ctx, ListMemoryEdgesByType, arg.EdgeType, arg.Lim)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
items := []MemoryEdge{}
|
||||||
|
for rows.Next() {
|
||||||
|
var i MemoryEdge
|
||||||
|
if err := rows.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.FromID,
|
||||||
|
&i.ToID,
|
||||||
|
&i.EdgeType,
|
||||||
|
&i.Weight,
|
||||||
|
&i.CreatedAt,
|
||||||
|
); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
items = append(items, i)
|
||||||
|
}
|
||||||
|
if err := rows.Close(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := rows.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return items, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
const ListMemoryEdgesForItem = `-- name: ListMemoryEdgesForItem :many
|
||||||
|
SELECT id,
|
||||||
|
from_id,
|
||||||
|
to_id,
|
||||||
|
edge_type,
|
||||||
|
weight,
|
||||||
|
created_at
|
||||||
|
FROM memory_edges
|
||||||
|
WHERE from_id = ?1
|
||||||
|
OR to_id = ?1
|
||||||
|
ORDER BY created_at DESC
|
||||||
|
LIMIT ?2
|
||||||
|
`
|
||||||
|
|
||||||
|
type ListMemoryEdgesForItemParams struct {
|
||||||
|
MemoryID ids.UUID `db:"memory_id" json:"memory_id"`
|
||||||
|
Lim int64 `db:"lim" json:"lim"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListMemoryEdgesForItem
|
||||||
|
//
|
||||||
|
// SELECT id,
|
||||||
|
// from_id,
|
||||||
|
// to_id,
|
||||||
|
// edge_type,
|
||||||
|
// weight,
|
||||||
|
// created_at
|
||||||
|
// FROM memory_edges
|
||||||
|
// WHERE from_id = ?1
|
||||||
|
// OR to_id = ?1
|
||||||
|
// ORDER BY created_at DESC
|
||||||
|
// LIMIT ?2
|
||||||
|
func (q *Queries) ListMemoryEdgesForItem(ctx context.Context, arg ListMemoryEdgesForItemParams) ([]MemoryEdge, error) {
|
||||||
|
rows, err := q.db.QueryContext(ctx, ListMemoryEdgesForItem, arg.MemoryID, arg.Lim)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
items := []MemoryEdge{}
|
||||||
|
for rows.Next() {
|
||||||
|
var i MemoryEdge
|
||||||
|
if err := rows.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.FromID,
|
||||||
|
&i.ToID,
|
||||||
|
&i.EdgeType,
|
||||||
|
&i.Weight,
|
||||||
|
&i.CreatedAt,
|
||||||
|
); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
items = append(items, i)
|
||||||
|
}
|
||||||
|
if err := rows.Close(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := rows.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return items, nil
|
||||||
|
}
|
||||||
|
|
@ -181,14 +181,15 @@ type AgentToolResult struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type ArchivalChunk struct {
|
type ArchivalChunk struct {
|
||||||
ID ids.UUID `db:"id" json:"id"`
|
ID ids.UUID `db:"id" json:"id"`
|
||||||
RecallID ids.UUID `db:"recall_id" json:"recall_id"`
|
RecallID ids.UUID `db:"recall_id" json:"recall_id"`
|
||||||
ChunkIndex int64 `db:"chunk_index" json:"chunk_index"`
|
ChunkIndex int64 `db:"chunk_index" json:"chunk_index"`
|
||||||
Content string `db:"content" json:"content"`
|
Content string `db:"content" json:"content"`
|
||||||
Embedding memory.Embedding `db:"embedding" json:"embedding"`
|
Embedding memory.Embedding `db:"embedding" json:"embedding"`
|
||||||
Source string `db:"source" json:"source"`
|
Source string `db:"source" json:"source"`
|
||||||
Hash string `db:"hash" json:"hash"`
|
Hash string `db:"hash" json:"hash"`
|
||||||
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
||||||
|
SuppressedAt *time.Time `db:"suppressed_at" json:"suppressed_at"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type DagEdge struct {
|
type DagEdge struct {
|
||||||
|
|
@ -232,6 +233,17 @@ type DagSnapshot struct {
|
||||||
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
|
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ImmutableMessage struct {
|
||||||
|
ID ids.UUID `db:"id" json:"id"`
|
||||||
|
SessionKey string `db:"session_key" json:"session_key"`
|
||||||
|
Role string `db:"role" json:"role"`
|
||||||
|
Content string `db:"content" json:"content"`
|
||||||
|
ToolCallID string `db:"tool_call_id" json:"tool_call_id"`
|
||||||
|
ToolCalls string `db:"tool_calls" json:"tool_calls"`
|
||||||
|
TokenEstimate int64 `db:"token_estimate" json:"token_estimate"`
|
||||||
|
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
||||||
|
}
|
||||||
|
|
||||||
type Job struct {
|
type Job struct {
|
||||||
ID ids.UUID `db:"id" json:"id"`
|
ID ids.UUID `db:"id" json:"id"`
|
||||||
Kind string `db:"kind" json:"kind"`
|
Kind string `db:"kind" json:"kind"`
|
||||||
|
|
@ -284,6 +296,15 @@ type MapRun struct {
|
||||||
CompletedAt *time.Time `db:"completed_at" json:"completed_at"`
|
CompletedAt *time.Time `db:"completed_at" json:"completed_at"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type MemoryEdge struct {
|
||||||
|
ID int64 `db:"id" json:"id"`
|
||||||
|
FromID ids.UUID `db:"from_id" json:"from_id"`
|
||||||
|
ToID ids.UUID `db:"to_id" json:"to_id"`
|
||||||
|
EdgeType string `db:"edge_type" json:"edge_type"`
|
||||||
|
Weight float64 `db:"weight" json:"weight"`
|
||||||
|
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
||||||
|
}
|
||||||
|
|
||||||
type MemorySummary struct {
|
type MemorySummary struct {
|
||||||
ID ids.UUID `db:"id" json:"id"`
|
ID ids.UUID `db:"id" json:"id"`
|
||||||
AgentID string `db:"agent_id" json:"agent_id"`
|
AgentID string `db:"agent_id" json:"agent_id"`
|
||||||
|
|
@ -294,19 +315,30 @@ type MemorySummary struct {
|
||||||
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type RecallItem struct {
|
type TaskBaseline struct {
|
||||||
ID ids.UUID `db:"id" json:"id"`
|
AgentID string `db:"agent_id" json:"agent_id"`
|
||||||
AgentID string `db:"agent_id" json:"agent_id"`
|
Count *int64 `db:"count" json:"count"`
|
||||||
SessionKey string `db:"session_key" json:"session_key"`
|
MeanTokens *int64 `db:"mean_tokens" json:"mean_tokens"`
|
||||||
Role string `db:"role" json:"role"`
|
MeanErrors *float64 `db:"mean_errors" json:"mean_errors"`
|
||||||
Sector memory.Sector `db:"sector" json:"sector"`
|
MeanUserCorrections *float64 `db:"mean_user_corrections" json:"mean_user_corrections"`
|
||||||
Importance float64 `db:"importance" json:"importance"`
|
M2Tokens *float64 `db:"m2_tokens" json:"m2_tokens"`
|
||||||
Salience float64 `db:"salience" json:"salience"`
|
M2Errors *float64 `db:"m2_errors" json:"m2_errors"`
|
||||||
DecayRate float64 `db:"decay_rate" json:"decay_rate"`
|
M2UserCorrections *float64 `db:"m2_user_corrections" json:"m2_user_corrections"`
|
||||||
Content string `db:"content" json:"content"`
|
UpdatedAt *time.Time `db:"updated_at" json:"updated_at"`
|
||||||
Tags string `db:"tags" json:"tags"`
|
}
|
||||||
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
|
||||||
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
|
type TaskCompletion struct {
|
||||||
|
ID ids.UUID `db:"id" json:"id"`
|
||||||
|
AgentID string `db:"agent_id" json:"agent_id"`
|
||||||
|
ConversationID ids.UUID `db:"conversation_id" json:"conversation_id"`
|
||||||
|
RunID ids.UUID `db:"run_id" json:"run_id"`
|
||||||
|
Description string `db:"description" json:"description"`
|
||||||
|
TokensUsed *int64 `db:"tokens_used" json:"tokens_used"`
|
||||||
|
ToolCalls *int64 `db:"tool_calls" json:"tool_calls"`
|
||||||
|
Errors *int64 `db:"errors" json:"errors"`
|
||||||
|
UserCorrections *int64 `db:"user_corrections" json:"user_corrections"`
|
||||||
|
Completed bool `db:"completed" json:"completed"`
|
||||||
|
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type WorkingContext struct {
|
type WorkingContext struct {
|
||||||
|
|
|
||||||
|
|
@ -115,6 +115,13 @@ type Querier interface {
|
||||||
// JOIN recall_items ri ON ac.recall_id = ri.id
|
// JOIN recall_items ri ON ac.recall_id = ri.id
|
||||||
// WHERE ri.agent_id = ?1
|
// WHERE ri.agent_id = ?1
|
||||||
CountArchivalChunks(ctx context.Context, arg CountArchivalChunksParams) (int64, error)
|
CountArchivalChunks(ctx context.Context, arg CountArchivalChunksParams) (int64, error)
|
||||||
|
//CountArchivalChunksWithoutEmbedding
|
||||||
|
//
|
||||||
|
// SELECT COUNT(*)
|
||||||
|
// FROM archival_chunks
|
||||||
|
// WHERE embedding IS NULL
|
||||||
|
// AND suppressed_at IS NULL
|
||||||
|
CountArchivalChunksWithoutEmbedding(ctx context.Context) (int64, error)
|
||||||
//CountAuditEntries
|
//CountAuditEntries
|
||||||
//
|
//
|
||||||
// SELECT COUNT(*)
|
// SELECT COUNT(*)
|
||||||
|
|
@ -128,6 +135,12 @@ type Querier interface {
|
||||||
// WHERE agent_id = ?1
|
// WHERE agent_id = ?1
|
||||||
// AND action = ?2
|
// AND action = ?2
|
||||||
CountAuditEntriesByAction(ctx context.Context, arg CountAuditEntriesByActionParams) (int64, error)
|
CountAuditEntriesByAction(ctx context.Context, arg CountAuditEntriesByActionParams) (int64, error)
|
||||||
|
//CountImmutableMessages
|
||||||
|
//
|
||||||
|
// SELECT COUNT(*)
|
||||||
|
// FROM immutable_messages
|
||||||
|
// WHERE session_key = ?1
|
||||||
|
CountImmutableMessages(ctx context.Context, arg CountImmutableMessagesParams) (int64, error)
|
||||||
//CountJobsByStatus
|
//CountJobsByStatus
|
||||||
//
|
//
|
||||||
// SELECT status,
|
// SELECT status,
|
||||||
|
|
@ -149,11 +162,19 @@ type Querier interface {
|
||||||
// WHERE run_id = ?1
|
// WHERE run_id = ?1
|
||||||
// GROUP BY status
|
// GROUP BY status
|
||||||
CountMapItemsByRunAndStatus(ctx context.Context, arg CountMapItemsByRunAndStatusParams) ([]CountMapItemsByRunAndStatusRow, error)
|
CountMapItemsByRunAndStatus(ctx context.Context, arg CountMapItemsByRunAndStatusParams) ([]CountMapItemsByRunAndStatusRow, error)
|
||||||
|
//CountMemoryEdgesForItem
|
||||||
|
//
|
||||||
|
// SELECT COUNT(*)
|
||||||
|
// FROM memory_edges
|
||||||
|
// WHERE from_id = ?1
|
||||||
|
// OR to_id = ?1
|
||||||
|
CountMemoryEdgesForItem(ctx context.Context, arg CountMemoryEdgesForItemParams) (int64, error)
|
||||||
//CountRecallItems
|
//CountRecallItems
|
||||||
//
|
//
|
||||||
// SELECT COUNT(*)
|
// SELECT COUNT(*)
|
||||||
// FROM recall_items
|
// FROM recall_items
|
||||||
// WHERE agent_id = ?1
|
// WHERE agent_id = ?1
|
||||||
|
// AND suppressed_at IS NULL
|
||||||
// AND (
|
// AND (
|
||||||
// session_key = ?2
|
// session_key = ?2
|
||||||
// OR ?2 = ''
|
// OR ?2 = ''
|
||||||
|
|
@ -221,6 +242,23 @@ type Querier interface {
|
||||||
// VALUES (?, ?, ?, ?)
|
// VALUES (?, ?, ?, ?)
|
||||||
// RETURNING id, conversation_id, title, metadata_json, created_at, updated_at
|
// RETURNING id, conversation_id, title, metadata_json, created_at, updated_at
|
||||||
CreateAgentThread(ctx context.Context, arg CreateAgentThreadParams) (AgentThread, error)
|
CreateAgentThread(ctx context.Context, arg CreateAgentThreadParams) (AgentThread, error)
|
||||||
|
// Batch decay of recall item importance (Cortex decay task)
|
||||||
|
//
|
||||||
|
// UPDATE recall_items
|
||||||
|
// SET importance = MAX(
|
||||||
|
// recall_items.importance * ?1,
|
||||||
|
// ?2
|
||||||
|
// ),
|
||||||
|
// updated_at = datetime('now')
|
||||||
|
// WHERE recall_items.id IN (
|
||||||
|
// SELECT ri.id
|
||||||
|
// FROM recall_items ri
|
||||||
|
// WHERE ri.importance > ?2
|
||||||
|
// AND ri.suppressed_at IS NULL
|
||||||
|
// ORDER BY ri.updated_at ASC
|
||||||
|
// LIMIT ?3
|
||||||
|
// )
|
||||||
|
DecayRecallImportanceBatch(ctx context.Context, arg DecayRecallImportanceBatchParams) error
|
||||||
//DeleteAgentConversationLink
|
//DeleteAgentConversationLink
|
||||||
//
|
//
|
||||||
// DELETE FROM agent_conversation_links
|
// DELETE FROM agent_conversation_links
|
||||||
|
|
@ -245,6 +283,12 @@ type Querier interface {
|
||||||
// WHERE agent_id = ?1
|
// WHERE agent_id = ?1
|
||||||
// AND key = ?2
|
// AND key = ?2
|
||||||
DeleteKV(ctx context.Context, arg DeleteKVParams) error
|
DeleteKV(ctx context.Context, arg DeleteKVParams) error
|
||||||
|
//DeleteMemoryEdgesForItem
|
||||||
|
//
|
||||||
|
// DELETE FROM memory_edges
|
||||||
|
// WHERE from_id = ?1
|
||||||
|
// OR to_id = ?1
|
||||||
|
DeleteMemoryEdgesForItem(ctx context.Context, arg DeleteMemoryEdgesForItemParams) error
|
||||||
//DeleteRecallItem
|
//DeleteRecallItem
|
||||||
//
|
//
|
||||||
// DELETE FROM recall_items
|
// DELETE FROM recall_items
|
||||||
|
|
@ -295,6 +339,24 @@ type Querier interface {
|
||||||
// created_at ASC
|
// created_at ASC
|
||||||
// LIMIT 1
|
// LIMIT 1
|
||||||
FindNextRunnableJob(ctx context.Context) (ids.UUID, error)
|
FindNextRunnableJob(ctx context.Context) (ids.UUID, error)
|
||||||
|
// Finds recall items with high cosine similarity to the given embedding.
|
||||||
|
// Uses libSQL's built-in vector similarity if available, otherwise returns
|
||||||
|
// candidates for manual comparison.
|
||||||
|
//
|
||||||
|
// SELECT ri.id,
|
||||||
|
// ri.agent_id,
|
||||||
|
// ri.content,
|
||||||
|
// ac.embedding as embedding,
|
||||||
|
// vector_distance_cosine(ac.embedding, ?1) as distance
|
||||||
|
// FROM recall_items ri
|
||||||
|
// JOIN archival_chunks ac ON ac.recall_id = ri.id
|
||||||
|
// AND ac.chunk_index = 0
|
||||||
|
// WHERE ri.agent_id = ?2
|
||||||
|
// AND ri.id != ?3
|
||||||
|
// AND ac.embedding IS NOT NULL
|
||||||
|
// ORDER BY distance ASC
|
||||||
|
// LIMIT ?4
|
||||||
|
FindSimilarRecallItems(ctx context.Context, arg FindSimilarRecallItemsParams) ([]FindSimilarRecallItemsRow, error)
|
||||||
//GetAgentCheckpointByConversationIDAndName
|
//GetAgentCheckpointByConversationIDAndName
|
||||||
//
|
//
|
||||||
// SELECT id, conversation_id, name, run_state_id, metadata_json, created_at, updated_at
|
// SELECT id, conversation_id, name, run_state_id, metadata_json, created_at, updated_at
|
||||||
|
|
@ -354,7 +416,7 @@ type Querier interface {
|
||||||
// WHERE ac.id = ?1
|
// WHERE ac.id = ?1
|
||||||
// AND ri.agent_id = ?2
|
// AND ri.agent_id = ?2
|
||||||
// LIMIT 1
|
// LIMIT 1
|
||||||
GetArchivalChunk(ctx context.Context, arg GetArchivalChunkParams) (ArchivalChunk, error)
|
GetArchivalChunk(ctx context.Context, arg GetArchivalChunkParams) (GetArchivalChunkRow, error)
|
||||||
//GetArchivalChunksByIDs
|
//GetArchivalChunksByIDs
|
||||||
//
|
//
|
||||||
// SELECT ac.id,
|
// SELECT ac.id,
|
||||||
|
|
@ -369,7 +431,26 @@ type Querier interface {
|
||||||
// JOIN recall_items ri ON ac.recall_id = ri.id
|
// JOIN recall_items ri ON ac.recall_id = ri.id
|
||||||
// WHERE ac.id IN (/*SLICE:ids*/?)
|
// WHERE ac.id IN (/*SLICE:ids*/?)
|
||||||
// AND ri.agent_id = ?2
|
// AND ri.agent_id = ?2
|
||||||
GetArchivalChunksByIDs(ctx context.Context, arg GetArchivalChunksByIDsParams) ([]ArchivalChunk, error)
|
GetArchivalChunksByIDs(ctx context.Context, arg GetArchivalChunksByIDsParams) ([]GetArchivalChunksByIDsRow, error)
|
||||||
|
// Get tasks completed since the given time for RL processing
|
||||||
|
//
|
||||||
|
// SELECT id,
|
||||||
|
// agent_id,
|
||||||
|
// conversation_id,
|
||||||
|
// run_id,
|
||||||
|
// description,
|
||||||
|
// tokens_used,
|
||||||
|
// tool_calls,
|
||||||
|
// errors,
|
||||||
|
// user_corrections,
|
||||||
|
// completed,
|
||||||
|
// created_at
|
||||||
|
// FROM task_completions
|
||||||
|
// WHERE agent_id = ?1
|
||||||
|
// AND created_at > ?2
|
||||||
|
// AND completed = 1
|
||||||
|
// ORDER BY created_at ASC
|
||||||
|
GetCompletedTasks(ctx context.Context, arg GetCompletedTasksParams) ([]TaskCompletion, error)
|
||||||
//GetDAGNodeBySnapshotAndNodeID
|
//GetDAGNodeBySnapshotAndNodeID
|
||||||
//
|
//
|
||||||
// SELECT id,
|
// SELECT id,
|
||||||
|
|
@ -423,6 +504,20 @@ type Querier interface {
|
||||||
// AND name = ?2
|
// AND name = ?2
|
||||||
// LIMIT 1
|
// LIMIT 1
|
||||||
GetDocument(ctx context.Context, arg GetDocumentParams) (AgentDocument, error)
|
GetDocument(ctx context.Context, arg GetDocumentParams) (AgentDocument, error)
|
||||||
|
//GetImmutableMessage
|
||||||
|
//
|
||||||
|
// SELECT id,
|
||||||
|
// session_key,
|
||||||
|
// role,
|
||||||
|
// content,
|
||||||
|
// tool_call_id,
|
||||||
|
// tool_calls,
|
||||||
|
// token_estimate,
|
||||||
|
// created_at
|
||||||
|
// FROM immutable_messages
|
||||||
|
// WHERE id = ?1
|
||||||
|
// LIMIT 1
|
||||||
|
GetImmutableMessage(ctx context.Context, arg GetImmutableMessageParams) (ImmutableMessage, error)
|
||||||
//GetJob
|
//GetJob
|
||||||
//
|
//
|
||||||
// SELECT id, kind, status, run_at, attempts, max_attempts, locked_at, locked_by, payload_json, dedupe_key, last_error, created_at, updated_at, completed_at
|
// SELECT id, kind, status, run_at, attempts, max_attempts, locked_at, locked_by, payload_json, dedupe_key, last_error, created_at, updated_at, completed_at
|
||||||
|
|
@ -507,6 +602,30 @@ type Querier interface {
|
||||||
// AND idempotency_key = ?4
|
// AND idempotency_key = ?4
|
||||||
// LIMIT 1
|
// LIMIT 1
|
||||||
GetMapRunByIdempotencyKey(ctx context.Context, arg GetMapRunByIdempotencyKeyParams) (MapRun, error)
|
GetMapRunByIdempotencyKey(ctx context.Context, arg GetMapRunByIdempotencyKeyParams) (MapRun, error)
|
||||||
|
// Get memories ordered by their task retrieval count (for RL analysis)
|
||||||
|
//
|
||||||
|
// SELECT id,
|
||||||
|
// agent_id,
|
||||||
|
// session_key,
|
||||||
|
// role,
|
||||||
|
// sector,
|
||||||
|
// importance,
|
||||||
|
// salience,
|
||||||
|
// decay_rate,
|
||||||
|
// content,
|
||||||
|
// tags,
|
||||||
|
// rl_weight,
|
||||||
|
// rl_credit,
|
||||||
|
// self_report_score,
|
||||||
|
// task_retrieval_count,
|
||||||
|
// created_at,
|
||||||
|
// updated_at
|
||||||
|
// FROM recall_items
|
||||||
|
// WHERE agent_id = ?1
|
||||||
|
// AND suppressed_at IS NULL
|
||||||
|
// ORDER BY task_retrieval_count DESC
|
||||||
|
// LIMIT ?2
|
||||||
|
GetMemoriesByRetrievalCount(ctx context.Context, arg GetMemoriesByRetrievalCountParams) ([]GetMemoriesByRetrievalCountRow, error)
|
||||||
//GetRecallItem
|
//GetRecallItem
|
||||||
//
|
//
|
||||||
// SELECT id,
|
// SELECT id,
|
||||||
|
|
@ -524,8 +643,9 @@ type Querier interface {
|
||||||
// FROM recall_items
|
// FROM recall_items
|
||||||
// WHERE id = ?1
|
// WHERE id = ?1
|
||||||
// AND agent_id = ?2
|
// AND agent_id = ?2
|
||||||
|
// AND suppressed_at IS NULL
|
||||||
// LIMIT 1
|
// LIMIT 1
|
||||||
GetRecallItem(ctx context.Context, arg GetRecallItemParams) (RecallItem, error)
|
GetRecallItem(ctx context.Context, arg GetRecallItemParams) (GetRecallItemRow, error)
|
||||||
//GetRecallItemsByIDs
|
//GetRecallItemsByIDs
|
||||||
//
|
//
|
||||||
// SELECT id,
|
// SELECT id,
|
||||||
|
|
@ -543,7 +663,35 @@ type Querier interface {
|
||||||
// FROM recall_items
|
// FROM recall_items
|
||||||
// WHERE id IN (/*SLICE:ids*/?)
|
// WHERE id IN (/*SLICE:ids*/?)
|
||||||
// AND agent_id = ?2
|
// AND agent_id = ?2
|
||||||
GetRecallItemsByIDs(ctx context.Context, arg GetRecallItemsByIDsParams) ([]RecallItem, error)
|
// AND suppressed_at IS NULL
|
||||||
|
GetRecallItemsByIDs(ctx context.Context, arg GetRecallItemsByIDsParams) ([]GetRecallItemsByIDsRow, error)
|
||||||
|
// Get memories retrieved during a specific task with their self-report scores
|
||||||
|
//
|
||||||
|
// SELECT tr.memory_id,
|
||||||
|
// tr.similarity,
|
||||||
|
// ri.self_report_score
|
||||||
|
// FROM task_retrievals tr
|
||||||
|
// JOIN recall_items ri ON tr.memory_id = ri.id
|
||||||
|
// WHERE tr.task_id = ?1
|
||||||
|
GetRetrievedMemories(ctx context.Context, arg GetRetrievedMemoriesParams) ([]GetRetrievedMemoriesRow, error)
|
||||||
|
// RL (Reinforcement Learning) queries for Memelord integration
|
||||||
|
// Task baseline queries for per-agent performance statistics
|
||||||
|
// Get the baseline statistics for an agent
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// SELECT agent_id,
|
||||||
|
// count,
|
||||||
|
// mean_tokens,
|
||||||
|
// mean_errors,
|
||||||
|
// mean_user_corrections,
|
||||||
|
// m2_tokens,
|
||||||
|
// m2_errors,
|
||||||
|
// m2_user_corrections,
|
||||||
|
// updated_at
|
||||||
|
// FROM task_baselines
|
||||||
|
// WHERE agent_id = ?1
|
||||||
|
// LIMIT 1
|
||||||
|
GetTaskBaseline(ctx context.Context, arg GetTaskBaselineParams) (TaskBaseline, error)
|
||||||
// Working Context queries
|
// Working Context queries
|
||||||
//
|
//
|
||||||
// SELECT agent_id,
|
// SELECT agent_id,
|
||||||
|
|
@ -555,6 +703,30 @@ type Querier interface {
|
||||||
// AND session_key = ?2
|
// AND session_key = ?2
|
||||||
// LIMIT 1
|
// LIMIT 1
|
||||||
GetWorkingContext(ctx context.Context, arg GetWorkingContextParams) (WorkingContext, error)
|
GetWorkingContext(ctx context.Context, arg GetWorkingContextParams) (WorkingContext, error)
|
||||||
|
// Permanently deletes archival chunks for a recall item.
|
||||||
|
//
|
||||||
|
// DELETE FROM archival_chunks
|
||||||
|
// WHERE recall_id = ?1
|
||||||
|
HardDeleteArchivalChunks(ctx context.Context, arg HardDeleteArchivalChunksParams) error
|
||||||
|
// Permanently deletes a single archival chunk by ID.
|
||||||
|
//
|
||||||
|
// DELETE FROM archival_chunks
|
||||||
|
// WHERE id = ?1
|
||||||
|
HardDeleteChunk(ctx context.Context, arg HardDeleteChunkParams) error
|
||||||
|
// Permanently deletes a recall item (after quarantine period).
|
||||||
|
//
|
||||||
|
// DELETE FROM recall_items
|
||||||
|
// WHERE id = ?1
|
||||||
|
// AND agent_id = ?2
|
||||||
|
HardDeleteRecallItem(ctx context.Context, arg HardDeleteRecallItemParams) error
|
||||||
|
// Increment the task retrieval counter for a memory item
|
||||||
|
//
|
||||||
|
// UPDATE recall_items
|
||||||
|
// SET task_retrieval_count = task_retrieval_count + 1,
|
||||||
|
// updated_at = datetime('now')
|
||||||
|
// WHERE id = ?1
|
||||||
|
// AND agent_id = ?2
|
||||||
|
IncrementTaskRetrievalCount(ctx context.Context, arg IncrementTaskRetrievalCountParams) error
|
||||||
// Archival Chunk queries
|
// Archival Chunk queries
|
||||||
//
|
//
|
||||||
// INSERT INTO archival_chunks (
|
// INSERT INTO archival_chunks (
|
||||||
|
|
@ -578,7 +750,7 @@ type Querier interface {
|
||||||
// datetime('now')
|
// datetime('now')
|
||||||
// )
|
// )
|
||||||
// RETURNING id, recall_id, chunk_index, content, embedding, source, hash, created_at
|
// RETURNING id, recall_id, chunk_index, content, embedding, source, hash, created_at
|
||||||
InsertArchivalChunk(ctx context.Context, arg InsertArchivalChunkParams) (ArchivalChunk, error)
|
InsertArchivalChunk(ctx context.Context, arg InsertArchivalChunkParams) (InsertArchivalChunkRow, error)
|
||||||
// Agent Audit Log queries
|
// Agent Audit Log queries
|
||||||
//
|
//
|
||||||
// INSERT INTO agent_audit_log (
|
// INSERT INTO agent_audit_log (
|
||||||
|
|
@ -702,6 +874,35 @@ type Querier interface {
|
||||||
// created_at,
|
// created_at,
|
||||||
// updated_at
|
// updated_at
|
||||||
InsertDAGSnapshot(ctx context.Context, arg InsertDAGSnapshotParams) (DagSnapshot, error)
|
InsertDAGSnapshot(ctx context.Context, arg InsertDAGSnapshotParams) (DagSnapshot, error)
|
||||||
|
// Immutable Messages queries (LCM ADR-001: append-only verbatim message store)
|
||||||
|
//
|
||||||
|
// INSERT INTO immutable_messages (
|
||||||
|
// id,
|
||||||
|
// session_key,
|
||||||
|
// role,
|
||||||
|
// content,
|
||||||
|
// tool_call_id,
|
||||||
|
// tool_calls,
|
||||||
|
// token_estimate
|
||||||
|
// )
|
||||||
|
// VALUES (
|
||||||
|
// ?1,
|
||||||
|
// ?2,
|
||||||
|
// ?3,
|
||||||
|
// ?4,
|
||||||
|
// ?5,
|
||||||
|
// ?6,
|
||||||
|
// ?7
|
||||||
|
// )
|
||||||
|
// RETURNING id,
|
||||||
|
// session_key,
|
||||||
|
// role,
|
||||||
|
// content,
|
||||||
|
// tool_call_id,
|
||||||
|
// tool_calls,
|
||||||
|
// token_estimate,
|
||||||
|
// created_at
|
||||||
|
InsertImmutableMessage(ctx context.Context, arg InsertImmutableMessageParams) (ImmutableMessage, error)
|
||||||
//InsertMapItem
|
//InsertMapItem
|
||||||
//
|
//
|
||||||
// INSERT INTO map_items (
|
// INSERT INTO map_items (
|
||||||
|
|
@ -764,6 +965,22 @@ type Querier interface {
|
||||||
// )
|
// )
|
||||||
// RETURNING id, agent_id, session_key, operator_kind, idempotency_key, status, total_items, queued_items, running_items, succeeded_items, failed_items, spec_fb, last_error, created_at, updated_at, completed_at
|
// RETURNING id, agent_id, session_key, operator_kind, idempotency_key, status, total_items, queued_items, running_items, succeeded_items, failed_items, spec_fb, last_error, created_at, updated_at, completed_at
|
||||||
InsertMapRun(ctx context.Context, arg InsertMapRunParams) (MapRun, error)
|
InsertMapRun(ctx context.Context, arg InsertMapRunParams) (MapRun, error)
|
||||||
|
// Memory Graph Edges queries (ADR-004: typed relational memory)
|
||||||
|
//
|
||||||
|
// INSERT INTO memory_edges (from_id, to_id, edge_type, weight)
|
||||||
|
// VALUES (
|
||||||
|
// ?1,
|
||||||
|
// ?2,
|
||||||
|
// ?3,
|
||||||
|
// ?4
|
||||||
|
// )
|
||||||
|
// RETURNING id,
|
||||||
|
// from_id,
|
||||||
|
// to_id,
|
||||||
|
// edge_type,
|
||||||
|
// weight,
|
||||||
|
// created_at
|
||||||
|
InsertMemoryEdge(ctx context.Context, arg InsertMemoryEdgeParams) (MemoryEdge, error)
|
||||||
// Recall Item queries
|
// Recall Item queries
|
||||||
//
|
//
|
||||||
// INSERT INTO recall_items (
|
// INSERT INTO recall_items (
|
||||||
|
|
@ -777,6 +994,7 @@ type Querier interface {
|
||||||
// decay_rate,
|
// decay_rate,
|
||||||
// content,
|
// content,
|
||||||
// tags,
|
// tags,
|
||||||
|
// rl_weight,
|
||||||
// created_at,
|
// created_at,
|
||||||
// updated_at
|
// updated_at
|
||||||
// )
|
// )
|
||||||
|
|
@ -791,6 +1009,7 @@ type Querier interface {
|
||||||
// ?8,
|
// ?8,
|
||||||
// ?9,
|
// ?9,
|
||||||
// ?10,
|
// ?10,
|
||||||
|
// ?11,
|
||||||
// datetime('now'),
|
// datetime('now'),
|
||||||
// datetime('now')
|
// datetime('now')
|
||||||
// )
|
// )
|
||||||
|
|
@ -804,9 +1023,10 @@ type Querier interface {
|
||||||
// decay_rate,
|
// decay_rate,
|
||||||
// content,
|
// content,
|
||||||
// tags,
|
// tags,
|
||||||
|
// rl_weight,
|
||||||
// created_at,
|
// created_at,
|
||||||
// updated_at
|
// updated_at
|
||||||
InsertRecallItem(ctx context.Context, arg InsertRecallItemParams) (RecallItem, error)
|
InsertRecallItem(ctx context.Context, arg InsertRecallItemParams) (InsertRecallItemRow, error)
|
||||||
//InsertSessionMessage
|
//InsertSessionMessage
|
||||||
//
|
//
|
||||||
// INSERT INTO recall_items (
|
// INSERT INTO recall_items (
|
||||||
|
|
@ -849,7 +1069,7 @@ type Querier interface {
|
||||||
// tags,
|
// tags,
|
||||||
// created_at,
|
// created_at,
|
||||||
// updated_at
|
// updated_at
|
||||||
InsertSessionMessage(ctx context.Context, arg InsertSessionMessageParams) (RecallItem, error)
|
InsertSessionMessage(ctx context.Context, arg InsertSessionMessageParams) (InsertSessionMessageRow, error)
|
||||||
// Memory Summary queries
|
// Memory Summary queries
|
||||||
//
|
//
|
||||||
// INSERT INTO memory_summaries (
|
// INSERT INTO memory_summaries (
|
||||||
|
|
@ -1012,7 +1232,7 @@ type Querier interface {
|
||||||
// WHERE ri.agent_id = ?1
|
// WHERE ri.agent_id = ?1
|
||||||
// ORDER BY ac.created_at DESC
|
// ORDER BY ac.created_at DESC
|
||||||
// LIMIT ?3 OFFSET ?2
|
// LIMIT ?3 OFFSET ?2
|
||||||
ListAllArchivalChunks(ctx context.Context, arg ListAllArchivalChunksParams) ([]ArchivalChunk, error)
|
ListAllArchivalChunks(ctx context.Context, arg ListAllArchivalChunksParams) ([]ListAllArchivalChunksRow, error)
|
||||||
//ListAllDocuments
|
//ListAllDocuments
|
||||||
//
|
//
|
||||||
// SELECT id,
|
// SELECT id,
|
||||||
|
|
@ -1047,7 +1267,22 @@ type Querier interface {
|
||||||
// AND ri.agent_id = ?2
|
// AND ri.agent_id = ?2
|
||||||
// ORDER BY ac.chunk_index
|
// ORDER BY ac.chunk_index
|
||||||
// LIMIT ?3
|
// LIMIT ?3
|
||||||
ListArchivalChunks(ctx context.Context, arg ListArchivalChunksParams) ([]ArchivalChunk, error)
|
ListArchivalChunks(ctx context.Context, arg ListArchivalChunksParams) ([]ListArchivalChunksRow, error)
|
||||||
|
//ListArchivalChunksWithoutEmbedding
|
||||||
|
//
|
||||||
|
// SELECT id,
|
||||||
|
// recall_id,
|
||||||
|
// chunk_index,
|
||||||
|
// content,
|
||||||
|
// embedding,
|
||||||
|
// source,
|
||||||
|
// hash,
|
||||||
|
// created_at
|
||||||
|
// FROM archival_chunks
|
||||||
|
// WHERE embedding IS NULL
|
||||||
|
// AND suppressed_at IS NULL
|
||||||
|
// LIMIT ?1
|
||||||
|
ListArchivalChunksWithoutEmbedding(ctx context.Context, arg ListArchivalChunksWithoutEmbeddingParams) ([]ListArchivalChunksWithoutEmbeddingRow, error)
|
||||||
//ListAuditEntries
|
//ListAuditEntries
|
||||||
//
|
//
|
||||||
// SELECT id,
|
// SELECT id,
|
||||||
|
|
@ -1151,6 +1386,49 @@ type Querier interface {
|
||||||
// ORDER BY name
|
// ORDER BY name
|
||||||
// LIMIT ?3
|
// LIMIT ?3
|
||||||
ListDocumentsByCategory(ctx context.Context, arg ListDocumentsByCategoryParams) ([]AgentDocument, error)
|
ListDocumentsByCategory(ctx context.Context, arg ListDocumentsByCategoryParams) ([]AgentDocument, error)
|
||||||
|
// List memories with high RL weights (credits) for priority retention
|
||||||
|
//
|
||||||
|
// SELECT id,
|
||||||
|
// agent_id,
|
||||||
|
// session_key,
|
||||||
|
// role,
|
||||||
|
// sector,
|
||||||
|
// importance,
|
||||||
|
// salience,
|
||||||
|
// decay_rate,
|
||||||
|
// content,
|
||||||
|
// tags,
|
||||||
|
// rl_weight,
|
||||||
|
// rl_credit,
|
||||||
|
// self_report_score,
|
||||||
|
// task_retrieval_count,
|
||||||
|
// created_at,
|
||||||
|
// updated_at
|
||||||
|
// FROM recall_items
|
||||||
|
// WHERE agent_id = ?1
|
||||||
|
// AND suppressed_at IS NULL
|
||||||
|
// AND (
|
||||||
|
// rl_credit > ?2
|
||||||
|
// OR rl_weight > ?3
|
||||||
|
// )
|
||||||
|
// ORDER BY rl_credit DESC NULLS LAST
|
||||||
|
// LIMIT ?4
|
||||||
|
ListHighValueMemories(ctx context.Context, arg ListHighValueMemoriesParams) ([]ListHighValueMemoriesRow, error)
|
||||||
|
//ListImmutableMessages
|
||||||
|
//
|
||||||
|
// SELECT id,
|
||||||
|
// session_key,
|
||||||
|
// role,
|
||||||
|
// content,
|
||||||
|
// tool_call_id,
|
||||||
|
// tool_calls,
|
||||||
|
// token_estimate,
|
||||||
|
// created_at
|
||||||
|
// FROM immutable_messages
|
||||||
|
// WHERE session_key = ?1
|
||||||
|
// ORDER BY created_at ASC
|
||||||
|
// LIMIT ?3 OFFSET ?2
|
||||||
|
ListImmutableMessages(ctx context.Context, arg ListImmutableMessagesParams) ([]ImmutableMessage, error)
|
||||||
//ListJobs
|
//ListJobs
|
||||||
//
|
//
|
||||||
// SELECT id, kind, status, run_at, attempts, max_attempts, locked_at, locked_by, payload_json, dedupe_key, last_error, created_at, updated_at, completed_at
|
// SELECT id, kind, status, run_at, attempts, max_attempts, locked_at, locked_by, payload_json, dedupe_key, last_error, created_at, updated_at, completed_at
|
||||||
|
|
@ -1187,6 +1465,73 @@ type Querier interface {
|
||||||
// ORDER BY created_at DESC
|
// ORDER BY created_at DESC
|
||||||
// LIMIT ?4 OFFSET ?3
|
// LIMIT ?4 OFFSET ?3
|
||||||
ListMapRunsBySession(ctx context.Context, arg ListMapRunsBySessionParams) ([]MapRun, error)
|
ListMapRunsBySession(ctx context.Context, arg ListMapRunsBySessionParams) ([]MapRun, error)
|
||||||
|
//ListMemoryEdgesByType
|
||||||
|
//
|
||||||
|
// SELECT id,
|
||||||
|
// from_id,
|
||||||
|
// to_id,
|
||||||
|
// edge_type,
|
||||||
|
// weight,
|
||||||
|
// created_at
|
||||||
|
// FROM memory_edges
|
||||||
|
// WHERE edge_type = ?1
|
||||||
|
// ORDER BY created_at DESC
|
||||||
|
// LIMIT ?2
|
||||||
|
ListMemoryEdgesByType(ctx context.Context, arg ListMemoryEdgesByTypeParams) ([]MemoryEdge, error)
|
||||||
|
//ListMemoryEdgesForItem
|
||||||
|
//
|
||||||
|
// SELECT id,
|
||||||
|
// from_id,
|
||||||
|
// to_id,
|
||||||
|
// edge_type,
|
||||||
|
// weight,
|
||||||
|
// created_at
|
||||||
|
// FROM memory_edges
|
||||||
|
// WHERE from_id = ?1
|
||||||
|
// OR to_id = ?1
|
||||||
|
// ORDER BY created_at DESC
|
||||||
|
// LIMIT ?2
|
||||||
|
ListMemoryEdgesForItem(ctx context.Context, arg ListMemoryEdgesForItemParams) ([]MemoryEdge, error)
|
||||||
|
// Returns archival chunks that have been soft-deleted and are
|
||||||
|
// eligible for permanent deletion.
|
||||||
|
//
|
||||||
|
// SELECT id,
|
||||||
|
// recall_id,
|
||||||
|
// chunk_index,
|
||||||
|
// content,
|
||||||
|
// embedding,
|
||||||
|
// source,
|
||||||
|
// hash,
|
||||||
|
// created_at,
|
||||||
|
// suppressed_at
|
||||||
|
// FROM archival_chunks
|
||||||
|
// WHERE suppressed_at IS NOT NULL
|
||||||
|
// AND suppressed_at < ?1
|
||||||
|
// ORDER BY suppressed_at ASC
|
||||||
|
// LIMIT ?2
|
||||||
|
ListQuarantinedArchivalChunks(ctx context.Context, arg ListQuarantinedArchivalChunksParams) ([]ArchivalChunk, error)
|
||||||
|
// Returns recall items that have been soft-deleted (suppressed) and are
|
||||||
|
// eligible for permanent deletion (older than quarantine period).
|
||||||
|
//
|
||||||
|
// SELECT id,
|
||||||
|
// agent_id,
|
||||||
|
// session_key,
|
||||||
|
// role,
|
||||||
|
// sector,
|
||||||
|
// importance,
|
||||||
|
// salience,
|
||||||
|
// decay_rate,
|
||||||
|
// content,
|
||||||
|
// tags,
|
||||||
|
// created_at,
|
||||||
|
// updated_at,
|
||||||
|
// suppressed_at
|
||||||
|
// FROM recall_items
|
||||||
|
// WHERE suppressed_at IS NOT NULL
|
||||||
|
// AND suppressed_at < ?1
|
||||||
|
// ORDER BY suppressed_at ASC
|
||||||
|
// LIMIT ?2
|
||||||
|
ListQuarantinedRecallItems(ctx context.Context, arg ListQuarantinedRecallItemsParams) ([]ListQuarantinedRecallItemsRow, error)
|
||||||
//ListRecallItems
|
//ListRecallItems
|
||||||
//
|
//
|
||||||
// SELECT id,
|
// SELECT id,
|
||||||
|
|
@ -1203,13 +1548,43 @@ type Querier interface {
|
||||||
// updated_at
|
// updated_at
|
||||||
// FROM recall_items
|
// FROM recall_items
|
||||||
// WHERE agent_id = ?1
|
// WHERE agent_id = ?1
|
||||||
|
// AND suppressed_at IS NULL
|
||||||
// AND (
|
// AND (
|
||||||
// session_key = ?2
|
// session_key = ?2
|
||||||
// OR ?2 = ''
|
// OR ?2 = ''
|
||||||
// )
|
// )
|
||||||
// ORDER BY created_at DESC
|
// ORDER BY created_at DESC
|
||||||
// LIMIT ?4 OFFSET ?3
|
// LIMIT ?4 OFFSET ?3
|
||||||
ListRecallItems(ctx context.Context, arg ListRecallItemsParams) ([]RecallItem, error)
|
ListRecallItems(ctx context.Context, arg ListRecallItemsParams) ([]ListRecallItemsRow, error)
|
||||||
|
// Consolidation queries for memory graph maintenance (ADR-004)
|
||||||
|
// Returns recall items created after the cutoff time, joined with their first
|
||||||
|
// archival chunk's embedding for similarity comparison.
|
||||||
|
//
|
||||||
|
// SELECT ri.id,
|
||||||
|
// ri.agent_id,
|
||||||
|
// ri.session_key,
|
||||||
|
// ri.role,
|
||||||
|
// ri.sector,
|
||||||
|
// ri.importance,
|
||||||
|
// ri.salience,
|
||||||
|
// ri.decay_rate,
|
||||||
|
// ri.content,
|
||||||
|
// ri.tags,
|
||||||
|
// ri.created_at,
|
||||||
|
// ri.updated_at,
|
||||||
|
// ac.embedding as embedding
|
||||||
|
// FROM recall_items ri
|
||||||
|
// LEFT JOIN archival_chunks ac ON ac.recall_id = ri.id
|
||||||
|
// AND ac.chunk_index = 0
|
||||||
|
// WHERE ri.created_at > ?1
|
||||||
|
// AND ri.suppressed_at IS NULL
|
||||||
|
// AND (
|
||||||
|
// ?2 = ''
|
||||||
|
// OR ri.agent_id = ?2
|
||||||
|
// )
|
||||||
|
// ORDER BY ri.created_at DESC
|
||||||
|
// LIMIT ?3
|
||||||
|
ListRecallItemsForConsolidation(ctx context.Context, arg ListRecallItemsForConsolidationParams) ([]ListRecallItemsForConsolidationRow, error)
|
||||||
//ListSessionMessages
|
//ListSessionMessages
|
||||||
//
|
//
|
||||||
// SELECT id,
|
// SELECT id,
|
||||||
|
|
@ -1234,7 +1609,7 @@ type Querier interface {
|
||||||
// )
|
// )
|
||||||
// ORDER BY created_at ASC
|
// ORDER BY created_at ASC
|
||||||
// LIMIT ?4
|
// LIMIT ?4
|
||||||
ListSessionMessages(ctx context.Context, arg ListSessionMessagesParams) ([]RecallItem, error)
|
ListSessionMessages(ctx context.Context, arg ListSessionMessagesParams) ([]ListSessionMessagesRow, error)
|
||||||
//ListSessionMessagesPaged
|
//ListSessionMessagesPaged
|
||||||
//
|
//
|
||||||
// SELECT id,
|
// SELECT id,
|
||||||
|
|
@ -1259,7 +1634,7 @@ type Querier interface {
|
||||||
// )
|
// )
|
||||||
// ORDER BY created_at ASC
|
// ORDER BY created_at ASC
|
||||||
// LIMIT ?5 OFFSET ?4
|
// LIMIT ?5 OFFSET ?4
|
||||||
ListSessionMessagesPaged(ctx context.Context, arg ListSessionMessagesPagedParams) ([]RecallItem, error)
|
ListSessionMessagesPaged(ctx context.Context, arg ListSessionMessagesPagedParams) ([]ListSessionMessagesPagedRow, error)
|
||||||
//ListSummaries
|
//ListSummaries
|
||||||
//
|
//
|
||||||
// SELECT id,
|
// SELECT id,
|
||||||
|
|
@ -1352,6 +1727,13 @@ type Querier interface {
|
||||||
// WHERE id = ?3
|
// WHERE id = ?3
|
||||||
// RETURNING id, kind, status, run_at, attempts, max_attempts, locked_at, locked_by, payload_json, dedupe_key, last_error, created_at, updated_at, completed_at
|
// RETURNING id, kind, status, run_at, attempts, max_attempts, locked_at, locked_by, payload_json, dedupe_key, last_error, created_at, updated_at, completed_at
|
||||||
RequeueJob(ctx context.Context, arg RequeueJobParams) (Job, error)
|
RequeueJob(ctx context.Context, arg RequeueJobParams) (Job, error)
|
||||||
|
// Restores a soft-deleted recall item by clearing suppressed_at.
|
||||||
|
//
|
||||||
|
// UPDATE recall_items
|
||||||
|
// SET suppressed_at = NULL
|
||||||
|
// WHERE id = ?1
|
||||||
|
// AND agent_id = ?2
|
||||||
|
RestoreRecallItem(ctx context.Context, arg RestoreRecallItemParams) error
|
||||||
//SearchRecallByKeyword
|
//SearchRecallByKeyword
|
||||||
//
|
//
|
||||||
// SELECT ri.id,
|
// SELECT ri.id,
|
||||||
|
|
@ -1369,9 +1751,69 @@ type Querier interface {
|
||||||
// FROM recall_items ri
|
// FROM recall_items ri
|
||||||
// WHERE ri.content LIKE '%' || ?1 || '%'
|
// WHERE ri.content LIKE '%' || ?1 || '%'
|
||||||
// AND ri.agent_id = ?2
|
// AND ri.agent_id = ?2
|
||||||
|
// AND ri.suppressed_at IS NULL
|
||||||
// ORDER BY ri.importance DESC
|
// ORDER BY ri.importance DESC
|
||||||
// LIMIT ?3
|
// LIMIT ?3
|
||||||
SearchRecallByKeyword(ctx context.Context, arg SearchRecallByKeywordParams) ([]RecallItem, error)
|
SearchRecallByKeyword(ctx context.Context, arg SearchRecallByKeywordParams) ([]SearchRecallByKeywordRow, error)
|
||||||
|
// Sets suppressed_at for all chunks belonging to a recall item.
|
||||||
|
//
|
||||||
|
// UPDATE archival_chunks
|
||||||
|
// SET suppressed_at = datetime('now')
|
||||||
|
// WHERE recall_id = ?1
|
||||||
|
SoftDeleteArchivalChunks(ctx context.Context, arg SoftDeleteArchivalChunksParams) error
|
||||||
|
// Soft delete queries (T2.4: quarantine before permanent deletion)
|
||||||
|
// Sets suppressed_at for a recall item instead of permanently deleting it.
|
||||||
|
//
|
||||||
|
// UPDATE recall_items
|
||||||
|
// SET suppressed_at = datetime('now')
|
||||||
|
// WHERE id = ?1
|
||||||
|
// AND agent_id = ?2
|
||||||
|
SoftDeleteRecallItem(ctx context.Context, arg SoftDeleteRecallItemParams) error
|
||||||
|
// Store a task completion record for RL analysis
|
||||||
|
//
|
||||||
|
// INSERT INTO task_completions (
|
||||||
|
// id,
|
||||||
|
// agent_id,
|
||||||
|
// conversation_id,
|
||||||
|
// run_id,
|
||||||
|
// description,
|
||||||
|
// tokens_used,
|
||||||
|
// tool_calls,
|
||||||
|
// errors,
|
||||||
|
// user_corrections,
|
||||||
|
// completed
|
||||||
|
// )
|
||||||
|
// VALUES (
|
||||||
|
// ?1,
|
||||||
|
// ?2,
|
||||||
|
// ?3,
|
||||||
|
// ?4,
|
||||||
|
// ?5,
|
||||||
|
// ?6,
|
||||||
|
// ?7,
|
||||||
|
// ?8,
|
||||||
|
// ?9,
|
||||||
|
// ?10
|
||||||
|
// )
|
||||||
|
// RETURNING id,
|
||||||
|
// agent_id,
|
||||||
|
// conversation_id,
|
||||||
|
// run_id,
|
||||||
|
// description,
|
||||||
|
// tokens_used,
|
||||||
|
// tool_calls,
|
||||||
|
// errors,
|
||||||
|
// user_corrections,
|
||||||
|
// completed,
|
||||||
|
// created_at
|
||||||
|
StoreTaskCompletion(ctx context.Context, arg StoreTaskCompletionParams) (TaskCompletion, error)
|
||||||
|
// Store a memory retrieval record for a task
|
||||||
|
//
|
||||||
|
// INSERT INTO task_retrievals (id, task_id, memory_id, similarity)
|
||||||
|
// VALUES (?1, ?2, ?3, ?4)
|
||||||
|
// ON CONFLICT (task_id, memory_id) DO UPDATE SET
|
||||||
|
// similarity = excluded.similarity
|
||||||
|
StoreTaskRetrieval(ctx context.Context, arg StoreTaskRetrievalParams) error
|
||||||
//UpdateAgentConversationTitle
|
//UpdateAgentConversationTitle
|
||||||
//
|
//
|
||||||
// UPDATE agent_conversations
|
// UPDATE agent_conversations
|
||||||
|
|
@ -1396,6 +1838,12 @@ type Querier interface {
|
||||||
// WHERE id = ?
|
// WHERE id = ?
|
||||||
// RETURNING id, conversation_id, status, metadata_json, created_at, updated_at
|
// RETURNING id, conversation_id, status, metadata_json, created_at, updated_at
|
||||||
UpdateAgentRunStatus(ctx context.Context, arg UpdateAgentRunStatusParams) (AgentRun, error)
|
UpdateAgentRunStatus(ctx context.Context, arg UpdateAgentRunStatusParams) (AgentRun, error)
|
||||||
|
//UpdateArchivalChunkEmbedding
|
||||||
|
//
|
||||||
|
// UPDATE archival_chunks
|
||||||
|
// SET embedding = ?1
|
||||||
|
// WHERE id = ?2
|
||||||
|
UpdateArchivalChunkEmbedding(ctx context.Context, arg UpdateArchivalChunkEmbeddingParams) error
|
||||||
//UpdateMapRunProgress
|
//UpdateMapRunProgress
|
||||||
//
|
//
|
||||||
// UPDATE map_runs
|
// UPDATE map_runs
|
||||||
|
|
@ -1410,6 +1858,23 @@ type Querier interface {
|
||||||
// WHERE id = ?8
|
// WHERE id = ?8
|
||||||
// RETURNING id, agent_id, session_key, operator_kind, idempotency_key, status, total_items, queued_items, running_items, succeeded_items, failed_items, spec_fb, last_error, created_at, updated_at, completed_at
|
// RETURNING id, agent_id, session_key, operator_kind, idempotency_key, status, total_items, queued_items, running_items, succeeded_items, failed_items, spec_fb, last_error, created_at, updated_at, completed_at
|
||||||
UpdateMapRunProgress(ctx context.Context, arg UpdateMapRunProgressParams) (MapRun, error)
|
UpdateMapRunProgress(ctx context.Context, arg UpdateMapRunProgressParams) (MapRun, error)
|
||||||
|
// Update the self-reported score for a memory item
|
||||||
|
//
|
||||||
|
// UPDATE recall_items
|
||||||
|
// SET self_report_score = ?1,
|
||||||
|
// updated_at = datetime('now')
|
||||||
|
// WHERE id = ?2
|
||||||
|
// AND agent_id = ?3
|
||||||
|
UpdateMemorySelfReportScore(ctx context.Context, arg UpdateMemorySelfReportScoreParams) error
|
||||||
|
// Update the RL weight and credit for a specific memory item
|
||||||
|
//
|
||||||
|
// UPDATE recall_items
|
||||||
|
// SET rl_weight = ?1,
|
||||||
|
// rl_credit = ?2,
|
||||||
|
// updated_at = datetime('now')
|
||||||
|
// WHERE id = ?3
|
||||||
|
// AND agent_id = ?4
|
||||||
|
UpdateMemoryWeight(ctx context.Context, arg UpdateMemoryWeightParams) error
|
||||||
//UpdateRecallItem
|
//UpdateRecallItem
|
||||||
//
|
//
|
||||||
// UPDATE recall_items
|
// UPDATE recall_items
|
||||||
|
|
@ -1424,6 +1889,41 @@ type Querier interface {
|
||||||
// WHERE id = ?8
|
// WHERE id = ?8
|
||||||
// AND agent_id = ?9
|
// AND agent_id = ?9
|
||||||
UpdateRecallItem(ctx context.Context, arg UpdateRecallItemParams) error
|
UpdateRecallItem(ctx context.Context, arg UpdateRecallItemParams) error
|
||||||
|
// Insert or replace task baseline statistics for an agent
|
||||||
|
//
|
||||||
|
// INSERT INTO task_baselines (
|
||||||
|
// agent_id,
|
||||||
|
// count,
|
||||||
|
// mean_tokens,
|
||||||
|
// mean_errors,
|
||||||
|
// mean_user_corrections,
|
||||||
|
// m2_tokens,
|
||||||
|
// m2_errors,
|
||||||
|
// m2_user_corrections,
|
||||||
|
// updated_at
|
||||||
|
// )
|
||||||
|
// VALUES (
|
||||||
|
// ?1,
|
||||||
|
// ?2,
|
||||||
|
// ?3,
|
||||||
|
// ?4,
|
||||||
|
// ?5,
|
||||||
|
// ?6,
|
||||||
|
// ?7,
|
||||||
|
// ?8,
|
||||||
|
// datetime('now')
|
||||||
|
// )
|
||||||
|
// ON CONFLICT (agent_id) DO
|
||||||
|
// UPDATE
|
||||||
|
// SET count = excluded.count,
|
||||||
|
// mean_tokens = excluded.mean_tokens,
|
||||||
|
// mean_errors = excluded.mean_errors,
|
||||||
|
// mean_user_corrections = excluded.mean_user_corrections,
|
||||||
|
// m2_tokens = excluded.m2_tokens,
|
||||||
|
// m2_errors = excluded.m2_errors,
|
||||||
|
// m2_user_corrections = excluded.m2_user_corrections,
|
||||||
|
// updated_at = excluded.updated_at
|
||||||
|
UpdateTaskBaseline(ctx context.Context, arg UpdateTaskBaselineParams) error
|
||||||
//UpsertDocument
|
//UpsertDocument
|
||||||
//
|
//
|
||||||
// INSERT INTO agent_documents (
|
// INSERT INTO agent_documents (
|
||||||
|
|
|
||||||
45
pkg/memory/sqlc/queries/consolidation.sql
Normal file
45
pkg/memory/sqlc/queries/consolidation.sql
Normal file
|
|
@ -0,0 +1,45 @@
|
||||||
|
-- Consolidation queries for memory graph maintenance (ADR-004)
|
||||||
|
-- name: ListRecallItemsForConsolidation :many
|
||||||
|
-- Returns recall items created after the cutoff time, joined with their first
|
||||||
|
-- archival chunk's embedding for similarity comparison.
|
||||||
|
SELECT ri.id,
|
||||||
|
ri.agent_id,
|
||||||
|
ri.session_key,
|
||||||
|
ri.role,
|
||||||
|
ri.sector,
|
||||||
|
ri.importance,
|
||||||
|
ri.salience,
|
||||||
|
ri.decay_rate,
|
||||||
|
ri.content,
|
||||||
|
ri.tags,
|
||||||
|
ri.created_at,
|
||||||
|
ri.updated_at,
|
||||||
|
ac.embedding as embedding
|
||||||
|
FROM recall_items ri
|
||||||
|
LEFT JOIN archival_chunks ac ON ac.recall_id = ri.id
|
||||||
|
AND ac.chunk_index = 0
|
||||||
|
WHERE ri.created_at > sqlc.arg(cutoff)
|
||||||
|
AND ri.suppressed_at IS NULL
|
||||||
|
AND (
|
||||||
|
sqlc.arg(agent_id) = ''
|
||||||
|
OR ri.agent_id = sqlc.arg(agent_id)
|
||||||
|
)
|
||||||
|
ORDER BY ri.created_at DESC
|
||||||
|
LIMIT sqlc.arg(lim);
|
||||||
|
-- name: FindSimilarRecallItems :many
|
||||||
|
-- Finds recall items with high cosine similarity to the given embedding.
|
||||||
|
-- Uses libSQL's built-in vector similarity if available, otherwise returns
|
||||||
|
-- candidates for manual comparison.
|
||||||
|
SELECT ri.id,
|
||||||
|
ri.agent_id,
|
||||||
|
ri.content,
|
||||||
|
ac.embedding as embedding,
|
||||||
|
vector_distance_cosine(ac.embedding, sqlc.arg(query_embedding)) as distance
|
||||||
|
FROM recall_items ri
|
||||||
|
JOIN archival_chunks ac ON ac.recall_id = ri.id
|
||||||
|
AND ac.chunk_index = 0
|
||||||
|
WHERE ri.agent_id = sqlc.arg(agent_id)
|
||||||
|
AND ri.id != sqlc.arg(exclude_id)
|
||||||
|
AND ac.embedding IS NOT NULL
|
||||||
|
ORDER BY distance ASC
|
||||||
|
LIMIT sqlc.arg(lim);
|
||||||
57
pkg/memory/sqlc/queries/immutable_messages.sql
Normal file
57
pkg/memory/sqlc/queries/immutable_messages.sql
Normal file
|
|
@ -0,0 +1,57 @@
|
||||||
|
-- Immutable Messages queries (LCM ADR-001: append-only verbatim message store)
|
||||||
|
-- name: InsertImmutableMessage :one
|
||||||
|
INSERT INTO immutable_messages (
|
||||||
|
id,
|
||||||
|
session_key,
|
||||||
|
role,
|
||||||
|
content,
|
||||||
|
tool_call_id,
|
||||||
|
tool_calls,
|
||||||
|
token_estimate
|
||||||
|
)
|
||||||
|
VALUES (
|
||||||
|
sqlc.arg(id),
|
||||||
|
sqlc.arg(session_key),
|
||||||
|
sqlc.arg(role),
|
||||||
|
sqlc.arg(content),
|
||||||
|
sqlc.arg(tool_call_id),
|
||||||
|
sqlc.arg(tool_calls),
|
||||||
|
sqlc.arg(token_estimate)
|
||||||
|
)
|
||||||
|
RETURNING id,
|
||||||
|
session_key,
|
||||||
|
role,
|
||||||
|
content,
|
||||||
|
tool_call_id,
|
||||||
|
tool_calls,
|
||||||
|
token_estimate,
|
||||||
|
created_at;
|
||||||
|
-- name: GetImmutableMessage :one
|
||||||
|
SELECT id,
|
||||||
|
session_key,
|
||||||
|
role,
|
||||||
|
content,
|
||||||
|
tool_call_id,
|
||||||
|
tool_calls,
|
||||||
|
token_estimate,
|
||||||
|
created_at
|
||||||
|
FROM immutable_messages
|
||||||
|
WHERE id = sqlc.arg(id)
|
||||||
|
LIMIT 1;
|
||||||
|
-- name: ListImmutableMessages :many
|
||||||
|
SELECT id,
|
||||||
|
session_key,
|
||||||
|
role,
|
||||||
|
content,
|
||||||
|
tool_call_id,
|
||||||
|
tool_calls,
|
||||||
|
token_estimate,
|
||||||
|
created_at
|
||||||
|
FROM immutable_messages
|
||||||
|
WHERE session_key = sqlc.arg(session_key)
|
||||||
|
ORDER BY created_at ASC
|
||||||
|
LIMIT sqlc.arg(lim) OFFSET sqlc.arg(off);
|
||||||
|
-- name: CountImmutableMessages :one
|
||||||
|
SELECT COUNT(*)
|
||||||
|
FROM immutable_messages
|
||||||
|
WHERE session_key = sqlc.arg(session_key);
|
||||||
47
pkg/memory/sqlc/queries/memory_edges.sql
Normal file
47
pkg/memory/sqlc/queries/memory_edges.sql
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
-- Memory Graph Edges queries (ADR-004: typed relational memory)
|
||||||
|
-- name: InsertMemoryEdge :one
|
||||||
|
INSERT INTO memory_edges (from_id, to_id, edge_type, weight)
|
||||||
|
VALUES (
|
||||||
|
sqlc.arg(from_id),
|
||||||
|
sqlc.arg(to_id),
|
||||||
|
sqlc.arg(edge_type),
|
||||||
|
sqlc.arg(weight)
|
||||||
|
)
|
||||||
|
RETURNING id,
|
||||||
|
from_id,
|
||||||
|
to_id,
|
||||||
|
edge_type,
|
||||||
|
weight,
|
||||||
|
created_at;
|
||||||
|
-- name: ListMemoryEdgesForItem :many
|
||||||
|
SELECT id,
|
||||||
|
from_id,
|
||||||
|
to_id,
|
||||||
|
edge_type,
|
||||||
|
weight,
|
||||||
|
created_at
|
||||||
|
FROM memory_edges
|
||||||
|
WHERE from_id = sqlc.arg(memory_id)
|
||||||
|
OR to_id = sqlc.arg(memory_id)
|
||||||
|
ORDER BY created_at DESC
|
||||||
|
LIMIT sqlc.arg(lim);
|
||||||
|
-- name: CountMemoryEdgesForItem :one
|
||||||
|
SELECT COUNT(*)
|
||||||
|
FROM memory_edges
|
||||||
|
WHERE from_id = sqlc.arg(memory_id)
|
||||||
|
OR to_id = sqlc.arg(memory_id);
|
||||||
|
-- name: ListMemoryEdgesByType :many
|
||||||
|
SELECT id,
|
||||||
|
from_id,
|
||||||
|
to_id,
|
||||||
|
edge_type,
|
||||||
|
weight,
|
||||||
|
created_at
|
||||||
|
FROM memory_edges
|
||||||
|
WHERE edge_type = sqlc.arg(edge_type)
|
||||||
|
ORDER BY created_at DESC
|
||||||
|
LIMIT sqlc.arg(lim);
|
||||||
|
-- name: DeleteMemoryEdgesForItem :exec
|
||||||
|
DELETE FROM memory_edges
|
||||||
|
WHERE from_id = sqlc.arg(memory_id)
|
||||||
|
OR to_id = sqlc.arg(memory_id);
|
||||||
|
|
@ -11,6 +11,7 @@ INSERT INTO recall_items (
|
||||||
decay_rate,
|
decay_rate,
|
||||||
content,
|
content,
|
||||||
tags,
|
tags,
|
||||||
|
rl_weight,
|
||||||
created_at,
|
created_at,
|
||||||
updated_at
|
updated_at
|
||||||
)
|
)
|
||||||
|
|
@ -25,6 +26,7 @@ VALUES (
|
||||||
sqlc.arg(decay_rate),
|
sqlc.arg(decay_rate),
|
||||||
sqlc.arg(content),
|
sqlc.arg(content),
|
||||||
sqlc.arg(tags),
|
sqlc.arg(tags),
|
||||||
|
sqlc.arg(rl_weight),
|
||||||
datetime('now'),
|
datetime('now'),
|
||||||
datetime('now')
|
datetime('now')
|
||||||
)
|
)
|
||||||
|
|
@ -38,6 +40,7 @@ RETURNING id,
|
||||||
decay_rate,
|
decay_rate,
|
||||||
content,
|
content,
|
||||||
tags,
|
tags,
|
||||||
|
rl_weight,
|
||||||
created_at,
|
created_at,
|
||||||
updated_at;
|
updated_at;
|
||||||
-- name: GetRecallItem :one
|
-- name: GetRecallItem :one
|
||||||
|
|
@ -56,6 +59,7 @@ SELECT id,
|
||||||
FROM recall_items
|
FROM recall_items
|
||||||
WHERE id = sqlc.arg(id)
|
WHERE id = sqlc.arg(id)
|
||||||
AND agent_id = sqlc.arg(agent_id)
|
AND agent_id = sqlc.arg(agent_id)
|
||||||
|
AND suppressed_at IS NULL
|
||||||
LIMIT 1;
|
LIMIT 1;
|
||||||
-- name: UpdateRecallItem :exec
|
-- name: UpdateRecallItem :exec
|
||||||
UPDATE recall_items
|
UPDATE recall_items
|
||||||
|
|
@ -88,6 +92,7 @@ SELECT id,
|
||||||
updated_at
|
updated_at
|
||||||
FROM recall_items
|
FROM recall_items
|
||||||
WHERE agent_id = sqlc.arg(agent_id)
|
WHERE agent_id = sqlc.arg(agent_id)
|
||||||
|
AND suppressed_at IS NULL
|
||||||
AND (
|
AND (
|
||||||
session_key = sqlc.arg(session_key)
|
session_key = sqlc.arg(session_key)
|
||||||
OR sqlc.arg(session_key) = ''
|
OR sqlc.arg(session_key) = ''
|
||||||
|
|
@ -110,12 +115,14 @@ SELECT ri.id,
|
||||||
FROM recall_items ri
|
FROM recall_items ri
|
||||||
WHERE ri.content LIKE '%' || sqlc.arg(keyword) || '%'
|
WHERE ri.content LIKE '%' || sqlc.arg(keyword) || '%'
|
||||||
AND ri.agent_id = sqlc.arg(agent_id)
|
AND ri.agent_id = sqlc.arg(agent_id)
|
||||||
|
AND ri.suppressed_at IS NULL
|
||||||
ORDER BY ri.importance DESC
|
ORDER BY ri.importance DESC
|
||||||
LIMIT sqlc.arg(lim);
|
LIMIT sqlc.arg(lim);
|
||||||
-- name: CountRecallItems :one
|
-- name: CountRecallItems :one
|
||||||
SELECT COUNT(*)
|
SELECT COUNT(*)
|
||||||
FROM recall_items
|
FROM recall_items
|
||||||
WHERE agent_id = sqlc.arg(agent_id)
|
WHERE agent_id = sqlc.arg(agent_id)
|
||||||
|
AND suppressed_at IS NULL
|
||||||
AND (
|
AND (
|
||||||
session_key = sqlc.arg(session_key)
|
session_key = sqlc.arg(session_key)
|
||||||
OR sqlc.arg(session_key) = ''
|
OR sqlc.arg(session_key) = ''
|
||||||
|
|
@ -135,7 +142,8 @@ SELECT id,
|
||||||
updated_at
|
updated_at
|
||||||
FROM recall_items
|
FROM recall_items
|
||||||
WHERE id IN (sqlc.slice('ids'))
|
WHERE id IN (sqlc.slice('ids'))
|
||||||
AND agent_id = sqlc.arg(agent_id);
|
AND agent_id = sqlc.arg(agent_id)
|
||||||
|
AND suppressed_at IS NULL;
|
||||||
-- name: InsertSessionMessage :one
|
-- name: InsertSessionMessage :one
|
||||||
INSERT INTO recall_items (
|
INSERT INTO recall_items (
|
||||||
id,
|
id,
|
||||||
|
|
|
||||||
38
pkg/memory/sqlc/queries/recall_decay.sql
Normal file
38
pkg/memory/sqlc/queries/recall_decay.sql
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
-- Batch decay of recall item importance (Cortex decay task)
|
||||||
|
-- name: DecayRecallImportanceBatch :exec
|
||||||
|
UPDATE recall_items
|
||||||
|
SET importance = MAX(
|
||||||
|
recall_items.importance * sqlc.arg(factor),
|
||||||
|
sqlc.arg(floor_val)
|
||||||
|
),
|
||||||
|
updated_at = datetime('now')
|
||||||
|
WHERE recall_items.id IN (
|
||||||
|
SELECT ri.id
|
||||||
|
FROM recall_items ri
|
||||||
|
WHERE ri.importance > sqlc.arg(floor_val)
|
||||||
|
AND ri.suppressed_at IS NULL
|
||||||
|
ORDER BY ri.updated_at ASC
|
||||||
|
LIMIT sqlc.arg(batch_size)
|
||||||
|
);
|
||||||
|
-- name: CountArchivalChunksWithoutEmbedding :one
|
||||||
|
SELECT COUNT(*)
|
||||||
|
FROM archival_chunks
|
||||||
|
WHERE embedding IS NULL
|
||||||
|
AND suppressed_at IS NULL;
|
||||||
|
-- name: ListArchivalChunksWithoutEmbedding :many
|
||||||
|
SELECT id,
|
||||||
|
recall_id,
|
||||||
|
chunk_index,
|
||||||
|
content,
|
||||||
|
embedding,
|
||||||
|
source,
|
||||||
|
hash,
|
||||||
|
created_at
|
||||||
|
FROM archival_chunks
|
||||||
|
WHERE embedding IS NULL
|
||||||
|
AND suppressed_at IS NULL
|
||||||
|
LIMIT sqlc.arg(lim);
|
||||||
|
-- name: UpdateArchivalChunkEmbedding :exec
|
||||||
|
UPDATE archival_chunks
|
||||||
|
SET embedding = sqlc.arg(embedding)
|
||||||
|
WHERE id = sqlc.arg(id);
|
||||||
202
pkg/memory/sqlc/queries/rl.sql
Normal file
202
pkg/memory/sqlc/queries/rl.sql
Normal file
|
|
@ -0,0 +1,202 @@
|
||||||
|
-- RL (Reinforcement Learning) queries for Memelord integration
|
||||||
|
-- Task baseline queries for per-agent performance statistics
|
||||||
|
|
||||||
|
-- name: GetTaskBaseline :one
|
||||||
|
-- Get the baseline statistics for an agent
|
||||||
|
SELECT agent_id,
|
||||||
|
count,
|
||||||
|
mean_tokens,
|
||||||
|
mean_errors,
|
||||||
|
mean_user_corrections,
|
||||||
|
m2_tokens,
|
||||||
|
m2_errors,
|
||||||
|
m2_user_corrections,
|
||||||
|
updated_at
|
||||||
|
FROM task_baselines
|
||||||
|
WHERE agent_id = sqlc.arg(agent_id)
|
||||||
|
LIMIT 1;
|
||||||
|
|
||||||
|
-- name: UpdateTaskBaseline :exec
|
||||||
|
-- Insert or replace task baseline statistics for an agent
|
||||||
|
INSERT INTO task_baselines (
|
||||||
|
agent_id,
|
||||||
|
count,
|
||||||
|
mean_tokens,
|
||||||
|
mean_errors,
|
||||||
|
mean_user_corrections,
|
||||||
|
m2_tokens,
|
||||||
|
m2_errors,
|
||||||
|
m2_user_corrections,
|
||||||
|
updated_at
|
||||||
|
)
|
||||||
|
VALUES (
|
||||||
|
sqlc.arg(agent_id),
|
||||||
|
sqlc.arg(count),
|
||||||
|
sqlc.arg(mean_tokens),
|
||||||
|
sqlc.arg(mean_errors),
|
||||||
|
sqlc.arg(mean_user_corrections),
|
||||||
|
sqlc.arg(m2_tokens),
|
||||||
|
sqlc.arg(m2_errors),
|
||||||
|
sqlc.arg(m2_user_corrections),
|
||||||
|
datetime('now')
|
||||||
|
)
|
||||||
|
ON CONFLICT (agent_id) DO
|
||||||
|
UPDATE
|
||||||
|
SET count = excluded.count,
|
||||||
|
mean_tokens = excluded.mean_tokens,
|
||||||
|
mean_errors = excluded.mean_errors,
|
||||||
|
mean_user_corrections = excluded.mean_user_corrections,
|
||||||
|
m2_tokens = excluded.m2_tokens,
|
||||||
|
m2_errors = excluded.m2_errors,
|
||||||
|
m2_user_corrections = excluded.m2_user_corrections,
|
||||||
|
updated_at = excluded.updated_at;
|
||||||
|
|
||||||
|
-- name: UpdateMemoryWeight :exec
|
||||||
|
-- Update the RL weight and credit for a specific memory item
|
||||||
|
UPDATE recall_items
|
||||||
|
SET rl_weight = sqlc.arg(rl_weight),
|
||||||
|
rl_credit = sqlc.arg(rl_credit),
|
||||||
|
updated_at = datetime('now')
|
||||||
|
WHERE id = sqlc.arg(id)
|
||||||
|
AND agent_id = sqlc.arg(agent_id);
|
||||||
|
|
||||||
|
-- name: UpdateMemorySelfReportScore :exec
|
||||||
|
-- Update the self-reported score for a memory item
|
||||||
|
UPDATE recall_items
|
||||||
|
SET self_report_score = sqlc.arg(self_report_score),
|
||||||
|
updated_at = datetime('now')
|
||||||
|
WHERE id = sqlc.arg(id)
|
||||||
|
AND agent_id = sqlc.arg(agent_id);
|
||||||
|
|
||||||
|
-- name: IncrementTaskRetrievalCount :exec
|
||||||
|
-- Increment the task retrieval counter for a memory item
|
||||||
|
UPDATE recall_items
|
||||||
|
SET task_retrieval_count = task_retrieval_count + 1,
|
||||||
|
updated_at = datetime('now')
|
||||||
|
WHERE id = sqlc.arg(id)
|
||||||
|
AND agent_id = sqlc.arg(agent_id);
|
||||||
|
|
||||||
|
-- name: GetMemoriesByRetrievalCount :many
|
||||||
|
-- Get memories ordered by their task retrieval count (for RL analysis)
|
||||||
|
SELECT id,
|
||||||
|
agent_id,
|
||||||
|
session_key,
|
||||||
|
role,
|
||||||
|
sector,
|
||||||
|
importance,
|
||||||
|
salience,
|
||||||
|
decay_rate,
|
||||||
|
content,
|
||||||
|
tags,
|
||||||
|
rl_weight,
|
||||||
|
rl_credit,
|
||||||
|
self_report_score,
|
||||||
|
task_retrieval_count,
|
||||||
|
created_at,
|
||||||
|
updated_at
|
||||||
|
FROM recall_items
|
||||||
|
WHERE agent_id = sqlc.arg(agent_id)
|
||||||
|
AND suppressed_at IS NULL
|
||||||
|
ORDER BY task_retrieval_count DESC
|
||||||
|
LIMIT sqlc.arg(lim);
|
||||||
|
|
||||||
|
-- name: ListHighValueMemories :many
|
||||||
|
-- List memories with high RL weights (credits) for priority retention
|
||||||
|
SELECT id,
|
||||||
|
agent_id,
|
||||||
|
session_key,
|
||||||
|
role,
|
||||||
|
sector,
|
||||||
|
importance,
|
||||||
|
salience,
|
||||||
|
decay_rate,
|
||||||
|
content,
|
||||||
|
tags,
|
||||||
|
rl_weight,
|
||||||
|
rl_credit,
|
||||||
|
self_report_score,
|
||||||
|
task_retrieval_count,
|
||||||
|
created_at,
|
||||||
|
updated_at
|
||||||
|
FROM recall_items
|
||||||
|
WHERE agent_id = sqlc.arg(agent_id)
|
||||||
|
AND suppressed_at IS NULL
|
||||||
|
AND (
|
||||||
|
rl_credit > sqlc.arg(min_credit)
|
||||||
|
OR rl_weight > sqlc.arg(min_weight)
|
||||||
|
)
|
||||||
|
ORDER BY rl_credit DESC NULLS LAST
|
||||||
|
LIMIT sqlc.arg(lim);
|
||||||
|
|
||||||
|
-- name: StoreTaskCompletion :one
|
||||||
|
-- Store a task completion record for RL analysis
|
||||||
|
INSERT INTO task_completions (
|
||||||
|
id,
|
||||||
|
agent_id,
|
||||||
|
conversation_id,
|
||||||
|
run_id,
|
||||||
|
description,
|
||||||
|
tokens_used,
|
||||||
|
tool_calls,
|
||||||
|
errors,
|
||||||
|
user_corrections,
|
||||||
|
completed
|
||||||
|
)
|
||||||
|
VALUES (
|
||||||
|
sqlc.arg(id),
|
||||||
|
sqlc.arg(agent_id),
|
||||||
|
sqlc.arg(conversation_id),
|
||||||
|
sqlc.arg(run_id),
|
||||||
|
sqlc.arg(description),
|
||||||
|
sqlc.arg(tokens_used),
|
||||||
|
sqlc.arg(tool_calls),
|
||||||
|
sqlc.arg(errors),
|
||||||
|
sqlc.arg(user_corrections),
|
||||||
|
sqlc.arg(completed)
|
||||||
|
)
|
||||||
|
RETURNING id,
|
||||||
|
agent_id,
|
||||||
|
conversation_id,
|
||||||
|
run_id,
|
||||||
|
description,
|
||||||
|
tokens_used,
|
||||||
|
tool_calls,
|
||||||
|
errors,
|
||||||
|
user_corrections,
|
||||||
|
completed,
|
||||||
|
created_at;
|
||||||
|
|
||||||
|
-- name: GetCompletedTasks :many
|
||||||
|
-- Get tasks completed since the given time for RL processing
|
||||||
|
SELECT id,
|
||||||
|
agent_id,
|
||||||
|
conversation_id,
|
||||||
|
run_id,
|
||||||
|
description,
|
||||||
|
tokens_used,
|
||||||
|
tool_calls,
|
||||||
|
errors,
|
||||||
|
user_corrections,
|
||||||
|
completed,
|
||||||
|
created_at
|
||||||
|
FROM task_completions
|
||||||
|
WHERE agent_id = sqlc.arg(agent_id)
|
||||||
|
AND created_at > sqlc.arg(since)
|
||||||
|
AND completed = 1
|
||||||
|
ORDER BY created_at ASC;
|
||||||
|
|
||||||
|
-- name: StoreTaskRetrieval :exec
|
||||||
|
-- Store a memory retrieval record for a task
|
||||||
|
INSERT INTO task_retrievals (id, task_id, memory_id, similarity)
|
||||||
|
VALUES (sqlc.arg(id), sqlc.arg(task_id), sqlc.arg(memory_id), sqlc.arg(similarity))
|
||||||
|
ON CONFLICT (task_id, memory_id) DO UPDATE SET
|
||||||
|
similarity = excluded.similarity;
|
||||||
|
|
||||||
|
-- name: GetRetrievedMemories :many
|
||||||
|
-- Get memories retrieved during a specific task with their self-report scores
|
||||||
|
SELECT tr.memory_id,
|
||||||
|
tr.similarity,
|
||||||
|
ri.self_report_score
|
||||||
|
FROM task_retrievals tr
|
||||||
|
JOIN recall_items ri ON tr.memory_id = ri.id
|
||||||
|
WHERE tr.task_id = sqlc.arg(task_id);
|
||||||
69
pkg/memory/sqlc/queries/soft_delete.sql
Normal file
69
pkg/memory/sqlc/queries/soft_delete.sql
Normal file
|
|
@ -0,0 +1,69 @@
|
||||||
|
-- Soft delete queries (T2.4: quarantine before permanent deletion)
|
||||||
|
-- name: SoftDeleteRecallItem :exec
|
||||||
|
-- Sets suppressed_at for a recall item instead of permanently deleting it.
|
||||||
|
UPDATE recall_items
|
||||||
|
SET suppressed_at = datetime('now')
|
||||||
|
WHERE id = sqlc.arg(id)
|
||||||
|
AND agent_id = sqlc.arg(agent_id);
|
||||||
|
-- name: SoftDeleteArchivalChunks :exec
|
||||||
|
-- Sets suppressed_at for all chunks belonging to a recall item.
|
||||||
|
UPDATE archival_chunks
|
||||||
|
SET suppressed_at = datetime('now')
|
||||||
|
WHERE recall_id = sqlc.arg(recall_id);
|
||||||
|
-- name: ListQuarantinedRecallItems :many
|
||||||
|
-- Returns recall items that have been soft-deleted (suppressed) and are
|
||||||
|
-- eligible for permanent deletion (older than quarantine period).
|
||||||
|
SELECT id,
|
||||||
|
agent_id,
|
||||||
|
session_key,
|
||||||
|
role,
|
||||||
|
sector,
|
||||||
|
importance,
|
||||||
|
salience,
|
||||||
|
decay_rate,
|
||||||
|
content,
|
||||||
|
tags,
|
||||||
|
created_at,
|
||||||
|
updated_at,
|
||||||
|
suppressed_at
|
||||||
|
FROM recall_items
|
||||||
|
WHERE suppressed_at IS NOT NULL
|
||||||
|
AND suppressed_at < sqlc.arg(before_date)
|
||||||
|
ORDER BY suppressed_at ASC
|
||||||
|
LIMIT sqlc.arg(lim);
|
||||||
|
-- name: ListQuarantinedArchivalChunks :many
|
||||||
|
-- Returns archival chunks that have been soft-deleted and are
|
||||||
|
-- eligible for permanent deletion.
|
||||||
|
SELECT id,
|
||||||
|
recall_id,
|
||||||
|
chunk_index,
|
||||||
|
content,
|
||||||
|
embedding,
|
||||||
|
source,
|
||||||
|
hash,
|
||||||
|
created_at,
|
||||||
|
suppressed_at
|
||||||
|
FROM archival_chunks
|
||||||
|
WHERE suppressed_at IS NOT NULL
|
||||||
|
AND suppressed_at < sqlc.arg(before_date)
|
||||||
|
ORDER BY suppressed_at ASC
|
||||||
|
LIMIT sqlc.arg(lim);
|
||||||
|
-- name: HardDeleteRecallItem :exec
|
||||||
|
-- Permanently deletes a recall item (after quarantine period).
|
||||||
|
DELETE FROM recall_items
|
||||||
|
WHERE id = sqlc.arg(id)
|
||||||
|
AND agent_id = sqlc.arg(agent_id);
|
||||||
|
-- name: HardDeleteArchivalChunks :exec
|
||||||
|
-- Permanently deletes archival chunks for a recall item.
|
||||||
|
DELETE FROM archival_chunks
|
||||||
|
WHERE recall_id = sqlc.arg(recall_id);
|
||||||
|
-- name: HardDeleteChunk :exec
|
||||||
|
-- Permanently deletes a single archival chunk by ID.
|
||||||
|
DELETE FROM archival_chunks
|
||||||
|
WHERE id = sqlc.arg(id);
|
||||||
|
-- name: RestoreRecallItem :exec
|
||||||
|
-- Restores a soft-deleted recall item by clearing suppressed_at.
|
||||||
|
UPDATE recall_items
|
||||||
|
SET suppressed_at = NULL
|
||||||
|
WHERE id = sqlc.arg(id)
|
||||||
|
AND agent_id = sqlc.arg(agent_id);
|
||||||
|
|
@ -8,6 +8,7 @@ package sqlc
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/ZanzyTHEbar/dragonscale/pkg/ids"
|
"github.com/ZanzyTHEbar/dragonscale/pkg/ids"
|
||||||
"github.com/ZanzyTHEbar/dragonscale/pkg/memory"
|
"github.com/ZanzyTHEbar/dragonscale/pkg/memory"
|
||||||
|
|
@ -17,6 +18,7 @@ const CountRecallItems = `-- name: CountRecallItems :one
|
||||||
SELECT COUNT(*)
|
SELECT COUNT(*)
|
||||||
FROM recall_items
|
FROM recall_items
|
||||||
WHERE agent_id = ?1
|
WHERE agent_id = ?1
|
||||||
|
AND suppressed_at IS NULL
|
||||||
AND (
|
AND (
|
||||||
session_key = ?2
|
session_key = ?2
|
||||||
OR ?2 = ''
|
OR ?2 = ''
|
||||||
|
|
@ -33,6 +35,7 @@ type CountRecallItemsParams struct {
|
||||||
// SELECT COUNT(*)
|
// SELECT COUNT(*)
|
||||||
// FROM recall_items
|
// FROM recall_items
|
||||||
// WHERE agent_id = ?1
|
// WHERE agent_id = ?1
|
||||||
|
// AND suppressed_at IS NULL
|
||||||
// AND (
|
// AND (
|
||||||
// session_key = ?2
|
// session_key = ?2
|
||||||
// OR ?2 = ''
|
// OR ?2 = ''
|
||||||
|
|
@ -108,6 +111,7 @@ SELECT id,
|
||||||
FROM recall_items
|
FROM recall_items
|
||||||
WHERE id = ?1
|
WHERE id = ?1
|
||||||
AND agent_id = ?2
|
AND agent_id = ?2
|
||||||
|
AND suppressed_at IS NULL
|
||||||
LIMIT 1
|
LIMIT 1
|
||||||
`
|
`
|
||||||
|
|
||||||
|
|
@ -116,6 +120,21 @@ type GetRecallItemParams struct {
|
||||||
AgentID string `db:"agent_id" json:"agent_id"`
|
AgentID string `db:"agent_id" json:"agent_id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type GetRecallItemRow struct {
|
||||||
|
ID ids.UUID `db:"id" json:"id"`
|
||||||
|
AgentID string `db:"agent_id" json:"agent_id"`
|
||||||
|
SessionKey string `db:"session_key" json:"session_key"`
|
||||||
|
Role string `db:"role" json:"role"`
|
||||||
|
Sector memory.Sector `db:"sector" json:"sector"`
|
||||||
|
Importance float64 `db:"importance" json:"importance"`
|
||||||
|
Salience float64 `db:"salience" json:"salience"`
|
||||||
|
DecayRate float64 `db:"decay_rate" json:"decay_rate"`
|
||||||
|
Content string `db:"content" json:"content"`
|
||||||
|
Tags string `db:"tags" json:"tags"`
|
||||||
|
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
||||||
|
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
|
||||||
|
}
|
||||||
|
|
||||||
// GetRecallItem
|
// GetRecallItem
|
||||||
//
|
//
|
||||||
// SELECT id,
|
// SELECT id,
|
||||||
|
|
@ -133,10 +152,11 @@ type GetRecallItemParams struct {
|
||||||
// FROM recall_items
|
// FROM recall_items
|
||||||
// WHERE id = ?1
|
// WHERE id = ?1
|
||||||
// AND agent_id = ?2
|
// AND agent_id = ?2
|
||||||
|
// AND suppressed_at IS NULL
|
||||||
// LIMIT 1
|
// LIMIT 1
|
||||||
func (q *Queries) GetRecallItem(ctx context.Context, arg GetRecallItemParams) (RecallItem, error) {
|
func (q *Queries) GetRecallItem(ctx context.Context, arg GetRecallItemParams) (GetRecallItemRow, error) {
|
||||||
row := q.db.QueryRowContext(ctx, GetRecallItem, arg.ID, arg.AgentID)
|
row := q.db.QueryRowContext(ctx, GetRecallItem, arg.ID, arg.AgentID)
|
||||||
var i RecallItem
|
var i GetRecallItemRow
|
||||||
err := row.Scan(
|
err := row.Scan(
|
||||||
&i.ID,
|
&i.ID,
|
||||||
&i.AgentID,
|
&i.AgentID,
|
||||||
|
|
@ -170,6 +190,7 @@ SELECT id,
|
||||||
FROM recall_items
|
FROM recall_items
|
||||||
WHERE id IN (/*SLICE:ids*/?)
|
WHERE id IN (/*SLICE:ids*/?)
|
||||||
AND agent_id = ?2
|
AND agent_id = ?2
|
||||||
|
AND suppressed_at IS NULL
|
||||||
`
|
`
|
||||||
|
|
||||||
type GetRecallItemsByIDsParams struct {
|
type GetRecallItemsByIDsParams struct {
|
||||||
|
|
@ -177,6 +198,21 @@ type GetRecallItemsByIDsParams struct {
|
||||||
AgentID string `db:"agent_id" json:"agent_id"`
|
AgentID string `db:"agent_id" json:"agent_id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type GetRecallItemsByIDsRow struct {
|
||||||
|
ID ids.UUID `db:"id" json:"id"`
|
||||||
|
AgentID string `db:"agent_id" json:"agent_id"`
|
||||||
|
SessionKey string `db:"session_key" json:"session_key"`
|
||||||
|
Role string `db:"role" json:"role"`
|
||||||
|
Sector memory.Sector `db:"sector" json:"sector"`
|
||||||
|
Importance float64 `db:"importance" json:"importance"`
|
||||||
|
Salience float64 `db:"salience" json:"salience"`
|
||||||
|
DecayRate float64 `db:"decay_rate" json:"decay_rate"`
|
||||||
|
Content string `db:"content" json:"content"`
|
||||||
|
Tags string `db:"tags" json:"tags"`
|
||||||
|
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
||||||
|
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
|
||||||
|
}
|
||||||
|
|
||||||
// GetRecallItemsByIDs
|
// GetRecallItemsByIDs
|
||||||
//
|
//
|
||||||
// SELECT id,
|
// SELECT id,
|
||||||
|
|
@ -194,7 +230,8 @@ type GetRecallItemsByIDsParams struct {
|
||||||
// FROM recall_items
|
// FROM recall_items
|
||||||
// WHERE id IN (/*SLICE:ids*/?)
|
// WHERE id IN (/*SLICE:ids*/?)
|
||||||
// AND agent_id = ?2
|
// AND agent_id = ?2
|
||||||
func (q *Queries) GetRecallItemsByIDs(ctx context.Context, arg GetRecallItemsByIDsParams) ([]RecallItem, error) {
|
// AND suppressed_at IS NULL
|
||||||
|
func (q *Queries) GetRecallItemsByIDs(ctx context.Context, arg GetRecallItemsByIDsParams) ([]GetRecallItemsByIDsRow, error) {
|
||||||
query := GetRecallItemsByIDs
|
query := GetRecallItemsByIDs
|
||||||
var queryParams []interface{}
|
var queryParams []interface{}
|
||||||
if len(arg.Ids) > 0 {
|
if len(arg.Ids) > 0 {
|
||||||
|
|
@ -211,9 +248,9 @@ func (q *Queries) GetRecallItemsByIDs(ctx context.Context, arg GetRecallItemsByI
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
items := []RecallItem{}
|
items := []GetRecallItemsByIDsRow{}
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var i RecallItem
|
var i GetRecallItemsByIDsRow
|
||||||
if err := rows.Scan(
|
if err := rows.Scan(
|
||||||
&i.ID,
|
&i.ID,
|
||||||
&i.AgentID,
|
&i.AgentID,
|
||||||
|
|
@ -253,6 +290,7 @@ INSERT INTO recall_items (
|
||||||
decay_rate,
|
decay_rate,
|
||||||
content,
|
content,
|
||||||
tags,
|
tags,
|
||||||
|
rl_weight,
|
||||||
created_at,
|
created_at,
|
||||||
updated_at
|
updated_at
|
||||||
)
|
)
|
||||||
|
|
@ -267,6 +305,7 @@ VALUES (
|
||||||
?8,
|
?8,
|
||||||
?9,
|
?9,
|
||||||
?10,
|
?10,
|
||||||
|
?11,
|
||||||
datetime('now'),
|
datetime('now'),
|
||||||
datetime('now')
|
datetime('now')
|
||||||
)
|
)
|
||||||
|
|
@ -280,6 +319,7 @@ RETURNING id,
|
||||||
decay_rate,
|
decay_rate,
|
||||||
content,
|
content,
|
||||||
tags,
|
tags,
|
||||||
|
rl_weight,
|
||||||
created_at,
|
created_at,
|
||||||
updated_at
|
updated_at
|
||||||
`
|
`
|
||||||
|
|
@ -295,6 +335,23 @@ type InsertRecallItemParams struct {
|
||||||
DecayRate float64 `db:"decay_rate" json:"decay_rate"`
|
DecayRate float64 `db:"decay_rate" json:"decay_rate"`
|
||||||
Content string `db:"content" json:"content"`
|
Content string `db:"content" json:"content"`
|
||||||
Tags string `db:"tags" json:"tags"`
|
Tags string `db:"tags" json:"tags"`
|
||||||
|
RlWeight *float64 `db:"rl_weight" json:"rl_weight"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type InsertRecallItemRow struct {
|
||||||
|
ID ids.UUID `db:"id" json:"id"`
|
||||||
|
AgentID string `db:"agent_id" json:"agent_id"`
|
||||||
|
SessionKey string `db:"session_key" json:"session_key"`
|
||||||
|
Role string `db:"role" json:"role"`
|
||||||
|
Sector memory.Sector `db:"sector" json:"sector"`
|
||||||
|
Importance float64 `db:"importance" json:"importance"`
|
||||||
|
Salience float64 `db:"salience" json:"salience"`
|
||||||
|
DecayRate float64 `db:"decay_rate" json:"decay_rate"`
|
||||||
|
Content string `db:"content" json:"content"`
|
||||||
|
Tags string `db:"tags" json:"tags"`
|
||||||
|
RlWeight *float64 `db:"rl_weight" json:"rl_weight"`
|
||||||
|
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
||||||
|
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recall Item queries
|
// Recall Item queries
|
||||||
|
|
@ -310,6 +367,7 @@ type InsertRecallItemParams struct {
|
||||||
// decay_rate,
|
// decay_rate,
|
||||||
// content,
|
// content,
|
||||||
// tags,
|
// tags,
|
||||||
|
// rl_weight,
|
||||||
// created_at,
|
// created_at,
|
||||||
// updated_at
|
// updated_at
|
||||||
// )
|
// )
|
||||||
|
|
@ -324,6 +382,7 @@ type InsertRecallItemParams struct {
|
||||||
// ?8,
|
// ?8,
|
||||||
// ?9,
|
// ?9,
|
||||||
// ?10,
|
// ?10,
|
||||||
|
// ?11,
|
||||||
// datetime('now'),
|
// datetime('now'),
|
||||||
// datetime('now')
|
// datetime('now')
|
||||||
// )
|
// )
|
||||||
|
|
@ -337,9 +396,10 @@ type InsertRecallItemParams struct {
|
||||||
// decay_rate,
|
// decay_rate,
|
||||||
// content,
|
// content,
|
||||||
// tags,
|
// tags,
|
||||||
|
// rl_weight,
|
||||||
// created_at,
|
// created_at,
|
||||||
// updated_at
|
// updated_at
|
||||||
func (q *Queries) InsertRecallItem(ctx context.Context, arg InsertRecallItemParams) (RecallItem, error) {
|
func (q *Queries) InsertRecallItem(ctx context.Context, arg InsertRecallItemParams) (InsertRecallItemRow, error) {
|
||||||
row := q.db.QueryRowContext(ctx, InsertRecallItem,
|
row := q.db.QueryRowContext(ctx, InsertRecallItem,
|
||||||
arg.ID,
|
arg.ID,
|
||||||
arg.AgentID,
|
arg.AgentID,
|
||||||
|
|
@ -351,8 +411,9 @@ func (q *Queries) InsertRecallItem(ctx context.Context, arg InsertRecallItemPara
|
||||||
arg.DecayRate,
|
arg.DecayRate,
|
||||||
arg.Content,
|
arg.Content,
|
||||||
arg.Tags,
|
arg.Tags,
|
||||||
|
arg.RlWeight,
|
||||||
)
|
)
|
||||||
var i RecallItem
|
var i InsertRecallItemRow
|
||||||
err := row.Scan(
|
err := row.Scan(
|
||||||
&i.ID,
|
&i.ID,
|
||||||
&i.AgentID,
|
&i.AgentID,
|
||||||
|
|
@ -364,6 +425,7 @@ func (q *Queries) InsertRecallItem(ctx context.Context, arg InsertRecallItemPara
|
||||||
&i.DecayRate,
|
&i.DecayRate,
|
||||||
&i.Content,
|
&i.Content,
|
||||||
&i.Tags,
|
&i.Tags,
|
||||||
|
&i.RlWeight,
|
||||||
&i.CreatedAt,
|
&i.CreatedAt,
|
||||||
&i.UpdatedAt,
|
&i.UpdatedAt,
|
||||||
)
|
)
|
||||||
|
|
@ -421,6 +483,21 @@ type InsertSessionMessageParams struct {
|
||||||
Content string `db:"content" json:"content"`
|
Content string `db:"content" json:"content"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type InsertSessionMessageRow struct {
|
||||||
|
ID ids.UUID `db:"id" json:"id"`
|
||||||
|
AgentID string `db:"agent_id" json:"agent_id"`
|
||||||
|
SessionKey string `db:"session_key" json:"session_key"`
|
||||||
|
Role string `db:"role" json:"role"`
|
||||||
|
Sector memory.Sector `db:"sector" json:"sector"`
|
||||||
|
Importance float64 `db:"importance" json:"importance"`
|
||||||
|
Salience float64 `db:"salience" json:"salience"`
|
||||||
|
DecayRate float64 `db:"decay_rate" json:"decay_rate"`
|
||||||
|
Content string `db:"content" json:"content"`
|
||||||
|
Tags string `db:"tags" json:"tags"`
|
||||||
|
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
||||||
|
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
|
||||||
|
}
|
||||||
|
|
||||||
// InsertSessionMessage
|
// InsertSessionMessage
|
||||||
//
|
//
|
||||||
// INSERT INTO recall_items (
|
// INSERT INTO recall_items (
|
||||||
|
|
@ -463,7 +540,7 @@ type InsertSessionMessageParams struct {
|
||||||
// tags,
|
// tags,
|
||||||
// created_at,
|
// created_at,
|
||||||
// updated_at
|
// updated_at
|
||||||
func (q *Queries) InsertSessionMessage(ctx context.Context, arg InsertSessionMessageParams) (RecallItem, error) {
|
func (q *Queries) InsertSessionMessage(ctx context.Context, arg InsertSessionMessageParams) (InsertSessionMessageRow, error) {
|
||||||
row := q.db.QueryRowContext(ctx, InsertSessionMessage,
|
row := q.db.QueryRowContext(ctx, InsertSessionMessage,
|
||||||
arg.ID,
|
arg.ID,
|
||||||
arg.AgentID,
|
arg.AgentID,
|
||||||
|
|
@ -471,7 +548,7 @@ func (q *Queries) InsertSessionMessage(ctx context.Context, arg InsertSessionMes
|
||||||
arg.Role,
|
arg.Role,
|
||||||
arg.Content,
|
arg.Content,
|
||||||
)
|
)
|
||||||
var i RecallItem
|
var i InsertSessionMessageRow
|
||||||
err := row.Scan(
|
err := row.Scan(
|
||||||
&i.ID,
|
&i.ID,
|
||||||
&i.AgentID,
|
&i.AgentID,
|
||||||
|
|
@ -504,6 +581,7 @@ SELECT id,
|
||||||
updated_at
|
updated_at
|
||||||
FROM recall_items
|
FROM recall_items
|
||||||
WHERE agent_id = ?1
|
WHERE agent_id = ?1
|
||||||
|
AND suppressed_at IS NULL
|
||||||
AND (
|
AND (
|
||||||
session_key = ?2
|
session_key = ?2
|
||||||
OR ?2 = ''
|
OR ?2 = ''
|
||||||
|
|
@ -519,6 +597,21 @@ type ListRecallItemsParams struct {
|
||||||
Lim int64 `db:"lim" json:"lim"`
|
Lim int64 `db:"lim" json:"lim"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ListRecallItemsRow struct {
|
||||||
|
ID ids.UUID `db:"id" json:"id"`
|
||||||
|
AgentID string `db:"agent_id" json:"agent_id"`
|
||||||
|
SessionKey string `db:"session_key" json:"session_key"`
|
||||||
|
Role string `db:"role" json:"role"`
|
||||||
|
Sector memory.Sector `db:"sector" json:"sector"`
|
||||||
|
Importance float64 `db:"importance" json:"importance"`
|
||||||
|
Salience float64 `db:"salience" json:"salience"`
|
||||||
|
DecayRate float64 `db:"decay_rate" json:"decay_rate"`
|
||||||
|
Content string `db:"content" json:"content"`
|
||||||
|
Tags string `db:"tags" json:"tags"`
|
||||||
|
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
||||||
|
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
|
||||||
|
}
|
||||||
|
|
||||||
// ListRecallItems
|
// ListRecallItems
|
||||||
//
|
//
|
||||||
// SELECT id,
|
// SELECT id,
|
||||||
|
|
@ -535,13 +628,14 @@ type ListRecallItemsParams struct {
|
||||||
// updated_at
|
// updated_at
|
||||||
// FROM recall_items
|
// FROM recall_items
|
||||||
// WHERE agent_id = ?1
|
// WHERE agent_id = ?1
|
||||||
|
// AND suppressed_at IS NULL
|
||||||
// AND (
|
// AND (
|
||||||
// session_key = ?2
|
// session_key = ?2
|
||||||
// OR ?2 = ''
|
// OR ?2 = ''
|
||||||
// )
|
// )
|
||||||
// ORDER BY created_at DESC
|
// ORDER BY created_at DESC
|
||||||
// LIMIT ?4 OFFSET ?3
|
// LIMIT ?4 OFFSET ?3
|
||||||
func (q *Queries) ListRecallItems(ctx context.Context, arg ListRecallItemsParams) ([]RecallItem, error) {
|
func (q *Queries) ListRecallItems(ctx context.Context, arg ListRecallItemsParams) ([]ListRecallItemsRow, error) {
|
||||||
rows, err := q.db.QueryContext(ctx, ListRecallItems,
|
rows, err := q.db.QueryContext(ctx, ListRecallItems,
|
||||||
arg.AgentID,
|
arg.AgentID,
|
||||||
arg.SessionKey,
|
arg.SessionKey,
|
||||||
|
|
@ -552,9 +646,9 @@ func (q *Queries) ListRecallItems(ctx context.Context, arg ListRecallItemsParams
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
items := []RecallItem{}
|
items := []ListRecallItemsRow{}
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var i RecallItem
|
var i ListRecallItemsRow
|
||||||
if err := rows.Scan(
|
if err := rows.Scan(
|
||||||
&i.ID,
|
&i.ID,
|
||||||
&i.AgentID,
|
&i.AgentID,
|
||||||
|
|
@ -614,6 +708,21 @@ type ListSessionMessagesParams struct {
|
||||||
Lim int64 `db:"lim" json:"lim"`
|
Lim int64 `db:"lim" json:"lim"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ListSessionMessagesRow struct {
|
||||||
|
ID ids.UUID `db:"id" json:"id"`
|
||||||
|
AgentID string `db:"agent_id" json:"agent_id"`
|
||||||
|
SessionKey string `db:"session_key" json:"session_key"`
|
||||||
|
Role string `db:"role" json:"role"`
|
||||||
|
Sector memory.Sector `db:"sector" json:"sector"`
|
||||||
|
Importance float64 `db:"importance" json:"importance"`
|
||||||
|
Salience float64 `db:"salience" json:"salience"`
|
||||||
|
DecayRate float64 `db:"decay_rate" json:"decay_rate"`
|
||||||
|
Content string `db:"content" json:"content"`
|
||||||
|
Tags string `db:"tags" json:"tags"`
|
||||||
|
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
||||||
|
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
|
||||||
|
}
|
||||||
|
|
||||||
// ListSessionMessages
|
// ListSessionMessages
|
||||||
//
|
//
|
||||||
// SELECT id,
|
// SELECT id,
|
||||||
|
|
@ -638,7 +747,7 @@ type ListSessionMessagesParams struct {
|
||||||
// )
|
// )
|
||||||
// ORDER BY created_at ASC
|
// ORDER BY created_at ASC
|
||||||
// LIMIT ?4
|
// LIMIT ?4
|
||||||
func (q *Queries) ListSessionMessages(ctx context.Context, arg ListSessionMessagesParams) ([]RecallItem, error) {
|
func (q *Queries) ListSessionMessages(ctx context.Context, arg ListSessionMessagesParams) ([]ListSessionMessagesRow, error) {
|
||||||
rows, err := q.db.QueryContext(ctx, ListSessionMessages,
|
rows, err := q.db.QueryContext(ctx, ListSessionMessages,
|
||||||
arg.AgentID,
|
arg.AgentID,
|
||||||
arg.SessionKey,
|
arg.SessionKey,
|
||||||
|
|
@ -649,9 +758,9 @@ func (q *Queries) ListSessionMessages(ctx context.Context, arg ListSessionMessag
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
items := []RecallItem{}
|
items := []ListSessionMessagesRow{}
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var i RecallItem
|
var i ListSessionMessagesRow
|
||||||
if err := rows.Scan(
|
if err := rows.Scan(
|
||||||
&i.ID,
|
&i.ID,
|
||||||
&i.AgentID,
|
&i.AgentID,
|
||||||
|
|
@ -712,6 +821,21 @@ type ListSessionMessagesPagedParams struct {
|
||||||
Lim int64 `db:"lim" json:"lim"`
|
Lim int64 `db:"lim" json:"lim"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ListSessionMessagesPagedRow struct {
|
||||||
|
ID ids.UUID `db:"id" json:"id"`
|
||||||
|
AgentID string `db:"agent_id" json:"agent_id"`
|
||||||
|
SessionKey string `db:"session_key" json:"session_key"`
|
||||||
|
Role string `db:"role" json:"role"`
|
||||||
|
Sector memory.Sector `db:"sector" json:"sector"`
|
||||||
|
Importance float64 `db:"importance" json:"importance"`
|
||||||
|
Salience float64 `db:"salience" json:"salience"`
|
||||||
|
DecayRate float64 `db:"decay_rate" json:"decay_rate"`
|
||||||
|
Content string `db:"content" json:"content"`
|
||||||
|
Tags string `db:"tags" json:"tags"`
|
||||||
|
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
||||||
|
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
|
||||||
|
}
|
||||||
|
|
||||||
// ListSessionMessagesPaged
|
// ListSessionMessagesPaged
|
||||||
//
|
//
|
||||||
// SELECT id,
|
// SELECT id,
|
||||||
|
|
@ -736,7 +860,7 @@ type ListSessionMessagesPagedParams struct {
|
||||||
// )
|
// )
|
||||||
// ORDER BY created_at ASC
|
// ORDER BY created_at ASC
|
||||||
// LIMIT ?5 OFFSET ?4
|
// LIMIT ?5 OFFSET ?4
|
||||||
func (q *Queries) ListSessionMessagesPaged(ctx context.Context, arg ListSessionMessagesPagedParams) ([]RecallItem, error) {
|
func (q *Queries) ListSessionMessagesPaged(ctx context.Context, arg ListSessionMessagesPagedParams) ([]ListSessionMessagesPagedRow, error) {
|
||||||
rows, err := q.db.QueryContext(ctx, ListSessionMessagesPaged,
|
rows, err := q.db.QueryContext(ctx, ListSessionMessagesPaged,
|
||||||
arg.AgentID,
|
arg.AgentID,
|
||||||
arg.SessionKey,
|
arg.SessionKey,
|
||||||
|
|
@ -748,9 +872,9 @@ func (q *Queries) ListSessionMessagesPaged(ctx context.Context, arg ListSessionM
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
items := []RecallItem{}
|
items := []ListSessionMessagesPagedRow{}
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var i RecallItem
|
var i ListSessionMessagesPagedRow
|
||||||
if err := rows.Scan(
|
if err := rows.Scan(
|
||||||
&i.ID,
|
&i.ID,
|
||||||
&i.AgentID,
|
&i.AgentID,
|
||||||
|
|
@ -794,6 +918,7 @@ SELECT ri.id,
|
||||||
FROM recall_items ri
|
FROM recall_items ri
|
||||||
WHERE ri.content LIKE '%' || ?1 || '%'
|
WHERE ri.content LIKE '%' || ?1 || '%'
|
||||||
AND ri.agent_id = ?2
|
AND ri.agent_id = ?2
|
||||||
|
AND ri.suppressed_at IS NULL
|
||||||
ORDER BY ri.importance DESC
|
ORDER BY ri.importance DESC
|
||||||
LIMIT ?3
|
LIMIT ?3
|
||||||
`
|
`
|
||||||
|
|
@ -804,6 +929,21 @@ type SearchRecallByKeywordParams struct {
|
||||||
Lim int64 `db:"lim" json:"lim"`
|
Lim int64 `db:"lim" json:"lim"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type SearchRecallByKeywordRow struct {
|
||||||
|
ID ids.UUID `db:"id" json:"id"`
|
||||||
|
AgentID string `db:"agent_id" json:"agent_id"`
|
||||||
|
SessionKey string `db:"session_key" json:"session_key"`
|
||||||
|
Role string `db:"role" json:"role"`
|
||||||
|
Sector memory.Sector `db:"sector" json:"sector"`
|
||||||
|
Importance float64 `db:"importance" json:"importance"`
|
||||||
|
Salience float64 `db:"salience" json:"salience"`
|
||||||
|
DecayRate float64 `db:"decay_rate" json:"decay_rate"`
|
||||||
|
Content string `db:"content" json:"content"`
|
||||||
|
Tags string `db:"tags" json:"tags"`
|
||||||
|
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
||||||
|
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
|
||||||
|
}
|
||||||
|
|
||||||
// SearchRecallByKeyword
|
// SearchRecallByKeyword
|
||||||
//
|
//
|
||||||
// SELECT ri.id,
|
// SELECT ri.id,
|
||||||
|
|
@ -821,17 +961,18 @@ type SearchRecallByKeywordParams struct {
|
||||||
// FROM recall_items ri
|
// FROM recall_items ri
|
||||||
// WHERE ri.content LIKE '%' || ?1 || '%'
|
// WHERE ri.content LIKE '%' || ?1 || '%'
|
||||||
// AND ri.agent_id = ?2
|
// AND ri.agent_id = ?2
|
||||||
|
// AND ri.suppressed_at IS NULL
|
||||||
// ORDER BY ri.importance DESC
|
// ORDER BY ri.importance DESC
|
||||||
// LIMIT ?3
|
// LIMIT ?3
|
||||||
func (q *Queries) SearchRecallByKeyword(ctx context.Context, arg SearchRecallByKeywordParams) ([]RecallItem, error) {
|
func (q *Queries) SearchRecallByKeyword(ctx context.Context, arg SearchRecallByKeywordParams) ([]SearchRecallByKeywordRow, error) {
|
||||||
rows, err := q.db.QueryContext(ctx, SearchRecallByKeyword, arg.Keyword, arg.AgentID, arg.Lim)
|
rows, err := q.db.QueryContext(ctx, SearchRecallByKeyword, arg.Keyword, arg.AgentID, arg.Lim)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
items := []RecallItem{}
|
items := []SearchRecallByKeywordRow{}
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var i RecallItem
|
var i SearchRecallByKeywordRow
|
||||||
if err := rows.Scan(
|
if err := rows.Scan(
|
||||||
&i.ID,
|
&i.ID,
|
||||||
&i.AgentID,
|
&i.AgentID,
|
||||||
|
|
|
||||||
175
pkg/memory/sqlc/recall_decay.sql.go
Normal file
175
pkg/memory/sqlc/recall_decay.sql.go
Normal file
|
|
@ -0,0 +1,175 @@
|
||||||
|
// Code generated by sqlc. DO NOT EDIT.
|
||||||
|
// versions:
|
||||||
|
// sqlc v1.30.0
|
||||||
|
// source: recall_decay.sql
|
||||||
|
|
||||||
|
package sqlc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/ZanzyTHEbar/dragonscale/pkg/ids"
|
||||||
|
"github.com/ZanzyTHEbar/dragonscale/pkg/memory"
|
||||||
|
)
|
||||||
|
|
||||||
|
const CountArchivalChunksWithoutEmbedding = `-- name: CountArchivalChunksWithoutEmbedding :one
|
||||||
|
SELECT COUNT(*)
|
||||||
|
FROM archival_chunks
|
||||||
|
WHERE embedding IS NULL
|
||||||
|
AND suppressed_at IS NULL
|
||||||
|
`
|
||||||
|
|
||||||
|
// CountArchivalChunksWithoutEmbedding
|
||||||
|
//
|
||||||
|
// SELECT COUNT(*)
|
||||||
|
// FROM archival_chunks
|
||||||
|
// WHERE embedding IS NULL
|
||||||
|
// AND suppressed_at IS NULL
|
||||||
|
func (q *Queries) CountArchivalChunksWithoutEmbedding(ctx context.Context) (int64, error) {
|
||||||
|
row := q.db.QueryRowContext(ctx, CountArchivalChunksWithoutEmbedding)
|
||||||
|
var count int64
|
||||||
|
err := row.Scan(&count)
|
||||||
|
return count, err
|
||||||
|
}
|
||||||
|
|
||||||
|
const DecayRecallImportanceBatch = `-- name: DecayRecallImportanceBatch :exec
|
||||||
|
UPDATE recall_items
|
||||||
|
SET importance = MAX(
|
||||||
|
recall_items.importance * ?1,
|
||||||
|
?2
|
||||||
|
),
|
||||||
|
updated_at = datetime('now')
|
||||||
|
WHERE recall_items.id IN (
|
||||||
|
SELECT ri.id
|
||||||
|
FROM recall_items ri
|
||||||
|
WHERE ri.importance > ?2
|
||||||
|
AND ri.suppressed_at IS NULL
|
||||||
|
ORDER BY ri.updated_at ASC
|
||||||
|
LIMIT ?3
|
||||||
|
)
|
||||||
|
`
|
||||||
|
|
||||||
|
type DecayRecallImportanceBatchParams struct {
|
||||||
|
Factor float64 `db:"factor" json:"factor"`
|
||||||
|
FloorVal interface{} `db:"floor_val" json:"floor_val"`
|
||||||
|
BatchSize int64 `db:"batch_size" json:"batch_size"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Batch decay of recall item importance (Cortex decay task)
|
||||||
|
//
|
||||||
|
// UPDATE recall_items
|
||||||
|
// SET importance = MAX(
|
||||||
|
// recall_items.importance * ?1,
|
||||||
|
// ?2
|
||||||
|
// ),
|
||||||
|
// updated_at = datetime('now')
|
||||||
|
// WHERE recall_items.id IN (
|
||||||
|
// SELECT ri.id
|
||||||
|
// FROM recall_items ri
|
||||||
|
// WHERE ri.importance > ?2
|
||||||
|
// AND ri.suppressed_at IS NULL
|
||||||
|
// ORDER BY ri.updated_at ASC
|
||||||
|
// LIMIT ?3
|
||||||
|
// )
|
||||||
|
func (q *Queries) DecayRecallImportanceBatch(ctx context.Context, arg DecayRecallImportanceBatchParams) error {
|
||||||
|
_, err := q.db.ExecContext(ctx, DecayRecallImportanceBatch, arg.Factor, arg.FloorVal, arg.BatchSize)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
const ListArchivalChunksWithoutEmbedding = `-- name: ListArchivalChunksWithoutEmbedding :many
|
||||||
|
SELECT id,
|
||||||
|
recall_id,
|
||||||
|
chunk_index,
|
||||||
|
content,
|
||||||
|
embedding,
|
||||||
|
source,
|
||||||
|
hash,
|
||||||
|
created_at
|
||||||
|
FROM archival_chunks
|
||||||
|
WHERE embedding IS NULL
|
||||||
|
AND suppressed_at IS NULL
|
||||||
|
LIMIT ?1
|
||||||
|
`
|
||||||
|
|
||||||
|
type ListArchivalChunksWithoutEmbeddingParams struct {
|
||||||
|
Lim int64 `db:"lim" json:"lim"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ListArchivalChunksWithoutEmbeddingRow struct {
|
||||||
|
ID ids.UUID `db:"id" json:"id"`
|
||||||
|
RecallID ids.UUID `db:"recall_id" json:"recall_id"`
|
||||||
|
ChunkIndex int64 `db:"chunk_index" json:"chunk_index"`
|
||||||
|
Content string `db:"content" json:"content"`
|
||||||
|
Embedding memory.Embedding `db:"embedding" json:"embedding"`
|
||||||
|
Source string `db:"source" json:"source"`
|
||||||
|
Hash string `db:"hash" json:"hash"`
|
||||||
|
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListArchivalChunksWithoutEmbedding
|
||||||
|
//
|
||||||
|
// SELECT id,
|
||||||
|
// recall_id,
|
||||||
|
// chunk_index,
|
||||||
|
// content,
|
||||||
|
// embedding,
|
||||||
|
// source,
|
||||||
|
// hash,
|
||||||
|
// created_at
|
||||||
|
// FROM archival_chunks
|
||||||
|
// WHERE embedding IS NULL
|
||||||
|
// AND suppressed_at IS NULL
|
||||||
|
// LIMIT ?1
|
||||||
|
func (q *Queries) ListArchivalChunksWithoutEmbedding(ctx context.Context, arg ListArchivalChunksWithoutEmbeddingParams) ([]ListArchivalChunksWithoutEmbeddingRow, error) {
|
||||||
|
rows, err := q.db.QueryContext(ctx, ListArchivalChunksWithoutEmbedding, arg.Lim)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
items := []ListArchivalChunksWithoutEmbeddingRow{}
|
||||||
|
for rows.Next() {
|
||||||
|
var i ListArchivalChunksWithoutEmbeddingRow
|
||||||
|
if err := rows.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.RecallID,
|
||||||
|
&i.ChunkIndex,
|
||||||
|
&i.Content,
|
||||||
|
&i.Embedding,
|
||||||
|
&i.Source,
|
||||||
|
&i.Hash,
|
||||||
|
&i.CreatedAt,
|
||||||
|
); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
items = append(items, i)
|
||||||
|
}
|
||||||
|
if err := rows.Close(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := rows.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return items, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
const UpdateArchivalChunkEmbedding = `-- name: UpdateArchivalChunkEmbedding :exec
|
||||||
|
UPDATE archival_chunks
|
||||||
|
SET embedding = ?1
|
||||||
|
WHERE id = ?2
|
||||||
|
`
|
||||||
|
|
||||||
|
type UpdateArchivalChunkEmbeddingParams struct {
|
||||||
|
Embedding memory.Embedding `db:"embedding" json:"embedding"`
|
||||||
|
ID ids.UUID `db:"id" json:"id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateArchivalChunkEmbedding
|
||||||
|
//
|
||||||
|
// UPDATE archival_chunks
|
||||||
|
// SET embedding = ?1
|
||||||
|
// WHERE id = ?2
|
||||||
|
func (q *Queries) UpdateArchivalChunkEmbedding(ctx context.Context, arg UpdateArchivalChunkEmbeddingParams) error {
|
||||||
|
_, err := q.db.ExecContext(ctx, UpdateArchivalChunkEmbedding, arg.Embedding, arg.ID)
|
||||||
|
return err
|
||||||
|
}
|
||||||
758
pkg/memory/sqlc/rl.sql.go
Normal file
758
pkg/memory/sqlc/rl.sql.go
Normal file
|
|
@ -0,0 +1,758 @@
|
||||||
|
// Code generated by sqlc. DO NOT EDIT.
|
||||||
|
// versions:
|
||||||
|
// sqlc v1.30.0
|
||||||
|
// source: rl.sql
|
||||||
|
|
||||||
|
package sqlc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/ZanzyTHEbar/dragonscale/pkg/ids"
|
||||||
|
"github.com/ZanzyTHEbar/dragonscale/pkg/memory"
|
||||||
|
)
|
||||||
|
|
||||||
|
const GetCompletedTasks = `-- name: GetCompletedTasks :many
|
||||||
|
SELECT id,
|
||||||
|
agent_id,
|
||||||
|
conversation_id,
|
||||||
|
run_id,
|
||||||
|
description,
|
||||||
|
tokens_used,
|
||||||
|
tool_calls,
|
||||||
|
errors,
|
||||||
|
user_corrections,
|
||||||
|
completed,
|
||||||
|
created_at
|
||||||
|
FROM task_completions
|
||||||
|
WHERE agent_id = ?1
|
||||||
|
AND created_at > ?2
|
||||||
|
AND completed = 1
|
||||||
|
ORDER BY created_at ASC
|
||||||
|
`
|
||||||
|
|
||||||
|
type GetCompletedTasksParams struct {
|
||||||
|
AgentID string `db:"agent_id" json:"agent_id"`
|
||||||
|
Since time.Time `db:"since" json:"since"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get tasks completed since the given time for RL processing
|
||||||
|
//
|
||||||
|
// SELECT id,
|
||||||
|
// agent_id,
|
||||||
|
// conversation_id,
|
||||||
|
// run_id,
|
||||||
|
// description,
|
||||||
|
// tokens_used,
|
||||||
|
// tool_calls,
|
||||||
|
// errors,
|
||||||
|
// user_corrections,
|
||||||
|
// completed,
|
||||||
|
// created_at
|
||||||
|
// FROM task_completions
|
||||||
|
// WHERE agent_id = ?1
|
||||||
|
// AND created_at > ?2
|
||||||
|
// AND completed = 1
|
||||||
|
// ORDER BY created_at ASC
|
||||||
|
func (q *Queries) GetCompletedTasks(ctx context.Context, arg GetCompletedTasksParams) ([]TaskCompletion, error) {
|
||||||
|
rows, err := q.db.QueryContext(ctx, GetCompletedTasks, arg.AgentID, arg.Since)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
items := []TaskCompletion{}
|
||||||
|
for rows.Next() {
|
||||||
|
var i TaskCompletion
|
||||||
|
if err := rows.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.AgentID,
|
||||||
|
&i.ConversationID,
|
||||||
|
&i.RunID,
|
||||||
|
&i.Description,
|
||||||
|
&i.TokensUsed,
|
||||||
|
&i.ToolCalls,
|
||||||
|
&i.Errors,
|
||||||
|
&i.UserCorrections,
|
||||||
|
&i.Completed,
|
||||||
|
&i.CreatedAt,
|
||||||
|
); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
items = append(items, i)
|
||||||
|
}
|
||||||
|
if err := rows.Close(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := rows.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return items, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
const GetMemoriesByRetrievalCount = `-- name: GetMemoriesByRetrievalCount :many
|
||||||
|
SELECT id,
|
||||||
|
agent_id,
|
||||||
|
session_key,
|
||||||
|
role,
|
||||||
|
sector,
|
||||||
|
importance,
|
||||||
|
salience,
|
||||||
|
decay_rate,
|
||||||
|
content,
|
||||||
|
tags,
|
||||||
|
rl_weight,
|
||||||
|
rl_credit,
|
||||||
|
self_report_score,
|
||||||
|
task_retrieval_count,
|
||||||
|
created_at,
|
||||||
|
updated_at
|
||||||
|
FROM recall_items
|
||||||
|
WHERE agent_id = ?1
|
||||||
|
AND suppressed_at IS NULL
|
||||||
|
ORDER BY task_retrieval_count DESC
|
||||||
|
LIMIT ?2
|
||||||
|
`
|
||||||
|
|
||||||
|
type GetMemoriesByRetrievalCountParams struct {
|
||||||
|
AgentID string `db:"agent_id" json:"agent_id"`
|
||||||
|
Lim int64 `db:"lim" json:"lim"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetMemoriesByRetrievalCountRow struct {
|
||||||
|
ID ids.UUID `db:"id" json:"id"`
|
||||||
|
AgentID string `db:"agent_id" json:"agent_id"`
|
||||||
|
SessionKey string `db:"session_key" json:"session_key"`
|
||||||
|
Role string `db:"role" json:"role"`
|
||||||
|
Sector memory.Sector `db:"sector" json:"sector"`
|
||||||
|
Importance float64 `db:"importance" json:"importance"`
|
||||||
|
Salience float64 `db:"salience" json:"salience"`
|
||||||
|
DecayRate float64 `db:"decay_rate" json:"decay_rate"`
|
||||||
|
Content string `db:"content" json:"content"`
|
||||||
|
Tags string `db:"tags" json:"tags"`
|
||||||
|
RlWeight *float64 `db:"rl_weight" json:"rl_weight"`
|
||||||
|
RlCredit *float64 `db:"rl_credit" json:"rl_credit"`
|
||||||
|
SelfReportScore *int64 `db:"self_report_score" json:"self_report_score"`
|
||||||
|
TaskRetrievalCount *int64 `db:"task_retrieval_count" json:"task_retrieval_count"`
|
||||||
|
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
||||||
|
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get memories ordered by their task retrieval count (for RL analysis)
|
||||||
|
//
|
||||||
|
// SELECT id,
|
||||||
|
// agent_id,
|
||||||
|
// session_key,
|
||||||
|
// role,
|
||||||
|
// sector,
|
||||||
|
// importance,
|
||||||
|
// salience,
|
||||||
|
// decay_rate,
|
||||||
|
// content,
|
||||||
|
// tags,
|
||||||
|
// rl_weight,
|
||||||
|
// rl_credit,
|
||||||
|
// self_report_score,
|
||||||
|
// task_retrieval_count,
|
||||||
|
// created_at,
|
||||||
|
// updated_at
|
||||||
|
// FROM recall_items
|
||||||
|
// WHERE agent_id = ?1
|
||||||
|
// AND suppressed_at IS NULL
|
||||||
|
// ORDER BY task_retrieval_count DESC
|
||||||
|
// LIMIT ?2
|
||||||
|
func (q *Queries) GetMemoriesByRetrievalCount(ctx context.Context, arg GetMemoriesByRetrievalCountParams) ([]GetMemoriesByRetrievalCountRow, error) {
|
||||||
|
rows, err := q.db.QueryContext(ctx, GetMemoriesByRetrievalCount, arg.AgentID, arg.Lim)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
items := []GetMemoriesByRetrievalCountRow{}
|
||||||
|
for rows.Next() {
|
||||||
|
var i GetMemoriesByRetrievalCountRow
|
||||||
|
if err := rows.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.AgentID,
|
||||||
|
&i.SessionKey,
|
||||||
|
&i.Role,
|
||||||
|
&i.Sector,
|
||||||
|
&i.Importance,
|
||||||
|
&i.Salience,
|
||||||
|
&i.DecayRate,
|
||||||
|
&i.Content,
|
||||||
|
&i.Tags,
|
||||||
|
&i.RlWeight,
|
||||||
|
&i.RlCredit,
|
||||||
|
&i.SelfReportScore,
|
||||||
|
&i.TaskRetrievalCount,
|
||||||
|
&i.CreatedAt,
|
||||||
|
&i.UpdatedAt,
|
||||||
|
); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
items = append(items, i)
|
||||||
|
}
|
||||||
|
if err := rows.Close(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := rows.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return items, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
const GetRetrievedMemories = `-- name: GetRetrievedMemories :many
|
||||||
|
SELECT tr.memory_id,
|
||||||
|
tr.similarity,
|
||||||
|
ri.self_report_score
|
||||||
|
FROM task_retrievals tr
|
||||||
|
JOIN recall_items ri ON tr.memory_id = ri.id
|
||||||
|
WHERE tr.task_id = ?1
|
||||||
|
`
|
||||||
|
|
||||||
|
type GetRetrievedMemoriesParams struct {
|
||||||
|
TaskID ids.UUID `db:"task_id" json:"task_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetRetrievedMemoriesRow struct {
|
||||||
|
MemoryID ids.UUID `db:"memory_id" json:"memory_id"`
|
||||||
|
Similarity float64 `db:"similarity" json:"similarity"`
|
||||||
|
SelfReportScore *int64 `db:"self_report_score" json:"self_report_score"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get memories retrieved during a specific task with their self-report scores
|
||||||
|
//
|
||||||
|
// SELECT tr.memory_id,
|
||||||
|
// tr.similarity,
|
||||||
|
// ri.self_report_score
|
||||||
|
// FROM task_retrievals tr
|
||||||
|
// JOIN recall_items ri ON tr.memory_id = ri.id
|
||||||
|
// WHERE tr.task_id = ?1
|
||||||
|
func (q *Queries) GetRetrievedMemories(ctx context.Context, arg GetRetrievedMemoriesParams) ([]GetRetrievedMemoriesRow, error) {
|
||||||
|
rows, err := q.db.QueryContext(ctx, GetRetrievedMemories, arg.TaskID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
items := []GetRetrievedMemoriesRow{}
|
||||||
|
for rows.Next() {
|
||||||
|
var i GetRetrievedMemoriesRow
|
||||||
|
if err := rows.Scan(&i.MemoryID, &i.Similarity, &i.SelfReportScore); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
items = append(items, i)
|
||||||
|
}
|
||||||
|
if err := rows.Close(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := rows.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return items, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
const GetTaskBaseline = `-- name: GetTaskBaseline :one
|
||||||
|
|
||||||
|
SELECT agent_id,
|
||||||
|
count,
|
||||||
|
mean_tokens,
|
||||||
|
mean_errors,
|
||||||
|
mean_user_corrections,
|
||||||
|
m2_tokens,
|
||||||
|
m2_errors,
|
||||||
|
m2_user_corrections,
|
||||||
|
updated_at
|
||||||
|
FROM task_baselines
|
||||||
|
WHERE agent_id = ?1
|
||||||
|
LIMIT 1
|
||||||
|
`
|
||||||
|
|
||||||
|
type GetTaskBaselineParams struct {
|
||||||
|
AgentID string `db:"agent_id" json:"agent_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// RL (Reinforcement Learning) queries for Memelord integration
|
||||||
|
// Task baseline queries for per-agent performance statistics
|
||||||
|
// Get the baseline statistics for an agent
|
||||||
|
//
|
||||||
|
// SELECT agent_id,
|
||||||
|
// count,
|
||||||
|
// mean_tokens,
|
||||||
|
// mean_errors,
|
||||||
|
// mean_user_corrections,
|
||||||
|
// m2_tokens,
|
||||||
|
// m2_errors,
|
||||||
|
// m2_user_corrections,
|
||||||
|
// updated_at
|
||||||
|
// FROM task_baselines
|
||||||
|
// WHERE agent_id = ?1
|
||||||
|
// LIMIT 1
|
||||||
|
func (q *Queries) GetTaskBaseline(ctx context.Context, arg GetTaskBaselineParams) (TaskBaseline, error) {
|
||||||
|
row := q.db.QueryRowContext(ctx, GetTaskBaseline, arg.AgentID)
|
||||||
|
var i TaskBaseline
|
||||||
|
err := row.Scan(
|
||||||
|
&i.AgentID,
|
||||||
|
&i.Count,
|
||||||
|
&i.MeanTokens,
|
||||||
|
&i.MeanErrors,
|
||||||
|
&i.MeanUserCorrections,
|
||||||
|
&i.M2Tokens,
|
||||||
|
&i.M2Errors,
|
||||||
|
&i.M2UserCorrections,
|
||||||
|
&i.UpdatedAt,
|
||||||
|
)
|
||||||
|
return i, err
|
||||||
|
}
|
||||||
|
|
||||||
|
const IncrementTaskRetrievalCount = `-- name: IncrementTaskRetrievalCount :exec
|
||||||
|
UPDATE recall_items
|
||||||
|
SET task_retrieval_count = task_retrieval_count + 1,
|
||||||
|
updated_at = datetime('now')
|
||||||
|
WHERE id = ?1
|
||||||
|
AND agent_id = ?2
|
||||||
|
`
|
||||||
|
|
||||||
|
type IncrementTaskRetrievalCountParams struct {
|
||||||
|
ID ids.UUID `db:"id" json:"id"`
|
||||||
|
AgentID string `db:"agent_id" json:"agent_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Increment the task retrieval counter for a memory item
|
||||||
|
//
|
||||||
|
// UPDATE recall_items
|
||||||
|
// SET task_retrieval_count = task_retrieval_count + 1,
|
||||||
|
// updated_at = datetime('now')
|
||||||
|
// WHERE id = ?1
|
||||||
|
// AND agent_id = ?2
|
||||||
|
func (q *Queries) IncrementTaskRetrievalCount(ctx context.Context, arg IncrementTaskRetrievalCountParams) error {
|
||||||
|
_, err := q.db.ExecContext(ctx, IncrementTaskRetrievalCount, arg.ID, arg.AgentID)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
const ListHighValueMemories = `-- name: ListHighValueMemories :many
|
||||||
|
SELECT id,
|
||||||
|
agent_id,
|
||||||
|
session_key,
|
||||||
|
role,
|
||||||
|
sector,
|
||||||
|
importance,
|
||||||
|
salience,
|
||||||
|
decay_rate,
|
||||||
|
content,
|
||||||
|
tags,
|
||||||
|
rl_weight,
|
||||||
|
rl_credit,
|
||||||
|
self_report_score,
|
||||||
|
task_retrieval_count,
|
||||||
|
created_at,
|
||||||
|
updated_at
|
||||||
|
FROM recall_items
|
||||||
|
WHERE agent_id = ?1
|
||||||
|
AND suppressed_at IS NULL
|
||||||
|
AND (
|
||||||
|
rl_credit > ?2
|
||||||
|
OR rl_weight > ?3
|
||||||
|
)
|
||||||
|
ORDER BY rl_credit DESC NULLS LAST
|
||||||
|
LIMIT ?4
|
||||||
|
`
|
||||||
|
|
||||||
|
type ListHighValueMemoriesParams struct {
|
||||||
|
AgentID string `db:"agent_id" json:"agent_id"`
|
||||||
|
MinCredit *float64 `db:"min_credit" json:"min_credit"`
|
||||||
|
MinWeight *float64 `db:"min_weight" json:"min_weight"`
|
||||||
|
Lim int64 `db:"lim" json:"lim"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ListHighValueMemoriesRow struct {
|
||||||
|
ID ids.UUID `db:"id" json:"id"`
|
||||||
|
AgentID string `db:"agent_id" json:"agent_id"`
|
||||||
|
SessionKey string `db:"session_key" json:"session_key"`
|
||||||
|
Role string `db:"role" json:"role"`
|
||||||
|
Sector memory.Sector `db:"sector" json:"sector"`
|
||||||
|
Importance float64 `db:"importance" json:"importance"`
|
||||||
|
Salience float64 `db:"salience" json:"salience"`
|
||||||
|
DecayRate float64 `db:"decay_rate" json:"decay_rate"`
|
||||||
|
Content string `db:"content" json:"content"`
|
||||||
|
Tags string `db:"tags" json:"tags"`
|
||||||
|
RlWeight *float64 `db:"rl_weight" json:"rl_weight"`
|
||||||
|
RlCredit *float64 `db:"rl_credit" json:"rl_credit"`
|
||||||
|
SelfReportScore *int64 `db:"self_report_score" json:"self_report_score"`
|
||||||
|
TaskRetrievalCount *int64 `db:"task_retrieval_count" json:"task_retrieval_count"`
|
||||||
|
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
||||||
|
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// List memories with high RL weights (credits) for priority retention
|
||||||
|
//
|
||||||
|
// SELECT id,
|
||||||
|
// agent_id,
|
||||||
|
// session_key,
|
||||||
|
// role,
|
||||||
|
// sector,
|
||||||
|
// importance,
|
||||||
|
// salience,
|
||||||
|
// decay_rate,
|
||||||
|
// content,
|
||||||
|
// tags,
|
||||||
|
// rl_weight,
|
||||||
|
// rl_credit,
|
||||||
|
// self_report_score,
|
||||||
|
// task_retrieval_count,
|
||||||
|
// created_at,
|
||||||
|
// updated_at
|
||||||
|
// FROM recall_items
|
||||||
|
// WHERE agent_id = ?1
|
||||||
|
// AND suppressed_at IS NULL
|
||||||
|
// AND (
|
||||||
|
// rl_credit > ?2
|
||||||
|
// OR rl_weight > ?3
|
||||||
|
// )
|
||||||
|
// ORDER BY rl_credit DESC NULLS LAST
|
||||||
|
// LIMIT ?4
|
||||||
|
func (q *Queries) ListHighValueMemories(ctx context.Context, arg ListHighValueMemoriesParams) ([]ListHighValueMemoriesRow, error) {
|
||||||
|
rows, err := q.db.QueryContext(ctx, ListHighValueMemories,
|
||||||
|
arg.AgentID,
|
||||||
|
arg.MinCredit,
|
||||||
|
arg.MinWeight,
|
||||||
|
arg.Lim,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
items := []ListHighValueMemoriesRow{}
|
||||||
|
for rows.Next() {
|
||||||
|
var i ListHighValueMemoriesRow
|
||||||
|
if err := rows.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.AgentID,
|
||||||
|
&i.SessionKey,
|
||||||
|
&i.Role,
|
||||||
|
&i.Sector,
|
||||||
|
&i.Importance,
|
||||||
|
&i.Salience,
|
||||||
|
&i.DecayRate,
|
||||||
|
&i.Content,
|
||||||
|
&i.Tags,
|
||||||
|
&i.RlWeight,
|
||||||
|
&i.RlCredit,
|
||||||
|
&i.SelfReportScore,
|
||||||
|
&i.TaskRetrievalCount,
|
||||||
|
&i.CreatedAt,
|
||||||
|
&i.UpdatedAt,
|
||||||
|
); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
items = append(items, i)
|
||||||
|
}
|
||||||
|
if err := rows.Close(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := rows.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return items, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
const StoreTaskCompletion = `-- name: StoreTaskCompletion :one
|
||||||
|
INSERT INTO task_completions (
|
||||||
|
id,
|
||||||
|
agent_id,
|
||||||
|
conversation_id,
|
||||||
|
run_id,
|
||||||
|
description,
|
||||||
|
tokens_used,
|
||||||
|
tool_calls,
|
||||||
|
errors,
|
||||||
|
user_corrections,
|
||||||
|
completed
|
||||||
|
)
|
||||||
|
VALUES (
|
||||||
|
?1,
|
||||||
|
?2,
|
||||||
|
?3,
|
||||||
|
?4,
|
||||||
|
?5,
|
||||||
|
?6,
|
||||||
|
?7,
|
||||||
|
?8,
|
||||||
|
?9,
|
||||||
|
?10
|
||||||
|
)
|
||||||
|
RETURNING id,
|
||||||
|
agent_id,
|
||||||
|
conversation_id,
|
||||||
|
run_id,
|
||||||
|
description,
|
||||||
|
tokens_used,
|
||||||
|
tool_calls,
|
||||||
|
errors,
|
||||||
|
user_corrections,
|
||||||
|
completed,
|
||||||
|
created_at
|
||||||
|
`
|
||||||
|
|
||||||
|
type StoreTaskCompletionParams struct {
|
||||||
|
ID ids.UUID `db:"id" json:"id"`
|
||||||
|
AgentID string `db:"agent_id" json:"agent_id"`
|
||||||
|
ConversationID ids.UUID `db:"conversation_id" json:"conversation_id"`
|
||||||
|
RunID ids.UUID `db:"run_id" json:"run_id"`
|
||||||
|
Description string `db:"description" json:"description"`
|
||||||
|
TokensUsed *int64 `db:"tokens_used" json:"tokens_used"`
|
||||||
|
ToolCalls *int64 `db:"tool_calls" json:"tool_calls"`
|
||||||
|
Errors *int64 `db:"errors" json:"errors"`
|
||||||
|
UserCorrections *int64 `db:"user_corrections" json:"user_corrections"`
|
||||||
|
Completed bool `db:"completed" json:"completed"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store a task completion record for RL analysis
|
||||||
|
//
|
||||||
|
// INSERT INTO task_completions (
|
||||||
|
// id,
|
||||||
|
// agent_id,
|
||||||
|
// conversation_id,
|
||||||
|
// run_id,
|
||||||
|
// description,
|
||||||
|
// tokens_used,
|
||||||
|
// tool_calls,
|
||||||
|
// errors,
|
||||||
|
// user_corrections,
|
||||||
|
// completed
|
||||||
|
// )
|
||||||
|
// VALUES (
|
||||||
|
// ?1,
|
||||||
|
// ?2,
|
||||||
|
// ?3,
|
||||||
|
// ?4,
|
||||||
|
// ?5,
|
||||||
|
// ?6,
|
||||||
|
// ?7,
|
||||||
|
// ?8,
|
||||||
|
// ?9,
|
||||||
|
// ?10
|
||||||
|
// )
|
||||||
|
// RETURNING id,
|
||||||
|
// agent_id,
|
||||||
|
// conversation_id,
|
||||||
|
// run_id,
|
||||||
|
// description,
|
||||||
|
// tokens_used,
|
||||||
|
// tool_calls,
|
||||||
|
// errors,
|
||||||
|
// user_corrections,
|
||||||
|
// completed,
|
||||||
|
// created_at
|
||||||
|
func (q *Queries) StoreTaskCompletion(ctx context.Context, arg StoreTaskCompletionParams) (TaskCompletion, error) {
|
||||||
|
row := q.db.QueryRowContext(ctx, StoreTaskCompletion,
|
||||||
|
arg.ID,
|
||||||
|
arg.AgentID,
|
||||||
|
arg.ConversationID,
|
||||||
|
arg.RunID,
|
||||||
|
arg.Description,
|
||||||
|
arg.TokensUsed,
|
||||||
|
arg.ToolCalls,
|
||||||
|
arg.Errors,
|
||||||
|
arg.UserCorrections,
|
||||||
|
arg.Completed,
|
||||||
|
)
|
||||||
|
var i TaskCompletion
|
||||||
|
err := row.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.AgentID,
|
||||||
|
&i.ConversationID,
|
||||||
|
&i.RunID,
|
||||||
|
&i.Description,
|
||||||
|
&i.TokensUsed,
|
||||||
|
&i.ToolCalls,
|
||||||
|
&i.Errors,
|
||||||
|
&i.UserCorrections,
|
||||||
|
&i.Completed,
|
||||||
|
&i.CreatedAt,
|
||||||
|
)
|
||||||
|
return i, err
|
||||||
|
}
|
||||||
|
|
||||||
|
const StoreTaskRetrieval = `-- name: StoreTaskRetrieval :exec
|
||||||
|
INSERT INTO task_retrievals (id, task_id, memory_id, similarity)
|
||||||
|
VALUES (?1, ?2, ?3, ?4)
|
||||||
|
ON CONFLICT (task_id, memory_id) DO UPDATE SET
|
||||||
|
similarity = excluded.similarity
|
||||||
|
`
|
||||||
|
|
||||||
|
type StoreTaskRetrievalParams struct {
|
||||||
|
ID ids.UUID `db:"id" json:"id"`
|
||||||
|
TaskID ids.UUID `db:"task_id" json:"task_id"`
|
||||||
|
MemoryID ids.UUID `db:"memory_id" json:"memory_id"`
|
||||||
|
Similarity float64 `db:"similarity" json:"similarity"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store a memory retrieval record for a task
|
||||||
|
//
|
||||||
|
// INSERT INTO task_retrievals (id, task_id, memory_id, similarity)
|
||||||
|
// VALUES (?1, ?2, ?3, ?4)
|
||||||
|
// ON CONFLICT (task_id, memory_id) DO UPDATE SET
|
||||||
|
// similarity = excluded.similarity
|
||||||
|
func (q *Queries) StoreTaskRetrieval(ctx context.Context, arg StoreTaskRetrievalParams) error {
|
||||||
|
_, err := q.db.ExecContext(ctx, StoreTaskRetrieval,
|
||||||
|
arg.ID,
|
||||||
|
arg.TaskID,
|
||||||
|
arg.MemoryID,
|
||||||
|
arg.Similarity,
|
||||||
|
)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
const UpdateMemorySelfReportScore = `-- name: UpdateMemorySelfReportScore :exec
|
||||||
|
UPDATE recall_items
|
||||||
|
SET self_report_score = ?1,
|
||||||
|
updated_at = datetime('now')
|
||||||
|
WHERE id = ?2
|
||||||
|
AND agent_id = ?3
|
||||||
|
`
|
||||||
|
|
||||||
|
type UpdateMemorySelfReportScoreParams struct {
|
||||||
|
SelfReportScore *int64 `db:"self_report_score" json:"self_report_score"`
|
||||||
|
ID ids.UUID `db:"id" json:"id"`
|
||||||
|
AgentID string `db:"agent_id" json:"agent_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the self-reported score for a memory item
|
||||||
|
//
|
||||||
|
// UPDATE recall_items
|
||||||
|
// SET self_report_score = ?1,
|
||||||
|
// updated_at = datetime('now')
|
||||||
|
// WHERE id = ?2
|
||||||
|
// AND agent_id = ?3
|
||||||
|
func (q *Queries) UpdateMemorySelfReportScore(ctx context.Context, arg UpdateMemorySelfReportScoreParams) error {
|
||||||
|
_, err := q.db.ExecContext(ctx, UpdateMemorySelfReportScore, arg.SelfReportScore, arg.ID, arg.AgentID)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
const UpdateMemoryWeight = `-- name: UpdateMemoryWeight :exec
|
||||||
|
UPDATE recall_items
|
||||||
|
SET rl_weight = ?1,
|
||||||
|
rl_credit = ?2,
|
||||||
|
updated_at = datetime('now')
|
||||||
|
WHERE id = ?3
|
||||||
|
AND agent_id = ?4
|
||||||
|
`
|
||||||
|
|
||||||
|
type UpdateMemoryWeightParams struct {
|
||||||
|
RlWeight *float64 `db:"rl_weight" json:"rl_weight"`
|
||||||
|
RlCredit *float64 `db:"rl_credit" json:"rl_credit"`
|
||||||
|
ID ids.UUID `db:"id" json:"id"`
|
||||||
|
AgentID string `db:"agent_id" json:"agent_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the RL weight and credit for a specific memory item
|
||||||
|
//
|
||||||
|
// UPDATE recall_items
|
||||||
|
// SET rl_weight = ?1,
|
||||||
|
// rl_credit = ?2,
|
||||||
|
// updated_at = datetime('now')
|
||||||
|
// WHERE id = ?3
|
||||||
|
// AND agent_id = ?4
|
||||||
|
func (q *Queries) UpdateMemoryWeight(ctx context.Context, arg UpdateMemoryWeightParams) error {
|
||||||
|
_, err := q.db.ExecContext(ctx, UpdateMemoryWeight,
|
||||||
|
arg.RlWeight,
|
||||||
|
arg.RlCredit,
|
||||||
|
arg.ID,
|
||||||
|
arg.AgentID,
|
||||||
|
)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
const UpdateTaskBaseline = `-- name: UpdateTaskBaseline :exec
|
||||||
|
INSERT INTO task_baselines (
|
||||||
|
agent_id,
|
||||||
|
count,
|
||||||
|
mean_tokens,
|
||||||
|
mean_errors,
|
||||||
|
mean_user_corrections,
|
||||||
|
m2_tokens,
|
||||||
|
m2_errors,
|
||||||
|
m2_user_corrections,
|
||||||
|
updated_at
|
||||||
|
)
|
||||||
|
VALUES (
|
||||||
|
?1,
|
||||||
|
?2,
|
||||||
|
?3,
|
||||||
|
?4,
|
||||||
|
?5,
|
||||||
|
?6,
|
||||||
|
?7,
|
||||||
|
?8,
|
||||||
|
datetime('now')
|
||||||
|
)
|
||||||
|
ON CONFLICT (agent_id) DO
|
||||||
|
UPDATE
|
||||||
|
SET count = excluded.count,
|
||||||
|
mean_tokens = excluded.mean_tokens,
|
||||||
|
mean_errors = excluded.mean_errors,
|
||||||
|
mean_user_corrections = excluded.mean_user_corrections,
|
||||||
|
m2_tokens = excluded.m2_tokens,
|
||||||
|
m2_errors = excluded.m2_errors,
|
||||||
|
m2_user_corrections = excluded.m2_user_corrections,
|
||||||
|
updated_at = excluded.updated_at
|
||||||
|
`
|
||||||
|
|
||||||
|
type UpdateTaskBaselineParams struct {
|
||||||
|
AgentID string `db:"agent_id" json:"agent_id"`
|
||||||
|
Count *int64 `db:"count" json:"count"`
|
||||||
|
MeanTokens *int64 `db:"mean_tokens" json:"mean_tokens"`
|
||||||
|
MeanErrors *float64 `db:"mean_errors" json:"mean_errors"`
|
||||||
|
MeanUserCorrections *float64 `db:"mean_user_corrections" json:"mean_user_corrections"`
|
||||||
|
M2Tokens *float64 `db:"m2_tokens" json:"m2_tokens"`
|
||||||
|
M2Errors *float64 `db:"m2_errors" json:"m2_errors"`
|
||||||
|
M2UserCorrections *float64 `db:"m2_user_corrections" json:"m2_user_corrections"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert or replace task baseline statistics for an agent
|
||||||
|
//
|
||||||
|
// INSERT INTO task_baselines (
|
||||||
|
// agent_id,
|
||||||
|
// count,
|
||||||
|
// mean_tokens,
|
||||||
|
// mean_errors,
|
||||||
|
// mean_user_corrections,
|
||||||
|
// m2_tokens,
|
||||||
|
// m2_errors,
|
||||||
|
// m2_user_corrections,
|
||||||
|
// updated_at
|
||||||
|
// )
|
||||||
|
// VALUES (
|
||||||
|
// ?1,
|
||||||
|
// ?2,
|
||||||
|
// ?3,
|
||||||
|
// ?4,
|
||||||
|
// ?5,
|
||||||
|
// ?6,
|
||||||
|
// ?7,
|
||||||
|
// ?8,
|
||||||
|
// datetime('now')
|
||||||
|
// )
|
||||||
|
// ON CONFLICT (agent_id) DO
|
||||||
|
// UPDATE
|
||||||
|
// SET count = excluded.count,
|
||||||
|
// mean_tokens = excluded.mean_tokens,
|
||||||
|
// mean_errors = excluded.mean_errors,
|
||||||
|
// mean_user_corrections = excluded.mean_user_corrections,
|
||||||
|
// m2_tokens = excluded.m2_tokens,
|
||||||
|
// m2_errors = excluded.m2_errors,
|
||||||
|
// m2_user_corrections = excluded.m2_user_corrections,
|
||||||
|
// updated_at = excluded.updated_at
|
||||||
|
func (q *Queries) UpdateTaskBaseline(ctx context.Context, arg UpdateTaskBaselineParams) error {
|
||||||
|
_, err := q.db.ExecContext(ctx, UpdateTaskBaseline,
|
||||||
|
arg.AgentID,
|
||||||
|
arg.Count,
|
||||||
|
arg.MeanTokens,
|
||||||
|
arg.MeanErrors,
|
||||||
|
arg.MeanUserCorrections,
|
||||||
|
arg.M2Tokens,
|
||||||
|
arg.M2Errors,
|
||||||
|
arg.M2UserCorrections,
|
||||||
|
)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
@ -26,7 +26,13 @@ CREATE TABLE IF NOT EXISTS recall_items (
|
||||||
content TEXT NOT NULL,
|
content TEXT NOT NULL,
|
||||||
tags TEXT NOT NULL DEFAULT '',
|
tags TEXT NOT NULL DEFAULT '',
|
||||||
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
|
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
suppressed_at DATETIME, -- soft delete timestamp (T2.4)
|
||||||
|
-- RL (Memelord) support columns
|
||||||
|
rl_weight REAL DEFAULT 1.0, -- current weight for credit assignment
|
||||||
|
rl_credit REAL, -- accumulated credit for this memory
|
||||||
|
self_report_score INTEGER, -- self-reported usefulness score
|
||||||
|
task_retrieval_count INTEGER DEFAULT 0 -- how many times retrieved for tasks
|
||||||
);
|
);
|
||||||
CREATE INDEX IF NOT EXISTS idx_recall_agent_session ON recall_items(agent_id, session_key);
|
CREATE INDEX IF NOT EXISTS idx_recall_agent_session ON recall_items(agent_id, session_key);
|
||||||
CREATE INDEX IF NOT EXISTS idx_recall_sector ON recall_items(sector);
|
CREATE INDEX IF NOT EXISTS idx_recall_sector ON recall_items(sector);
|
||||||
|
|
@ -44,7 +50,8 @@ CREATE TABLE IF NOT EXISTS archival_chunks (
|
||||||
embedding BLOB,
|
embedding BLOB,
|
||||||
source TEXT NOT NULL DEFAULT '',
|
source TEXT NOT NULL DEFAULT '',
|
||||||
hash TEXT NOT NULL DEFAULT '',
|
hash TEXT NOT NULL DEFAULT '',
|
||||||
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
|
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
suppressed_at DATETIME -- soft delete timestamp (T2.4)
|
||||||
);
|
);
|
||||||
CREATE INDEX IF NOT EXISTS idx_chunks_recall ON archival_chunks(recall_id);
|
CREATE INDEX IF NOT EXISTS idx_chunks_recall ON archival_chunks(recall_id);
|
||||||
CREATE INDEX IF NOT EXISTS idx_chunks_source ON archival_chunks(source);
|
CREATE INDEX IF NOT EXISTS idx_chunks_source ON archival_chunks(source);
|
||||||
|
|
@ -385,3 +392,78 @@ CREATE TABLE IF NOT EXISTS dag_edges (
|
||||||
CREATE INDEX IF NOT EXISTS idx_dag_edges_snapshot ON dag_edges(snapshot_id);
|
CREATE INDEX IF NOT EXISTS idx_dag_edges_snapshot ON dag_edges(snapshot_id);
|
||||||
CREATE INDEX IF NOT EXISTS idx_dag_edges_parent ON dag_edges(parent_node_id);
|
CREATE INDEX IF NOT EXISTS idx_dag_edges_parent ON dag_edges(parent_node_id);
|
||||||
CREATE INDEX IF NOT EXISTS idx_dag_edges_child ON dag_edges(child_node_id);
|
CREATE INDEX IF NOT EXISTS idx_dag_edges_child ON dag_edges(child_node_id);
|
||||||
|
-- ============================================================================
|
||||||
|
-- Immutable Message Store (LCM ADR-001)
|
||||||
|
-- ============================================================================
|
||||||
|
-- Append-only verbatim record of every message. Never modified or deleted.
|
||||||
|
CREATE TABLE IF NOT EXISTS immutable_messages (
|
||||||
|
id BLOB PRIMARY KEY,
|
||||||
|
session_key TEXT NOT NULL,
|
||||||
|
role TEXT NOT NULL,
|
||||||
|
content TEXT NOT NULL,
|
||||||
|
tool_call_id TEXT NOT NULL DEFAULT '',
|
||||||
|
tool_calls TEXT NOT NULL DEFAULT '',
|
||||||
|
token_estimate INTEGER NOT NULL DEFAULT 0,
|
||||||
|
created_at DATETIME NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now'))
|
||||||
|
);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_immutable_session_created ON immutable_messages(session_key, created_at);
|
||||||
|
-- ============================================================================
|
||||||
|
-- Memory Graph Edges (ADR-004)
|
||||||
|
-- ============================================================================
|
||||||
|
-- Typed, weighted relationships between memory items.
|
||||||
|
CREATE TABLE IF NOT EXISTS memory_edges (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
from_id BLOB NOT NULL,
|
||||||
|
to_id BLOB NOT NULL,
|
||||||
|
edge_type TEXT NOT NULL DEFAULT 'related_to',
|
||||||
|
weight REAL NOT NULL DEFAULT 1.0,
|
||||||
|
created_at DATETIME NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now'))
|
||||||
|
);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_memory_edges_from ON memory_edges(from_id);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_memory_edges_to ON memory_edges(to_id);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_memory_edges_type ON memory_edges(edge_type);
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
-- RL (Reinforcement Learning) Support Tables
|
||||||
|
-- ============================================================================
|
||||||
|
-- Task baselines: per-agent performance statistics for RL credit assignment
|
||||||
|
CREATE TABLE IF NOT EXISTS task_baselines (
|
||||||
|
agent_id TEXT PRIMARY KEY,
|
||||||
|
count INTEGER DEFAULT 0,
|
||||||
|
mean_tokens INTEGER DEFAULT 0,
|
||||||
|
mean_errors REAL DEFAULT 0,
|
||||||
|
mean_user_corrections REAL DEFAULT 0,
|
||||||
|
m2_tokens REAL DEFAULT 0,
|
||||||
|
m2_errors REAL DEFAULT 0,
|
||||||
|
m2_user_corrections REAL DEFAULT 0,
|
||||||
|
updated_at DATETIME
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Task completions: record of completed agent runs for RL analysis
|
||||||
|
CREATE TABLE IF NOT EXISTS task_completions (
|
||||||
|
id BLOB PRIMARY KEY,
|
||||||
|
agent_id TEXT NOT NULL,
|
||||||
|
conversation_id BLOB NOT NULL REFERENCES agent_conversations(id) ON DELETE CASCADE,
|
||||||
|
run_id BLOB NOT NULL REFERENCES agent_runs(id) ON DELETE CASCADE,
|
||||||
|
description TEXT NOT NULL DEFAULT '',
|
||||||
|
tokens_used INTEGER DEFAULT 0,
|
||||||
|
tool_calls INTEGER DEFAULT 0,
|
||||||
|
errors INTEGER DEFAULT 0,
|
||||||
|
user_corrections INTEGER DEFAULT 0,
|
||||||
|
completed BOOLEAN NOT NULL DEFAULT 0,
|
||||||
|
created_at DATETIME NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now'))
|
||||||
|
);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_task_completions_agent_created ON task_completions(agent_id, created_at);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_task_completions_run ON task_completions(run_id);
|
||||||
|
|
||||||
|
-- Task retrievals: links memories retrieved during task execution for RL credit assignment
|
||||||
|
CREATE TABLE IF NOT EXISTS task_retrievals (
|
||||||
|
id BLOB PRIMARY KEY,
|
||||||
|
task_id BLOB NOT NULL REFERENCES task_completions(id) ON DELETE CASCADE,
|
||||||
|
memory_id BLOB NOT NULL REFERENCES recall_items(id) ON DELETE CASCADE,
|
||||||
|
similarity REAL NOT NULL DEFAULT 0,
|
||||||
|
created_at DATETIME NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
|
||||||
|
UNIQUE(task_id, memory_id)
|
||||||
|
);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_task_retrievals_task ON task_retrievals(task_id);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_task_retrievals_memory ON task_retrievals(memory_id);
|
||||||
310
pkg/memory/sqlc/soft_delete.sql.go
Normal file
310
pkg/memory/sqlc/soft_delete.sql.go
Normal file
|
|
@ -0,0 +1,310 @@
|
||||||
|
// Code generated by sqlc. DO NOT EDIT.
|
||||||
|
// versions:
|
||||||
|
// sqlc v1.30.0
|
||||||
|
// source: soft_delete.sql
|
||||||
|
|
||||||
|
package sqlc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/ZanzyTHEbar/dragonscale/pkg/ids"
|
||||||
|
"github.com/ZanzyTHEbar/dragonscale/pkg/memory"
|
||||||
|
)
|
||||||
|
|
||||||
|
const HardDeleteArchivalChunks = `-- name: HardDeleteArchivalChunks :exec
|
||||||
|
DELETE FROM archival_chunks
|
||||||
|
WHERE recall_id = ?1
|
||||||
|
`
|
||||||
|
|
||||||
|
type HardDeleteArchivalChunksParams struct {
|
||||||
|
RecallID ids.UUID `db:"recall_id" json:"recall_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Permanently deletes archival chunks for a recall item.
|
||||||
|
//
|
||||||
|
// DELETE FROM archival_chunks
|
||||||
|
// WHERE recall_id = ?1
|
||||||
|
func (q *Queries) HardDeleteArchivalChunks(ctx context.Context, arg HardDeleteArchivalChunksParams) error {
|
||||||
|
_, err := q.db.ExecContext(ctx, HardDeleteArchivalChunks, arg.RecallID)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
const HardDeleteChunk = `-- name: HardDeleteChunk :exec
|
||||||
|
DELETE FROM archival_chunks
|
||||||
|
WHERE id = ?1
|
||||||
|
`
|
||||||
|
|
||||||
|
type HardDeleteChunkParams struct {
|
||||||
|
ID ids.UUID `db:"id" json:"id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Permanently deletes a single archival chunk by ID.
|
||||||
|
//
|
||||||
|
// DELETE FROM archival_chunks
|
||||||
|
// WHERE id = ?1
|
||||||
|
func (q *Queries) HardDeleteChunk(ctx context.Context, arg HardDeleteChunkParams) error {
|
||||||
|
_, err := q.db.ExecContext(ctx, HardDeleteChunk, arg.ID)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
const HardDeleteRecallItem = `-- name: HardDeleteRecallItem :exec
|
||||||
|
DELETE FROM recall_items
|
||||||
|
WHERE id = ?1
|
||||||
|
AND agent_id = ?2
|
||||||
|
`
|
||||||
|
|
||||||
|
type HardDeleteRecallItemParams struct {
|
||||||
|
ID ids.UUID `db:"id" json:"id"`
|
||||||
|
AgentID string `db:"agent_id" json:"agent_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Permanently deletes a recall item (after quarantine period).
|
||||||
|
//
|
||||||
|
// DELETE FROM recall_items
|
||||||
|
// WHERE id = ?1
|
||||||
|
// AND agent_id = ?2
|
||||||
|
func (q *Queries) HardDeleteRecallItem(ctx context.Context, arg HardDeleteRecallItemParams) error {
|
||||||
|
_, err := q.db.ExecContext(ctx, HardDeleteRecallItem, arg.ID, arg.AgentID)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
const ListQuarantinedArchivalChunks = `-- name: ListQuarantinedArchivalChunks :many
|
||||||
|
SELECT id,
|
||||||
|
recall_id,
|
||||||
|
chunk_index,
|
||||||
|
content,
|
||||||
|
embedding,
|
||||||
|
source,
|
||||||
|
hash,
|
||||||
|
created_at,
|
||||||
|
suppressed_at
|
||||||
|
FROM archival_chunks
|
||||||
|
WHERE suppressed_at IS NOT NULL
|
||||||
|
AND suppressed_at < ?1
|
||||||
|
ORDER BY suppressed_at ASC
|
||||||
|
LIMIT ?2
|
||||||
|
`
|
||||||
|
|
||||||
|
type ListQuarantinedArchivalChunksParams struct {
|
||||||
|
BeforeDate *time.Time `db:"before_date" json:"before_date"`
|
||||||
|
Lim int64 `db:"lim" json:"lim"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns archival chunks that have been soft-deleted and are
|
||||||
|
// eligible for permanent deletion.
|
||||||
|
//
|
||||||
|
// SELECT id,
|
||||||
|
// recall_id,
|
||||||
|
// chunk_index,
|
||||||
|
// content,
|
||||||
|
// embedding,
|
||||||
|
// source,
|
||||||
|
// hash,
|
||||||
|
// created_at,
|
||||||
|
// suppressed_at
|
||||||
|
// FROM archival_chunks
|
||||||
|
// WHERE suppressed_at IS NOT NULL
|
||||||
|
// AND suppressed_at < ?1
|
||||||
|
// ORDER BY suppressed_at ASC
|
||||||
|
// LIMIT ?2
|
||||||
|
func (q *Queries) ListQuarantinedArchivalChunks(ctx context.Context, arg ListQuarantinedArchivalChunksParams) ([]ArchivalChunk, error) {
|
||||||
|
rows, err := q.db.QueryContext(ctx, ListQuarantinedArchivalChunks, arg.BeforeDate, arg.Lim)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
items := []ArchivalChunk{}
|
||||||
|
for rows.Next() {
|
||||||
|
var i ArchivalChunk
|
||||||
|
if err := rows.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.RecallID,
|
||||||
|
&i.ChunkIndex,
|
||||||
|
&i.Content,
|
||||||
|
&i.Embedding,
|
||||||
|
&i.Source,
|
||||||
|
&i.Hash,
|
||||||
|
&i.CreatedAt,
|
||||||
|
&i.SuppressedAt,
|
||||||
|
); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
items = append(items, i)
|
||||||
|
}
|
||||||
|
if err := rows.Close(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := rows.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return items, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
const ListQuarantinedRecallItems = `-- name: ListQuarantinedRecallItems :many
|
||||||
|
SELECT id,
|
||||||
|
agent_id,
|
||||||
|
session_key,
|
||||||
|
role,
|
||||||
|
sector,
|
||||||
|
importance,
|
||||||
|
salience,
|
||||||
|
decay_rate,
|
||||||
|
content,
|
||||||
|
tags,
|
||||||
|
created_at,
|
||||||
|
updated_at,
|
||||||
|
suppressed_at
|
||||||
|
FROM recall_items
|
||||||
|
WHERE suppressed_at IS NOT NULL
|
||||||
|
AND suppressed_at < ?1
|
||||||
|
ORDER BY suppressed_at ASC
|
||||||
|
LIMIT ?2
|
||||||
|
`
|
||||||
|
|
||||||
|
type ListQuarantinedRecallItemsParams struct {
|
||||||
|
BeforeDate *time.Time `db:"before_date" json:"before_date"`
|
||||||
|
Lim int64 `db:"lim" json:"lim"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ListQuarantinedRecallItemsRow struct {
|
||||||
|
ID ids.UUID `db:"id" json:"id"`
|
||||||
|
AgentID string `db:"agent_id" json:"agent_id"`
|
||||||
|
SessionKey string `db:"session_key" json:"session_key"`
|
||||||
|
Role string `db:"role" json:"role"`
|
||||||
|
Sector memory.Sector `db:"sector" json:"sector"`
|
||||||
|
Importance float64 `db:"importance" json:"importance"`
|
||||||
|
Salience float64 `db:"salience" json:"salience"`
|
||||||
|
DecayRate float64 `db:"decay_rate" json:"decay_rate"`
|
||||||
|
Content string `db:"content" json:"content"`
|
||||||
|
Tags string `db:"tags" json:"tags"`
|
||||||
|
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
||||||
|
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
|
||||||
|
SuppressedAt *time.Time `db:"suppressed_at" json:"suppressed_at"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns recall items that have been soft-deleted (suppressed) and are
|
||||||
|
// eligible for permanent deletion (older than quarantine period).
|
||||||
|
//
|
||||||
|
// SELECT id,
|
||||||
|
// agent_id,
|
||||||
|
// session_key,
|
||||||
|
// role,
|
||||||
|
// sector,
|
||||||
|
// importance,
|
||||||
|
// salience,
|
||||||
|
// decay_rate,
|
||||||
|
// content,
|
||||||
|
// tags,
|
||||||
|
// created_at,
|
||||||
|
// updated_at,
|
||||||
|
// suppressed_at
|
||||||
|
// FROM recall_items
|
||||||
|
// WHERE suppressed_at IS NOT NULL
|
||||||
|
// AND suppressed_at < ?1
|
||||||
|
// ORDER BY suppressed_at ASC
|
||||||
|
// LIMIT ?2
|
||||||
|
func (q *Queries) ListQuarantinedRecallItems(ctx context.Context, arg ListQuarantinedRecallItemsParams) ([]ListQuarantinedRecallItemsRow, error) {
|
||||||
|
rows, err := q.db.QueryContext(ctx, ListQuarantinedRecallItems, arg.BeforeDate, arg.Lim)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
items := []ListQuarantinedRecallItemsRow{}
|
||||||
|
for rows.Next() {
|
||||||
|
var i ListQuarantinedRecallItemsRow
|
||||||
|
if err := rows.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.AgentID,
|
||||||
|
&i.SessionKey,
|
||||||
|
&i.Role,
|
||||||
|
&i.Sector,
|
||||||
|
&i.Importance,
|
||||||
|
&i.Salience,
|
||||||
|
&i.DecayRate,
|
||||||
|
&i.Content,
|
||||||
|
&i.Tags,
|
||||||
|
&i.CreatedAt,
|
||||||
|
&i.UpdatedAt,
|
||||||
|
&i.SuppressedAt,
|
||||||
|
); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
items = append(items, i)
|
||||||
|
}
|
||||||
|
if err := rows.Close(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := rows.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return items, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
const RestoreRecallItem = `-- name: RestoreRecallItem :exec
|
||||||
|
UPDATE recall_items
|
||||||
|
SET suppressed_at = NULL
|
||||||
|
WHERE id = ?1
|
||||||
|
AND agent_id = ?2
|
||||||
|
`
|
||||||
|
|
||||||
|
type RestoreRecallItemParams struct {
|
||||||
|
ID ids.UUID `db:"id" json:"id"`
|
||||||
|
AgentID string `db:"agent_id" json:"agent_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Restores a soft-deleted recall item by clearing suppressed_at.
|
||||||
|
//
|
||||||
|
// UPDATE recall_items
|
||||||
|
// SET suppressed_at = NULL
|
||||||
|
// WHERE id = ?1
|
||||||
|
// AND agent_id = ?2
|
||||||
|
func (q *Queries) RestoreRecallItem(ctx context.Context, arg RestoreRecallItemParams) error {
|
||||||
|
_, err := q.db.ExecContext(ctx, RestoreRecallItem, arg.ID, arg.AgentID)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
const SoftDeleteArchivalChunks = `-- name: SoftDeleteArchivalChunks :exec
|
||||||
|
UPDATE archival_chunks
|
||||||
|
SET suppressed_at = datetime('now')
|
||||||
|
WHERE recall_id = ?1
|
||||||
|
`
|
||||||
|
|
||||||
|
type SoftDeleteArchivalChunksParams struct {
|
||||||
|
RecallID ids.UUID `db:"recall_id" json:"recall_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sets suppressed_at for all chunks belonging to a recall item.
|
||||||
|
//
|
||||||
|
// UPDATE archival_chunks
|
||||||
|
// SET suppressed_at = datetime('now')
|
||||||
|
// WHERE recall_id = ?1
|
||||||
|
func (q *Queries) SoftDeleteArchivalChunks(ctx context.Context, arg SoftDeleteArchivalChunksParams) error {
|
||||||
|
_, err := q.db.ExecContext(ctx, SoftDeleteArchivalChunks, arg.RecallID)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
const SoftDeleteRecallItem = `-- name: SoftDeleteRecallItem :exec
|
||||||
|
UPDATE recall_items
|
||||||
|
SET suppressed_at = datetime('now')
|
||||||
|
WHERE id = ?1
|
||||||
|
AND agent_id = ?2
|
||||||
|
`
|
||||||
|
|
||||||
|
type SoftDeleteRecallItemParams struct {
|
||||||
|
ID ids.UUID `db:"id" json:"id"`
|
||||||
|
AgentID string `db:"agent_id" json:"agent_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Soft delete queries (T2.4: quarantine before permanent deletion)
|
||||||
|
// Sets suppressed_at for a recall item instead of permanently deleting it.
|
||||||
|
//
|
||||||
|
// UPDATE recall_items
|
||||||
|
// SET suppressed_at = datetime('now')
|
||||||
|
// WHERE id = ?1
|
||||||
|
// AND agent_id = ?2
|
||||||
|
func (q *Queries) SoftDeleteRecallItem(ctx context.Context, arg SoftDeleteRecallItemParams) error {
|
||||||
|
_, err := q.db.ExecContext(ctx, SoftDeleteRecallItem, arg.ID, arg.AgentID)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
@ -208,6 +208,46 @@ sql:
|
||||||
go_type:
|
go_type:
|
||||||
import: "github.com/ZanzyTHEbar/dragonscale/pkg/ids"
|
import: "github.com/ZanzyTHEbar/dragonscale/pkg/ids"
|
||||||
type: "UUID"
|
type: "UUID"
|
||||||
|
# Immutable messages
|
||||||
|
- column: "immutable_messages.id"
|
||||||
|
go_type:
|
||||||
|
import: "github.com/ZanzyTHEbar/dragonscale/pkg/ids"
|
||||||
|
type: "UUID"
|
||||||
|
# Memory edges — from_id/to_id reference recall_items
|
||||||
|
- column: "memory_edges.from_id"
|
||||||
|
go_type:
|
||||||
|
import: "github.com/ZanzyTHEbar/dragonscale/pkg/ids"
|
||||||
|
type: "UUID"
|
||||||
|
- column: "memory_edges.to_id"
|
||||||
|
go_type:
|
||||||
|
import: "github.com/ZanzyTHEbar/dragonscale/pkg/ids"
|
||||||
|
type: "UUID"
|
||||||
|
# Task completions
|
||||||
|
- column: "task_completions.id"
|
||||||
|
go_type:
|
||||||
|
import: "github.com/ZanzyTHEbar/dragonscale/pkg/ids"
|
||||||
|
type: "UUID"
|
||||||
|
- column: "task_completions.conversation_id"
|
||||||
|
go_type:
|
||||||
|
import: "github.com/ZanzyTHEbar/dragonscale/pkg/ids"
|
||||||
|
type: "UUID"
|
||||||
|
- column: "task_completions.run_id"
|
||||||
|
go_type:
|
||||||
|
import: "github.com/ZanzyTHEbar/dragonscale/pkg/ids"
|
||||||
|
type: "UUID"
|
||||||
|
# Task retrievals
|
||||||
|
- column: "task_retrievals.id"
|
||||||
|
go_type:
|
||||||
|
import: "github.com/ZanzyTHEbar/dragonscale/pkg/ids"
|
||||||
|
type: "UUID"
|
||||||
|
- column: "task_retrievals.task_id"
|
||||||
|
go_type:
|
||||||
|
import: "github.com/ZanzyTHEbar/dragonscale/pkg/ids"
|
||||||
|
type: "UUID"
|
||||||
|
- column: "task_retrievals.memory_id"
|
||||||
|
go_type:
|
||||||
|
import: "github.com/ZanzyTHEbar/dragonscale/pkg/ids"
|
||||||
|
type: "UUID"
|
||||||
# DAG
|
# DAG
|
||||||
- column: "dag_snapshots.id"
|
- column: "dag_snapshots.id"
|
||||||
go_type:
|
go_type:
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue