feat(memory): add migrations for immutable messages, edges, soft delete, RL schema
This commit is contained in:
parent
3ce3faed42
commit
89c8f17aa9
4 changed files with 213 additions and 0 deletions
50
pkg/memory/migrations/013_immutable_messages.go
Normal file
50
pkg/memory/migrations/013_immutable_messages.go
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
package migrations
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
|
||||
"github.com/pressly/goose/v3"
|
||||
)
|
||||
|
||||
func init() {
|
||||
goose.AddMigrationContext(up013ImmutableMessages, down013ImmutableMessages)
|
||||
}
|
||||
|
||||
func up013ImmutableMessages(ctx context.Context, tx *sql.Tx) error {
|
||||
stmts := []string{
|
||||
`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)`,
|
||||
`CREATE INDEX IF NOT EXISTS idx_immutable_token_estimate ON immutable_messages(token_estimate)`,
|
||||
}
|
||||
for _, s := range stmts {
|
||||
if _, err := tx.ExecContext(ctx, s); err != nil {
|
||||
return fmt.Errorf("013_immutable_messages up: %w\nSQL: %s", err, s)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func down013ImmutableMessages(ctx context.Context, tx *sql.Tx) error {
|
||||
stmts := []string{
|
||||
`DROP INDEX IF EXISTS idx_immutable_token_estimate`,
|
||||
`DROP INDEX IF EXISTS idx_immutable_session_created`,
|
||||
`DROP TABLE IF EXISTS immutable_messages`,
|
||||
}
|
||||
for _, s := range stmts {
|
||||
if _, err := tx.ExecContext(ctx, s); err != nil {
|
||||
return fmt.Errorf("013_immutable_messages down: %w\nSQL: %s", err, s)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
52
pkg/memory/migrations/014_memory_edges.go
Normal file
52
pkg/memory/migrations/014_memory_edges.go
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
package migrations
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
|
||||
"github.com/pressly/goose/v3"
|
||||
)
|
||||
|
||||
func init() {
|
||||
goose.AddMigrationContext(up014MemoryEdges, down014MemoryEdges)
|
||||
}
|
||||
|
||||
func up014MemoryEdges(ctx context.Context, tx *sql.Tx) error {
|
||||
stmts := []string{
|
||||
`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)`,
|
||||
`CREATE UNIQUE INDEX IF NOT EXISTS idx_memory_edges_pair ON memory_edges(from_id, to_id)`,
|
||||
}
|
||||
for _, s := range stmts {
|
||||
if _, err := tx.ExecContext(ctx, s); err != nil {
|
||||
return fmt.Errorf("014_memory_edges up: %w\nSQL: %s", err, s)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func down014MemoryEdges(ctx context.Context, tx *sql.Tx) error {
|
||||
stmts := []string{
|
||||
`DROP INDEX IF EXISTS idx_memory_edges_pair`,
|
||||
`DROP INDEX IF EXISTS idx_memory_edges_type`,
|
||||
`DROP INDEX IF EXISTS idx_memory_edges_to`,
|
||||
`DROP INDEX IF EXISTS idx_memory_edges_from`,
|
||||
`DROP TABLE IF EXISTS memory_edges`,
|
||||
}
|
||||
for _, s := range stmts {
|
||||
if _, err := tx.ExecContext(ctx, s); err != nil {
|
||||
return fmt.Errorf("014_memory_edges down: %w\nSQL: %s", err, s)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
46
pkg/memory/migrations/015_soft_delete.go
Normal file
46
pkg/memory/migrations/015_soft_delete.go
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
package migrations
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
|
||||
"github.com/pressly/goose/v3"
|
||||
)
|
||||
|
||||
func init() {
|
||||
goose.AddMigrationContext(up015SoftDelete, down015SoftDelete)
|
||||
}
|
||||
|
||||
func up015SoftDelete(ctx context.Context, tx *sql.Tx) error {
|
||||
stmts := []string{
|
||||
// Add suppressed_at column to recall_items for soft delete
|
||||
`ALTER TABLE recall_items ADD COLUMN suppressed_at DATETIME`,
|
||||
`CREATE INDEX IF NOT EXISTS idx_recall_suppressed ON recall_items(suppressed_at)`,
|
||||
|
||||
// Add suppressed_at column to archival_chunks for soft delete
|
||||
`ALTER TABLE archival_chunks ADD COLUMN suppressed_at DATETIME`,
|
||||
`CREATE INDEX IF NOT EXISTS idx_chunks_suppressed ON archival_chunks(suppressed_at)`,
|
||||
}
|
||||
for _, s := range stmts {
|
||||
if _, err := tx.ExecContext(ctx, s); err != nil {
|
||||
return fmt.Errorf("015_soft_delete up: %w\nSQL: %s", err, s)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func down015SoftDelete(ctx context.Context, tx *sql.Tx) error {
|
||||
stmts := []string{
|
||||
`DROP INDEX IF EXISTS idx_recall_suppressed`,
|
||||
`DROP INDEX IF EXISTS idx_chunks_suppressed`,
|
||||
// SQLite doesn't support DROP COLUMN directly; would need table recreation
|
||||
// Leaving columns as-is for safety; they are nullable and ignored by queries
|
||||
}
|
||||
for _, s := range stmts {
|
||||
if _, err := tx.ExecContext(ctx, s); err != nil {
|
||||
return fmt.Errorf("015_soft_delete down: %w\nSQL: %s", err, s)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
65
pkg/memory/migrations/016_rl_schema.go
Normal file
65
pkg/memory/migrations/016_rl_schema.go
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
package migrations
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
|
||||
"github.com/pressly/goose/v3"
|
||||
)
|
||||
|
||||
func init() {
|
||||
goose.AddMigrationContext(up016RLSchema, down016RLSchema)
|
||||
}
|
||||
|
||||
func up016RLSchema(ctx context.Context, tx *sql.Tx) error {
|
||||
stmts := []string{
|
||||
// Create task_baselines table for RL statistics per agent
|
||||
`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
|
||||
)`,
|
||||
// Add RL-related columns to recall_items
|
||||
`ALTER TABLE recall_items ADD COLUMN rl_weight REAL DEFAULT 1.0`,
|
||||
`ALTER TABLE recall_items ADD COLUMN rl_credit REAL`,
|
||||
`ALTER TABLE recall_items ADD COLUMN self_report_score INTEGER`,
|
||||
`ALTER TABLE recall_items ADD COLUMN task_retrieval_count INTEGER DEFAULT 0`,
|
||||
// Create index for RL weight lookups
|
||||
`CREATE INDEX IF NOT EXISTS idx_recall_rl_weight ON recall_items(rl_weight)`,
|
||||
// Create index for task retrieval tracking
|
||||
`CREATE INDEX IF NOT EXISTS idx_recall_task_retrieval ON recall_items(task_retrieval_count)`,
|
||||
}
|
||||
for _, s := range stmts {
|
||||
if _, err := tx.ExecContext(ctx, s); err != nil {
|
||||
return fmt.Errorf("016_rl_schema up: %w\nSQL: %s", err, s)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func down016RLSchema(ctx context.Context, tx *sql.Tx) error {
|
||||
stmts := []string{
|
||||
// Drop indexes first
|
||||
`DROP INDEX IF EXISTS idx_recall_task_retrieval`,
|
||||
`DROP INDEX IF EXISTS idx_recall_rl_weight`,
|
||||
// Drop task_baselines table
|
||||
`DROP TABLE IF EXISTS task_baselines`,
|
||||
// Note: SQLite doesn't support DROP COLUMN directly
|
||||
// The columns (rl_weight, rl_credit, self_report_score, task_retrieval_count)
|
||||
// are left in place with defaults to avoid breaking existing data.
|
||||
// They will be ignored by queries that don't reference them.
|
||||
}
|
||||
for _, s := range stmts {
|
||||
if _, err := tx.ExecContext(ctx, s); err != nil {
|
||||
return fmt.Errorf("016_rl_schema down: %w\nSQL: %s", err, s)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue