refactor(store,tools): migrate IDs from UUID to bigserial int64
Some checks failed
CI / build-and-test (push) Failing after -31m12s

All internal entity lookups now use bigserial primary keys (int64) while
GUIDs are retained for external/public identification. Updated store
functions (TouchProject, UpdateThoughtMetadata, AddThoughtAttachment) to
query by id instead of guid, added GetThoughtByID, changed semanticSearch
and all tool helpers to use *int64 project IDs, and updated retry/backfill
workers to use int64 thought IDs throughout.
This commit is contained in:
2026-05-03 11:43:34 +02:00
parent 9e6d05e055
commit 91239bcf4b
58 changed files with 1208 additions and 2774 deletions

View File

@@ -7,7 +7,6 @@ import (
"strings"
"time"
"github.com/google/uuid"
"github.com/jackc/pgx/v5"
"git.warky.dev/wdevs/amcs/internal/generatedmodels"
@@ -28,7 +27,7 @@ func (db *DB) SaveChatHistory(ctx context.Context, h ext.ChatHistory) (ext.ChatH
insert into chat_histories
(session_id, title, channel, agent_id, project_id, messages, summary, metadata)
values ($1, $2, $3, $4, $5, $6, $7, $8)
returning id, created_at, updated_at
returning id, guid, created_at, updated_at
`,
h.SessionID, nullStr(h.Title), nullStr(h.Channel), nullStr(h.AgentID),
h.ProjectID, messages, nullStr(h.Summary), meta,
@@ -36,16 +35,17 @@ func (db *DB) SaveChatHistory(ctx context.Context, h ext.ChatHistory) (ext.ChatH
created := h
var model generatedmodels.ModelPublicChatHistories
if err := row.Scan(&model.ID, &model.CreatedAt, &model.UpdatedAt); err != nil {
if err := row.Scan(&model.ID, &model.GUID, &model.CreatedAt, &model.UpdatedAt); err != nil {
return ext.ChatHistory{}, fmt.Errorf("insert chat history: %w", err)
}
created.ID = model.ID.UUID()
created.ID = model.ID.Int64()
created.GUID = model.GUID.UUID()
created.CreatedAt = model.CreatedAt.Time()
created.UpdatedAt = model.UpdatedAt.Time()
return created, nil
}
func (db *DB) GetChatHistory(ctx context.Context, id uuid.UUID) (ext.ChatHistory, bool, error) {
func (db *DB) GetChatHistory(ctx context.Context, id int64) (ext.ChatHistory, bool, error) {
row := db.pool.QueryRow(ctx, `
select id, session_id, title, channel, agent_id, project_id,
messages, summary, metadata, created_at, updated_at
@@ -81,7 +81,7 @@ func (db *DB) GetChatHistoryBySessionID(ctx context.Context, sessionID string) (
}
type ListChatHistoriesFilter struct {
ProjectID *uuid.UUID
ProjectID *int64
Channel string
AgentID string
SessionID string
@@ -149,7 +149,7 @@ func (db *DB) ListChatHistories(ctx context.Context, f ListChatHistoriesFilter)
return result, rows.Err()
}
func (db *DB) DeleteChatHistory(ctx context.Context, id uuid.UUID) (bool, error) {
func (db *DB) DeleteChatHistory(ctx context.Context, id int64) (bool, error) {
tag, err := db.pool.Exec(ctx, `delete from chat_histories where id = $1`, id)
if err != nil {
return false, fmt.Errorf("delete chat history: %w", err)
@@ -171,7 +171,8 @@ func scanChatHistory(row rowScanner) (ext.ChatHistory, error) {
}
h := ext.ChatHistory{
ID: model.ID.UUID(),
ID: model.ID.Int64(),
GUID: model.GUID.UUID(),
SessionID: model.SessionID.String(),
Title: model.Title.String(),
Channel: model.Channel.String(),
@@ -181,7 +182,7 @@ func scanChatHistory(row rowScanner) (ext.ChatHistory, error) {
UpdatedAt: model.UpdatedAt.Time(),
}
if model.ProjectID.Valid {
id := model.ProjectID.UUID()
id := model.ProjectID.Int64()
h.ProjectID = &id
}

View File

@@ -17,11 +17,12 @@ func (db *DB) InsertStoredFile(ctx context.Context, file thoughttypes.StoredFile
row := db.pool.QueryRow(ctx, `
insert into stored_files (thought_id, project_id, name, media_type, kind, encoding, size_bytes, sha256, content)
values ($1, $2, $3, $4, $5, $6, $7, $8, $9)
returning guid, thought_id, project_id, name, media_type, kind, encoding, size_bytes, sha256, created_at, updated_at
returning id, guid, thought_id, project_id, name, media_type, kind, encoding, size_bytes, sha256, created_at, updated_at
`, file.ThoughtID, file.ProjectID, file.Name, file.MediaType, file.Kind, file.Encoding, file.SizeBytes, file.SHA256, file.Content)
var model generatedmodels.ModelPublicStoredFiles
if err := row.Scan(
&model.ID,
&model.GUID,
&model.ThoughtID,
&model.ProjectID,
@@ -42,13 +43,14 @@ func (db *DB) InsertStoredFile(ctx context.Context, file thoughttypes.StoredFile
func (db *DB) GetStoredFile(ctx context.Context, id uuid.UUID) (thoughttypes.StoredFile, error) {
row := db.pool.QueryRow(ctx, `
select guid, thought_id, project_id, name, media_type, kind, encoding, size_bytes, sha256, content, created_at, updated_at
select id, guid, thought_id, project_id, name, media_type, kind, encoding, size_bytes, sha256, content, created_at, updated_at
from stored_files
where guid = $1
`, id)
var model generatedmodels.ModelPublicStoredFiles
if err := row.Scan(
&model.ID,
&model.GUID,
&model.ThoughtID,
&model.ProjectID,
@@ -89,7 +91,7 @@ func (db *DB) ListStoredFiles(ctx context.Context, filter thoughttypes.StoredFil
}
query := `
select guid, thought_id, project_id, name, media_type, kind, encoding, size_bytes, sha256, created_at, updated_at
select id, guid, thought_id, project_id, name, media_type, kind, encoding, size_bytes, sha256, created_at, updated_at
from stored_files
`
if len(conditions) > 0 {
@@ -109,6 +111,7 @@ func (db *DB) ListStoredFiles(ctx context.Context, filter thoughttypes.StoredFil
for rows.Next() {
var model generatedmodels.ModelPublicStoredFiles
if err := rows.Scan(
&model.ID,
&model.GUID,
&model.ThoughtID,
&model.ProjectID,
@@ -132,7 +135,7 @@ func (db *DB) ListStoredFiles(ctx context.Context, filter thoughttypes.StoredFil
return files, nil
}
func (db *DB) AddThoughtAttachment(ctx context.Context, thoughtID uuid.UUID, attachment thoughttypes.ThoughtAttachment) error {
func (db *DB) AddThoughtAttachment(ctx context.Context, thoughtID int64, attachment thoughttypes.ThoughtAttachment) error {
tx, err := db.pool.Begin(ctx)
if err != nil {
return fmt.Errorf("begin transaction: %w", err)
@@ -142,7 +145,7 @@ func (db *DB) AddThoughtAttachment(ctx context.Context, thoughtID uuid.UUID, att
}()
var metadataBytes []byte
if err := tx.QueryRow(ctx, `select metadata from thoughts where guid = $1 for update`, thoughtID).Scan(&metadataBytes); err != nil {
if err := tx.QueryRow(ctx, `select metadata from thoughts where id = $1 for update`, thoughtID).Scan(&metadataBytes); err != nil {
if err == pgx.ErrNoRows {
return err
}
@@ -177,7 +180,7 @@ func (db *DB) AddThoughtAttachment(ctx context.Context, thoughtID uuid.UUID, att
update thoughts
set metadata = $2::jsonb,
updated_at = now()
where guid = $1
where id = $1
`, thoughtID, updatedMetadata)
if err != nil {
return fmt.Errorf("update thought attachments: %w", err)

View File

@@ -6,7 +6,6 @@ import (
"strings"
"git.warky.dev/wdevs/amcs/internal/generatedmodels"
"github.com/google/uuid"
"github.com/jackc/pgx/v5"
thoughttypes "git.warky.dev/wdevs/amcs/internal/types"
@@ -25,7 +24,7 @@ func (db *DB) CreateLearning(ctx context.Context, learning thoughttypes.Learning
$13, $14, $15, $16,
$17, $18
)
returning id, created_at, updated_at
returning id, guid, created_at, updated_at
`,
strings.TrimSpace(learning.Summary),
strings.TrimSpace(learning.Details),
@@ -49,16 +48,17 @@ func (db *DB) CreateLearning(ctx context.Context, learning thoughttypes.Learning
created := learning
var model generatedmodels.ModelPublicLearnings
if err := row.Scan(&model.ID, &model.CreatedAt, &model.UpdatedAt); err != nil {
if err := row.Scan(&model.ID, &model.GUID, &model.CreatedAt, &model.UpdatedAt); err != nil {
return thoughttypes.Learning{}, fmt.Errorf("create learning: %w", err)
}
created.ID = model.ID.UUID()
created.ID = model.ID.Int64()
created.GUID = model.GUID.UUID()
created.CreatedAt = model.CreatedAt.Time()
created.UpdatedAt = model.UpdatedAt.Time()
return created, nil
}
func (db *DB) GetLearning(ctx context.Context, id uuid.UUID) (thoughttypes.Learning, error) {
func (db *DB) GetLearning(ctx context.Context, id int64) (thoughttypes.Learning, error) {
row := db.pool.QueryRow(ctx, `
select id, summary, details, category, area, status, priority, confidence,
action_required, source_type, source_ref, project_id, related_thought_id,
@@ -71,7 +71,7 @@ func (db *DB) GetLearning(ctx context.Context, id uuid.UUID) (thoughttypes.Learn
learning, err := scanLearning(row)
if err != nil {
if err == pgx.ErrNoRows {
return thoughttypes.Learning{}, fmt.Errorf("learning not found: %s", id)
return thoughttypes.Learning{}, fmt.Errorf("learning not found: %d", id)
}
return thoughttypes.Learning{}, fmt.Errorf("get learning: %w", err)
}

View File

@@ -25,12 +25,12 @@ func (db *DB) InsertLink(ctx context.Context, link thoughttypes.ThoughtLink) err
func (db *DB) LinkedThoughts(ctx context.Context, thoughtID uuid.UUID) ([]thoughttypes.LinkedThought, error) {
rows, err := db.pool.Query(ctx, `
select t.guid, t.content, t.metadata, t.project_id, t.archived_at, t.created_at, t.updated_at, l.relation, 'outgoing' as direction, l.created_at
select t.id, t.guid, t.content, t.metadata, t.project_id, t.archived_at, t.created_at, t.updated_at, l.relation, 'outgoing' as direction, l.created_at
from thought_links l
join thoughts t on t.id = l.to_id
where l.from_id = (select id from thoughts where guid = $1)
union all
select t.guid, t.content, t.metadata, t.project_id, t.archived_at, t.created_at, t.updated_at, l.relation, 'incoming' as direction, l.created_at
select t.id, t.guid, t.content, t.metadata, t.project_id, t.archived_at, t.created_at, t.updated_at, l.relation, 'incoming' as direction, l.created_at
from thought_links l
join thoughts t on t.id = l.from_id
where l.to_id = (select id from thoughts where guid = $1)
@@ -46,6 +46,7 @@ func (db *DB) LinkedThoughts(ctx context.Context, thoughtID uuid.UUID) ([]though
var linked thoughttypes.LinkedThought
var model generatedmodels.ModelPublicThoughts
if err := rows.Scan(
&model.ID,
&model.GUID,
&model.Content,
&model.Metadata,

View File

@@ -5,8 +5,6 @@ import (
"fmt"
"time"
"github.com/google/uuid"
"git.warky.dev/wdevs/amcs/internal/generatedmodels"
ext "git.warky.dev/wdevs/amcs/internal/types"
)
@@ -14,6 +12,7 @@ import (
func projectFromModel(m generatedmodels.ModelPublicProjects) ext.Project {
return ext.Project{
ID: m.GUID.UUID(),
NumericID: m.ID.Int64(),
Name: m.Name.String(),
Description: m.Description.String(),
CreatedAt: m.CreatedAt.Time(),
@@ -29,9 +28,9 @@ func thoughtFromModel(m generatedmodels.ModelPublicThoughts) (ext.Thought, error
}
}
var projectID *uuid.UUID
var projectID *int64
if m.ProjectID.Valid {
id := m.ProjectID.UUID()
id := m.ProjectID.Int64()
projectID = &id
}
@@ -42,7 +41,8 @@ func thoughtFromModel(m generatedmodels.ModelPublicThoughts) (ext.Thought, error
}
return ext.Thought{
ID: m.GUID.UUID(),
ID: m.ID.Int64(),
GUID: m.GUID.UUID(),
Content: m.Content.String(),
Metadata: metadata,
ProjectID: projectID,
@@ -53,20 +53,21 @@ func thoughtFromModel(m generatedmodels.ModelPublicThoughts) (ext.Thought, error
}
func storedFileFromModel(m generatedmodels.ModelPublicStoredFiles) ext.StoredFile {
var thoughtID *uuid.UUID
var thoughtID *int64
if m.ThoughtID.Valid {
id := m.ThoughtID.UUID()
id := m.ThoughtID.Int64()
thoughtID = &id
}
var projectID *uuid.UUID
var projectID *int64
if m.ProjectID.Valid {
id := m.ProjectID.UUID()
id := m.ProjectID.Int64()
projectID = &id
}
return ext.StoredFile{
ID: m.GUID.UUID(),
ID: m.ID.Int64(),
GUID: m.GUID.UUID(),
ThoughtID: thoughtID,
ProjectID: projectID,
Name: m.Name.String(),
@@ -419,9 +420,9 @@ func storedFileFromModel(m generatedmodels.ModelPublicStoredFiles) ext.StoredFil
// }
func planFromModel(m generatedmodels.ModelPublicPlans, tags []string) ext.Plan {
var projectID *uuid.UUID
var projectID *int64
if m.ProjectID.Valid {
id := m.ProjectID.UUID()
id := m.ProjectID.Int64()
projectID = &id
}
@@ -443,14 +444,15 @@ func planFromModel(m generatedmodels.ModelPublicPlans, tags []string) ext.Plan {
lastReviewedAt = &t
}
var supersedesPlanID *uuid.UUID
var supersedesPlanID *int64
if m.SupersedesPlanID.Valid {
id := m.SupersedesPlanID.UUID()
id := m.SupersedesPlanID.Int64()
supersedesPlanID = &id
}
return ext.Plan{
ID: m.ID.UUID(),
ID: m.ID.Int64(),
GUID: m.GUID.UUID(),
Title: m.Title.String(),
Description: m.Description.String(),
Status: ext.PlanStatus(m.Status.String()),
@@ -469,33 +471,33 @@ func planFromModel(m generatedmodels.ModelPublicPlans, tags []string) ext.Plan {
}
func learningFromModel(m generatedmodels.ModelPublicLearnings, tags []string) ext.Learning {
var projectID *uuid.UUID
var projectID *int64
if m.ProjectID.Valid {
id := m.ProjectID.UUID()
id := m.ProjectID.Int64()
projectID = &id
}
var relatedThoughtID *uuid.UUID
var relatedThoughtID *int64
if m.RelatedThoughtID.Valid {
id := m.RelatedThoughtID.UUID()
id := m.RelatedThoughtID.Int64()
relatedThoughtID = &id
}
var relatedSkillID *uuid.UUID
var relatedSkillID *int64
if m.RelatedSkillID.Valid {
id := m.RelatedSkillID.UUID()
id := m.RelatedSkillID.Int64()
relatedSkillID = &id
}
var duplicateOfLearningID *uuid.UUID
var duplicateOfLearningID *int64
if m.DuplicateOfLearningID.Valid {
id := m.DuplicateOfLearningID.UUID()
id := m.DuplicateOfLearningID.Int64()
duplicateOfLearningID = &id
}
var supersedesLearningID *uuid.UUID
var supersedesLearningID *int64
if m.SupersedesLearningID.Valid {
id := m.SupersedesLearningID.UUID()
id := m.SupersedesLearningID.Int64()
supersedesLearningID = &id
}
@@ -512,7 +514,8 @@ func learningFromModel(m generatedmodels.ModelPublicLearnings, tags []string) ex
}
return ext.Learning{
ID: m.ID.UUID(),
ID: m.ID.Int64(),
GUID: m.GUID.UUID(),
Summary: m.Summary.String(),
Details: m.Details.String(),
Category: m.Category.String(),

View File

@@ -4,7 +4,7 @@ import (
"context"
"fmt"
"strings"
"github.com/google/uuid"
"github.com/jackc/pgx/v5"
"git.warky.dev/wdevs/amcs/internal/generatedmodels"
@@ -12,7 +12,7 @@ import (
)
const planColumns = `
id, title, description, status, priority, project_id, owner, due_date,
id, guid, title, description, status, priority, project_id, owner, due_date,
completed_at, reviewed_by, last_reviewed_at, supersedes_plan_id, tags::text[], created_at, updated_at`
func (db *DB) CreatePlan(ctx context.Context, plan ext.Plan) (ext.Plan, error) {
@@ -37,19 +37,19 @@ func (db *DB) CreatePlan(ctx context.Context, plan ext.Plan) (ext.Plan, error) {
return scanPlan(row)
}
func (db *DB) GetPlan(ctx context.Context, id uuid.UUID) (ext.Plan, error) {
func (db *DB) GetPlan(ctx context.Context, id int64) (ext.Plan, error) {
row := db.pool.QueryRow(ctx, `select`+planColumns+` from plans where id = $1`, id)
plan, err := scanPlan(row)
if err != nil {
if err == pgx.ErrNoRows {
return ext.Plan{}, fmt.Errorf("plan not found: %s", id)
return ext.Plan{}, fmt.Errorf("plan not found: %d", id)
}
return ext.Plan{}, fmt.Errorf("get plan: %w", err)
}
return plan, nil
}
func (db *DB) GetPlanDetail(ctx context.Context, id uuid.UUID) (ext.PlanDetail, error) {
func (db *DB) GetPlanDetail(ctx context.Context, id int64) (ext.PlanDetail, error) {
plan, err := db.GetPlan(ctx, id)
if err != nil {
return ext.PlanDetail{}, err
@@ -105,7 +105,7 @@ func (db *DB) GetPlanDetail(ctx context.Context, id uuid.UUID) (ext.PlanDetail,
}, nil
}
func (db *DB) UpdatePlan(ctx context.Context, id uuid.UUID, u ext.PlanUpdate) (ext.Plan, error) {
func (db *DB) UpdatePlan(ctx context.Context, id int64, u ext.PlanUpdate) (ext.Plan, error) {
sets := []string{"updated_at = now()"}
args := []any{}
@@ -169,14 +169,14 @@ func (db *DB) UpdatePlan(ctx context.Context, id uuid.UUID, u ext.PlanUpdate) (e
plan, err := scanPlan(row)
if err != nil {
if err == pgx.ErrNoRows {
return ext.Plan{}, fmt.Errorf("plan not found: %s", id)
return ext.Plan{}, fmt.Errorf("plan not found: %d", id)
}
return ext.Plan{}, fmt.Errorf("update plan: %w", err)
}
return plan, nil
}
func (db *DB) DeletePlan(ctx context.Context, id uuid.UUID) error {
func (db *DB) DeletePlan(ctx context.Context, id int64) error {
tag, err := db.pool.Exec(ctx, `delete from plans where id = $1`, id)
if err != nil {
return fmt.Errorf("delete plan: %w", err)
@@ -232,7 +232,7 @@ func (db *DB) ListPlans(ctx context.Context, filter ext.PlanFilter) ([]ext.Plan,
// Dependencies
func (db *DB) AddPlanDependency(ctx context.Context, planID, dependsOnPlanID uuid.UUID) error {
func (db *DB) AddPlanDependency(ctx context.Context, planID, dependsOnPlanID int64) error {
_, err := db.pool.Exec(ctx, `
insert into plan_dependencies (plan_id, depends_on_plan_id)
values ($1, $2)
@@ -244,7 +244,7 @@ func (db *DB) AddPlanDependency(ctx context.Context, planID, dependsOnPlanID uui
return nil
}
func (db *DB) RemovePlanDependency(ctx context.Context, planID, dependsOnPlanID uuid.UUID) error {
func (db *DB) RemovePlanDependency(ctx context.Context, planID, dependsOnPlanID int64) error {
tag, err := db.pool.Exec(ctx, `
delete from plan_dependencies where plan_id = $1 and depends_on_plan_id = $2
`, planID, dependsOnPlanID)
@@ -259,7 +259,7 @@ func (db *DB) RemovePlanDependency(ctx context.Context, planID, dependsOnPlanID
// Related Plans
func (db *DB) AddRelatedPlan(ctx context.Context, planAID, planBID uuid.UUID) error {
func (db *DB) AddRelatedPlan(ctx context.Context, planAID, planBID int64) error {
a, b := canonicalPlanPair(planAID, planBID)
_, err := db.pool.Exec(ctx, `
insert into plan_related_plans (plan_a_id, plan_b_id)
@@ -272,7 +272,7 @@ func (db *DB) AddRelatedPlan(ctx context.Context, planAID, planBID uuid.UUID) er
return nil
}
func (db *DB) RemoveRelatedPlan(ctx context.Context, planAID, planBID uuid.UUID) error {
func (db *DB) RemoveRelatedPlan(ctx context.Context, planAID, planBID int64) error {
a, b := canonicalPlanPair(planAID, planBID)
tag, err := db.pool.Exec(ctx, `
delete from plan_related_plans where plan_a_id = $1 and plan_b_id = $2
@@ -288,7 +288,7 @@ func (db *DB) RemoveRelatedPlan(ctx context.Context, planAID, planBID uuid.UUID)
// Plan Skills
func (db *DB) AddPlanSkill(ctx context.Context, planID, skillID uuid.UUID) error {
func (db *DB) AddPlanSkill(ctx context.Context, planID, skillID int64) error {
_, err := db.pool.Exec(ctx, `
insert into plan_skills (plan_id, skill_id) values ($1, $2) on conflict do nothing
`, planID, skillID)
@@ -298,7 +298,7 @@ func (db *DB) AddPlanSkill(ctx context.Context, planID, skillID uuid.UUID) error
return nil
}
func (db *DB) RemovePlanSkill(ctx context.Context, planID, skillID uuid.UUID) error {
func (db *DB) RemovePlanSkill(ctx context.Context, planID, skillID int64) error {
tag, err := db.pool.Exec(ctx, `
delete from plan_skills where plan_id = $1 and skill_id = $2
`, planID, skillID)
@@ -311,7 +311,7 @@ func (db *DB) RemovePlanSkill(ctx context.Context, planID, skillID uuid.UUID) er
return nil
}
func (db *DB) ListPlanSkills(ctx context.Context, planID uuid.UUID) ([]ext.AgentSkill, error) {
func (db *DB) ListPlanSkills(ctx context.Context, planID int64) ([]ext.AgentSkill, error) {
rows, err := db.pool.Query(ctx, `
select s.id, s.name, s.description, s.content, s.tags::text[], s.created_at, s.updated_at
from agent_skills s
@@ -332,7 +332,7 @@ func (db *DB) ListPlanSkills(ctx context.Context, planID uuid.UUID) ([]ext.Agent
return nil, fmt.Errorf("scan plan skill: %w", err)
}
s := ext.AgentSkill{
ID: model.ID.UUID(),
ID: model.ID.Int64(),
Name: model.Name.String(),
Description: model.Description.String(),
Content: model.Content.String(),
@@ -350,7 +350,7 @@ func (db *DB) ListPlanSkills(ctx context.Context, planID uuid.UUID) ([]ext.Agent
// Plan Guardrails
func (db *DB) AddPlanGuardrail(ctx context.Context, planID, guardrailID uuid.UUID) error {
func (db *DB) AddPlanGuardrail(ctx context.Context, planID, guardrailID int64) error {
_, err := db.pool.Exec(ctx, `
insert into plan_guardrails (plan_id, guardrail_id) values ($1, $2) on conflict do nothing
`, planID, guardrailID)
@@ -360,7 +360,7 @@ func (db *DB) AddPlanGuardrail(ctx context.Context, planID, guardrailID uuid.UUI
return nil
}
func (db *DB) RemovePlanGuardrail(ctx context.Context, planID, guardrailID uuid.UUID) error {
func (db *DB) RemovePlanGuardrail(ctx context.Context, planID, guardrailID int64) error {
tag, err := db.pool.Exec(ctx, `
delete from plan_guardrails where plan_id = $1 and guardrail_id = $2
`, planID, guardrailID)
@@ -373,7 +373,7 @@ func (db *DB) RemovePlanGuardrail(ctx context.Context, planID, guardrailID uuid.
return nil
}
func (db *DB) ListPlanGuardrails(ctx context.Context, planID uuid.UUID) ([]ext.AgentGuardrail, error) {
func (db *DB) ListPlanGuardrails(ctx context.Context, planID int64) ([]ext.AgentGuardrail, error) {
rows, err := db.pool.Query(ctx, `
select g.id, g.name, g.description, g.content, g.severity, g.tags::text[], g.created_at, g.updated_at
from agent_guardrails g
@@ -394,7 +394,7 @@ func (db *DB) ListPlanGuardrails(ctx context.Context, planID uuid.UUID) ([]ext.A
return nil, fmt.Errorf("scan plan guardrail: %w", err)
}
g := ext.AgentGuardrail{
ID: model.ID.UUID(),
ID: model.ID.Int64(),
Name: model.Name.String(),
Description: model.Description.String(),
Content: model.Content.String(),
@@ -422,6 +422,7 @@ func scanPlan(row planScanner) (ext.Plan, error) {
var tags []string
err := row.Scan(
&model.ID,
&model.GUID,
&model.Title,
&model.Description,
&model.Status,
@@ -467,9 +468,9 @@ func (db *DB) listPlansByQuery(ctx context.Context, query string, args ...any) (
return plans, nil
}
// canonicalPlanPair ensures the smaller UUID is always plan_a_id to prevent duplicates.
func canonicalPlanPair(a, b uuid.UUID) (uuid.UUID, uuid.UUID) {
if strings.Compare(a.String(), b.String()) <= 0 {
// canonicalPlanPair ensures the smaller ID is always plan_a_id to prevent duplicates.
func canonicalPlanPair(a, b int64) (int64, int64) {
if a <= b {
return a, b
}
return b, a

View File

@@ -16,11 +16,11 @@ func (db *DB) CreateProject(ctx context.Context, name, description string) (thou
row := db.pool.QueryRow(ctx, `
insert into projects (name, description)
values ($1, $2)
returning guid, name, description, created_at, last_active_at
returning id, guid, name, description, created_at, last_active_at
`, name, description)
var model generatedmodels.ModelPublicProjects
if err := row.Scan(&model.GUID, &model.Name, &model.Description, &model.CreatedAt, &model.LastActiveAt); err != nil {
if err := row.Scan(&model.ID, &model.GUID, &model.Name, &model.Description, &model.CreatedAt, &model.LastActiveAt); err != nil {
return thoughttypes.Project{}, fmt.Errorf("create project: %w", err)
}
return projectFromModel(model), nil
@@ -46,7 +46,7 @@ func (db *DB) GetProject(ctx context.Context, nameOrID string) (thoughttypes.Pro
func (db *DB) getProjectByGUID(ctx context.Context, id uuid.UUID) (thoughttypes.Project, error) {
row := db.pool.QueryRow(ctx, `
select guid, name, description, created_at, last_active_at
select id, guid, name, description, created_at, last_active_at
from projects
where guid = $1
`, id)
@@ -55,7 +55,7 @@ func (db *DB) getProjectByGUID(ctx context.Context, id uuid.UUID) (thoughttypes.
func (db *DB) getProjectByName(ctx context.Context, name string) (thoughttypes.Project, error) {
row := db.pool.QueryRow(ctx, `
select guid, name, description, created_at, last_active_at
select id, guid, name, description, created_at, last_active_at
from projects
where name = $1
`, name)
@@ -64,7 +64,7 @@ func (db *DB) getProjectByName(ctx context.Context, name string) (thoughttypes.P
func scanProject(row pgx.Row) (thoughttypes.Project, error) {
var model generatedmodels.ModelPublicProjects
if err := row.Scan(&model.GUID, &model.Name, &model.Description, &model.CreatedAt, &model.LastActiveAt); err != nil {
if err := row.Scan(&model.ID, &model.GUID, &model.Name, &model.Description, &model.CreatedAt, &model.LastActiveAt); err != nil {
if err == pgx.ErrNoRows {
return thoughttypes.Project{}, err
}
@@ -75,10 +75,10 @@ func scanProject(row pgx.Row) (thoughttypes.Project, error) {
func (db *DB) ListProjects(ctx context.Context) ([]thoughttypes.ProjectSummary, error) {
rows, err := db.pool.Query(ctx, `
select p.guid, p.name, p.description, p.created_at, p.last_active_at, count(t.id) as thought_count
select p.id, p.guid, p.name, p.description, p.created_at, p.last_active_at, count(t.id) as thought_count
from projects p
left join thoughts t on t.project_id = p.guid and t.archived_at is null
group by p.guid, p.name, p.description, p.created_at, p.last_active_at
left join thoughts t on t.project_id = p.id and t.archived_at is null
group by p.id, p.guid, p.name, p.description, p.created_at, p.last_active_at
order by p.last_active_at desc, p.created_at desc
`)
if err != nil {
@@ -90,7 +90,7 @@ func (db *DB) ListProjects(ctx context.Context) ([]thoughttypes.ProjectSummary,
for rows.Next() {
var model generatedmodels.ModelPublicProjects
var thoughtCount int
if err := rows.Scan(&model.GUID, &model.Name, &model.Description, &model.CreatedAt, &model.LastActiveAt, &thoughtCount); err != nil {
if err := rows.Scan(&model.ID, &model.GUID, &model.Name, &model.Description, &model.CreatedAt, &model.LastActiveAt, &thoughtCount); err != nil {
return nil, fmt.Errorf("scan project summary: %w", err)
}
projects = append(projects, thoughttypes.ProjectSummary{
@@ -104,8 +104,8 @@ func (db *DB) ListProjects(ctx context.Context) ([]thoughttypes.ProjectSummary,
return projects, nil
}
func (db *DB) TouchProject(ctx context.Context, id uuid.UUID) error {
tag, err := db.pool.Exec(ctx, `update projects set last_active_at = now() where guid = $1`, id)
func (db *DB) TouchProject(ctx context.Context, id int64) error {
tag, err := db.pool.Exec(ctx, `update projects set last_active_at = now() where id = $1`, id)
if err != nil {
return fmt.Errorf("touch project: %w", err)
}

View File

@@ -5,8 +5,6 @@ import (
"fmt"
"strings"
"github.com/google/uuid"
"git.warky.dev/wdevs/amcs/internal/generatedmodels"
ext "git.warky.dev/wdevs/amcs/internal/types"
)
@@ -20,21 +18,22 @@ func (db *DB) AddSkill(ctx context.Context, skill ext.AgentSkill) (ext.AgentSkil
row := db.pool.QueryRow(ctx, `
insert into agent_skills (name, description, content, tags)
values ($1, $2, $3, $4)
returning id, created_at, updated_at
returning id, guid, created_at, updated_at
`, skill.Name, skill.Description, skill.Content, skill.Tags)
created := skill
var model generatedmodels.ModelPublicAgentSkills
if err := row.Scan(&model.ID, &model.CreatedAt, &model.UpdatedAt); err != nil {
if err := row.Scan(&model.ID, &model.GUID, &model.CreatedAt, &model.UpdatedAt); err != nil {
return ext.AgentSkill{}, fmt.Errorf("insert agent skill: %w", err)
}
created.ID = model.ID.UUID()
created.ID = model.ID.Int64()
created.GUID = model.GUID.UUID()
created.CreatedAt = model.CreatedAt.Time()
created.UpdatedAt = model.UpdatedAt.Time()
return created, nil
}
func (db *DB) RemoveSkill(ctx context.Context, id uuid.UUID) error {
func (db *DB) RemoveSkill(ctx context.Context, id int64) error {
tag, err := db.pool.Exec(ctx, `delete from agent_skills where id = $1`, id)
if err != nil {
return fmt.Errorf("delete agent skill: %w", err)
@@ -68,7 +67,7 @@ func (db *DB) ListSkills(ctx context.Context, tag string) ([]ext.AgentSkill, err
return nil, fmt.Errorf("scan agent skill: %w", err)
}
s := ext.AgentSkill{
ID: model.ID.UUID(),
ID: model.ID.Int64(),
Name: model.Name.String(),
Description: model.Description.String(),
Content: model.Content.String(),
@@ -84,7 +83,7 @@ func (db *DB) ListSkills(ctx context.Context, tag string) ([]ext.AgentSkill, err
return skills, rows.Err()
}
func (db *DB) GetSkill(ctx context.Context, id uuid.UUID) (ext.AgentSkill, error) {
func (db *DB) GetSkill(ctx context.Context, id int64) (ext.AgentSkill, error) {
row := db.pool.QueryRow(ctx, `
select id, name, description, content, tags::text[], created_at, updated_at
from agent_skills where id = $1
@@ -96,7 +95,7 @@ func (db *DB) GetSkill(ctx context.Context, id uuid.UUID) (ext.AgentSkill, error
return ext.AgentSkill{}, fmt.Errorf("get agent skill: %w", err)
}
s := ext.AgentSkill{
ID: model.ID.UUID(),
ID: model.ID.Int64(),
Name: model.Name.String(),
Description: model.Description.String(),
Content: model.Content.String(),
@@ -122,21 +121,22 @@ func (db *DB) AddGuardrail(ctx context.Context, g ext.AgentGuardrail) (ext.Agent
row := db.pool.QueryRow(ctx, `
insert into agent_guardrails (name, description, content, severity, tags)
values ($1, $2, $3, $4, $5)
returning id, created_at, updated_at
returning id, guid, created_at, updated_at
`, g.Name, g.Description, g.Content, g.Severity, g.Tags)
created := g
var model generatedmodels.ModelPublicAgentGuardrails
if err := row.Scan(&model.ID, &model.CreatedAt, &model.UpdatedAt); err != nil {
if err := row.Scan(&model.ID, &model.GUID, &model.CreatedAt, &model.UpdatedAt); err != nil {
return ext.AgentGuardrail{}, fmt.Errorf("insert agent guardrail: %w", err)
}
created.ID = model.ID.UUID()
created.ID = model.ID.Int64()
created.GUID = model.GUID.UUID()
created.CreatedAt = model.CreatedAt.Time()
created.UpdatedAt = model.UpdatedAt.Time()
return created, nil
}
func (db *DB) RemoveGuardrail(ctx context.Context, id uuid.UUID) error {
func (db *DB) RemoveGuardrail(ctx context.Context, id int64) error {
tag, err := db.pool.Exec(ctx, `delete from agent_guardrails where id = $1`, id)
if err != nil {
return fmt.Errorf("delete agent guardrail: %w", err)
@@ -180,7 +180,7 @@ func (db *DB) ListGuardrails(ctx context.Context, tag, severity string) ([]ext.A
return nil, fmt.Errorf("scan agent guardrail: %w", err)
}
g := ext.AgentGuardrail{
ID: model.ID.UUID(),
ID: model.ID.Int64(),
Name: model.Name.String(),
Description: model.Description.String(),
Content: model.Content.String(),
@@ -197,7 +197,7 @@ func (db *DB) ListGuardrails(ctx context.Context, tag, severity string) ([]ext.A
return guardrails, rows.Err()
}
func (db *DB) GetGuardrail(ctx context.Context, id uuid.UUID) (ext.AgentGuardrail, error) {
func (db *DB) GetGuardrail(ctx context.Context, id int64) (ext.AgentGuardrail, error) {
row := db.pool.QueryRow(ctx, `
select id, name, description, content, severity, tags::text[], created_at, updated_at
from agent_guardrails where id = $1
@@ -209,7 +209,7 @@ func (db *DB) GetGuardrail(ctx context.Context, id uuid.UUID) (ext.AgentGuardrai
return ext.AgentGuardrail{}, fmt.Errorf("get agent guardrail: %w", err)
}
g := ext.AgentGuardrail{
ID: model.ID.UUID(),
ID: model.ID.Int64(),
Name: model.Name.String(),
Description: model.Description.String(),
Content: model.Content.String(),
@@ -226,7 +226,7 @@ func (db *DB) GetGuardrail(ctx context.Context, id uuid.UUID) (ext.AgentGuardrai
// Project Skills
func (db *DB) AddProjectSkill(ctx context.Context, projectID, skillID uuid.UUID) error {
func (db *DB) AddProjectSkill(ctx context.Context, projectID, skillID int64) error {
_, err := db.pool.Exec(ctx, `
insert into project_skills (project_id, skill_id)
values ($1, $2)
@@ -238,7 +238,7 @@ func (db *DB) AddProjectSkill(ctx context.Context, projectID, skillID uuid.UUID)
return nil
}
func (db *DB) RemoveProjectSkill(ctx context.Context, projectID, skillID uuid.UUID) error {
func (db *DB) RemoveProjectSkill(ctx context.Context, projectID, skillID int64) error {
tag, err := db.pool.Exec(ctx, `
delete from project_skills where project_id = $1 and skill_id = $2
`, projectID, skillID)
@@ -251,7 +251,7 @@ func (db *DB) RemoveProjectSkill(ctx context.Context, projectID, skillID uuid.UU
return nil
}
func (db *DB) ListProjectSkills(ctx context.Context, projectID uuid.UUID) ([]ext.AgentSkill, error) {
func (db *DB) ListProjectSkills(ctx context.Context, projectID int64) ([]ext.AgentSkill, error) {
rows, err := db.pool.Query(ctx, `
select s.id, s.name, s.description, s.content, s.tags::text[], s.created_at, s.updated_at
from agent_skills s
@@ -272,7 +272,7 @@ func (db *DB) ListProjectSkills(ctx context.Context, projectID uuid.UUID) ([]ext
return nil, fmt.Errorf("scan project skill: %w", err)
}
s := ext.AgentSkill{
ID: model.ID.UUID(),
ID: model.ID.Int64(),
Name: model.Name.String(),
Description: model.Description.String(),
Content: model.Content.String(),
@@ -290,7 +290,7 @@ func (db *DB) ListProjectSkills(ctx context.Context, projectID uuid.UUID) ([]ext
// Project Guardrails
func (db *DB) AddProjectGuardrail(ctx context.Context, projectID, guardrailID uuid.UUID) error {
func (db *DB) AddProjectGuardrail(ctx context.Context, projectID, guardrailID int64) error {
_, err := db.pool.Exec(ctx, `
insert into project_guardrails (project_id, guardrail_id)
values ($1, $2)
@@ -302,7 +302,7 @@ func (db *DB) AddProjectGuardrail(ctx context.Context, projectID, guardrailID uu
return nil
}
func (db *DB) RemoveProjectGuardrail(ctx context.Context, projectID, guardrailID uuid.UUID) error {
func (db *DB) RemoveProjectGuardrail(ctx context.Context, projectID, guardrailID int64) error {
tag, err := db.pool.Exec(ctx, `
delete from project_guardrails where project_id = $1 and guardrail_id = $2
`, projectID, guardrailID)
@@ -315,7 +315,7 @@ func (db *DB) RemoveProjectGuardrail(ctx context.Context, projectID, guardrailID
return nil
}
func (db *DB) ListProjectGuardrails(ctx context.Context, projectID uuid.UUID) ([]ext.AgentGuardrail, error) {
func (db *DB) ListProjectGuardrails(ctx context.Context, projectID int64) ([]ext.AgentGuardrail, error) {
rows, err := db.pool.Query(ctx, `
select g.id, g.name, g.description, g.content, g.severity, g.tags::text[], g.created_at, g.updated_at
from agent_guardrails g
@@ -336,7 +336,7 @@ func (db *DB) ListProjectGuardrails(ctx context.Context, projectID uuid.UUID) ([
return nil, fmt.Errorf("scan project guardrail: %w", err)
}
g := ext.AgentGuardrail{
ID: model.ID.UUID(),
ID: model.ID.Int64(),
Name: model.Name.String(),
Description: model.Description.String(),
Content: model.Content.String(),

View File

@@ -33,12 +33,12 @@ func (db *DB) InsertThought(ctx context.Context, thought thoughttypes.Thought, e
row := tx.QueryRow(ctx, `
insert into thoughts (content, metadata, project_id)
values ($1, $2::jsonb, $3)
returning guid, created_at, updated_at
returning id, guid, created_at, updated_at
`, thought.Content, metadata, thought.ProjectID)
created := thought
created.Embedding = nil
if err := row.Scan(&created.ID, &created.CreatedAt, &created.UpdatedAt); err != nil {
if err := row.Scan(&created.ID, &created.GUID, &created.CreatedAt, &created.UpdatedAt); err != nil {
return thoughttypes.Thought{}, fmt.Errorf("insert thought: %w", err)
}
@@ -132,7 +132,7 @@ func (db *DB) ListThoughts(ctx context.Context, filter thoughttypes.ListFilter)
}
query := `
select guid, content, metadata, project_id, archived_at, created_at, updated_at
select id, guid, content, metadata, project_id, archived_at, created_at, updated_at
from thoughts
`
if len(conditions) > 0 {
@@ -151,7 +151,7 @@ func (db *DB) ListThoughts(ctx context.Context, filter thoughttypes.ListFilter)
thoughts := make([]thoughttypes.Thought, 0, filter.Limit)
for rows.Next() {
var model generatedmodels.ModelPublicThoughts
if err := rows.Scan(&model.GUID, &model.Content, &model.Metadata, &model.ProjectID, &model.ArchivedAt, &model.CreatedAt, &model.UpdatedAt); err != nil {
if err := rows.Scan(&model.ID, &model.GUID, &model.Content, &model.Metadata, &model.ProjectID, &model.ArchivedAt, &model.CreatedAt, &model.UpdatedAt); err != nil {
return nil, fmt.Errorf("scan listed thought: %w", err)
}
thought, err := thoughtFromModel(model)
@@ -218,13 +218,13 @@ func (db *DB) Stats(ctx context.Context) (thoughttypes.ThoughtStats, error) {
func (db *DB) GetThought(ctx context.Context, id uuid.UUID) (thoughttypes.Thought, error) {
row := db.pool.QueryRow(ctx, `
select guid, content, metadata, project_id, archived_at, created_at, updated_at
select id, guid, content, metadata, project_id, archived_at, created_at, updated_at
from thoughts
where guid = $1
`, id)
var model generatedmodels.ModelPublicThoughts
if err := row.Scan(&model.GUID, &model.Content, &model.Metadata, &model.ProjectID, &model.ArchivedAt, &model.CreatedAt, &model.UpdatedAt); err != nil {
if err := row.Scan(&model.ID, &model.GUID, &model.Content, &model.Metadata, &model.ProjectID, &model.ArchivedAt, &model.CreatedAt, &model.UpdatedAt); err != nil {
if err == pgx.ErrNoRows {
return thoughttypes.Thought{}, err
}
@@ -239,7 +239,30 @@ func (db *DB) GetThought(ctx context.Context, id uuid.UUID) (thoughttypes.Though
return thought, nil
}
func (db *DB) UpdateThought(ctx context.Context, id uuid.UUID, content string, embedding []float32, embeddingModel string, metadata thoughttypes.ThoughtMetadata, projectID *uuid.UUID) (thoughttypes.Thought, error) {
func (db *DB) GetThoughtByID(ctx context.Context, id int64) (thoughttypes.Thought, error) {
row := db.pool.QueryRow(ctx, `
select id, guid, content, metadata, project_id, archived_at, created_at, updated_at
from thoughts
where id = $1
`, id)
var model generatedmodels.ModelPublicThoughts
if err := row.Scan(&model.ID, &model.GUID, &model.Content, &model.Metadata, &model.ProjectID, &model.ArchivedAt, &model.CreatedAt, &model.UpdatedAt); err != nil {
if err == pgx.ErrNoRows {
return thoughttypes.Thought{}, err
}
return thoughttypes.Thought{}, fmt.Errorf("get thought by id: %w", err)
}
thought, err := thoughtFromModel(model)
if err != nil {
return thoughttypes.Thought{}, fmt.Errorf("map thought: %w", err)
}
return thought, nil
}
func (db *DB) UpdateThought(ctx context.Context, id uuid.UUID, content string, embedding []float32, embeddingModel string, metadata thoughttypes.ThoughtMetadata, projectID *int64) (thoughttypes.Thought, error) {
metadataBytes, err := json.Marshal(metadata)
if err != nil {
return thoughttypes.Thought{}, fmt.Errorf("marshal updated metadata: %w", err)
@@ -271,7 +294,7 @@ func (db *DB) UpdateThought(ctx context.Context, id uuid.UUID, content string, e
if len(embedding) > 0 && embeddingModel != "" {
if _, err := tx.Exec(ctx, `
insert into embeddings (thought_id, model, dim, embedding)
values ($1, $2, $3, $4)
select id, $2, $3, $4 from thoughts where guid = $1
on conflict (thought_id, model) do update
set embedding = excluded.embedding,
dim = excluded.dim,
@@ -288,7 +311,7 @@ func (db *DB) UpdateThought(ctx context.Context, id uuid.UUID, content string, e
return db.GetThought(ctx, id)
}
func (db *DB) UpdateThoughtMetadata(ctx context.Context, id uuid.UUID, metadata thoughttypes.ThoughtMetadata) (thoughttypes.Thought, error) {
func (db *DB) UpdateThoughtMetadata(ctx context.Context, id int64, metadata thoughttypes.ThoughtMetadata) (thoughttypes.Thought, error) {
metadataBytes, err := json.Marshal(metadata)
if err != nil {
return thoughttypes.Thought{}, fmt.Errorf("marshal updated metadata: %w", err)
@@ -298,7 +321,7 @@ func (db *DB) UpdateThoughtMetadata(ctx context.Context, id uuid.UUID, metadata
update thoughts
set metadata = $2::jsonb,
updated_at = now()
where guid = $1
where id = $1
`, id, metadataBytes)
if err != nil {
return thoughttypes.Thought{}, fmt.Errorf("update thought metadata: %w", err)
@@ -307,7 +330,7 @@ func (db *DB) UpdateThoughtMetadata(ctx context.Context, id uuid.UUID, metadata
return thoughttypes.Thought{}, pgx.ErrNoRows
}
return db.GetThought(ctx, id)
return db.GetThoughtByID(ctx, id)
}
func (db *DB) DeleteThought(ctx context.Context, id uuid.UUID) error {
@@ -332,7 +355,7 @@ func (db *DB) ArchiveThought(ctx context.Context, id uuid.UUID) error {
return nil
}
func (db *DB) RecentThoughts(ctx context.Context, projectID *uuid.UUID, limit int, days int) ([]thoughttypes.Thought, error) {
func (db *DB) RecentThoughts(ctx context.Context, projectID *int64, limit int, days int) ([]thoughttypes.Thought, error) {
filter := thoughttypes.ListFilter{
Limit: limit,
ProjectID: projectID,
@@ -342,7 +365,7 @@ func (db *DB) RecentThoughts(ctx context.Context, projectID *uuid.UUID, limit in
return db.ListThoughts(ctx, filter)
}
func (db *DB) ListThoughtsPendingMetadataRetry(ctx context.Context, limit int, projectID *uuid.UUID, includeArchived bool, olderThanDays int) ([]thoughttypes.Thought, error) {
func (db *DB) ListThoughtsPendingMetadataRetry(ctx context.Context, limit int, projectID *int64, includeArchived bool, olderThanDays int) ([]thoughttypes.Thought, error) {
args := make([]any, 0, 4)
conditions := []string{
"(metadata->>'metadata_status' = 'pending' or metadata->>'metadata_status' = 'failed')",
@@ -361,7 +384,7 @@ func (db *DB) ListThoughtsPendingMetadataRetry(ctx context.Context, limit int, p
}
query := `
select guid, content, metadata, project_id, archived_at, created_at, updated_at
select id, guid, content, metadata, project_id, archived_at, created_at, updated_at
from thoughts
where ` + strings.Join(conditions, " and ")
@@ -376,12 +399,12 @@ func (db *DB) ListThoughtsPendingMetadataRetry(ctx context.Context, limit int, p
thoughts := make([]thoughttypes.Thought, 0, limit)
for rows.Next() {
var thought thoughttypes.Thought
var metadataBytes []byte
if err := rows.Scan(&thought.ID, &thought.Content, &metadataBytes, &thought.ProjectID, &thought.ArchivedAt, &thought.CreatedAt, &thought.UpdatedAt); err != nil {
var model generatedmodels.ModelPublicThoughts
if err := rows.Scan(&model.ID, &model.GUID, &model.Content, &model.Metadata, &model.ProjectID, &model.ArchivedAt, &model.CreatedAt, &model.UpdatedAt); err != nil {
return nil, fmt.Errorf("scan pending metadata retry thought: %w", err)
}
if err := json.Unmarshal(metadataBytes, &thought.Metadata); err != nil {
thought, err := thoughtFromModel(model)
if err != nil {
return nil, fmt.Errorf("decode pending metadata retry thought: %w", err)
}
thoughts = append(thoughts, thought)
@@ -394,7 +417,7 @@ func (db *DB) ListThoughtsPendingMetadataRetry(ctx context.Context, limit int, p
return thoughts, nil
}
func (db *DB) SearchSimilarThoughts(ctx context.Context, embedding []float32, embeddingModel string, threshold float64, limit int, projectID *uuid.UUID, excludeID *uuid.UUID) ([]thoughttypes.SearchResult, error) {
func (db *DB) SearchSimilarThoughts(ctx context.Context, embedding []float32, embeddingModel string, threshold float64, limit int, projectID *int64, excludeID *uuid.UUID) ([]thoughttypes.SearchResult, error) {
args := []any{pgvector.NewVector(embedding), threshold, embeddingModel}
conditions := []string{
"t.archived_at is null",
@@ -412,9 +435,9 @@ func (db *DB) SearchSimilarThoughts(ctx context.Context, embedding []float32, em
args = append(args, limit)
query := `
select t.guid, t.content, t.metadata, 1 - (e.embedding <=> $1) as similarity, t.created_at
select t.id, t.content, t.metadata, 1 - (e.embedding <=> $1) as similarity, t.created_at
from thoughts t
join embeddings e on e.thought_id = t.guid
join embeddings e on e.thought_id = t.id
where ` + strings.Join(conditions, " and ") + fmt.Sprintf(`
order by e.embedding <=> $1
limit $%d`, len(args))
@@ -443,7 +466,7 @@ func (db *DB) SearchSimilarThoughts(ctx context.Context, embedding []float32, em
return results, nil
}
func (db *DB) HasEmbeddingsForModel(ctx context.Context, model string, projectID *uuid.UUID) (bool, error) {
func (db *DB) HasEmbeddingsForModel(ctx context.Context, model string, projectID *int64) (bool, error) {
args := []any{model}
conditions := []string{
"e.model = $1",
@@ -454,7 +477,7 @@ func (db *DB) HasEmbeddingsForModel(ctx context.Context, model string, projectID
conditions = append(conditions, fmt.Sprintf("t.project_id = $%d", len(args)))
}
query := `select exists(select 1 from embeddings e join thoughts t on t.guid = e.thought_id where ` +
query := `select exists(select 1 from embeddings e join thoughts t on t.id = e.thought_id where ` +
strings.Join(conditions, " and ") + `)`
var exists bool
@@ -464,7 +487,7 @@ func (db *DB) HasEmbeddingsForModel(ctx context.Context, model string, projectID
return exists, nil
}
func (db *DB) ListThoughtsMissingEmbedding(ctx context.Context, model string, limit int, projectID *uuid.UUID, includeArchived bool, olderThanDays int) ([]thoughttypes.Thought, error) {
func (db *DB) ListThoughtsMissingEmbedding(ctx context.Context, model string, limit int, projectID *int64, includeArchived bool, olderThanDays int) ([]thoughttypes.Thought, error) {
args := []any{model}
conditions := []string{"e.id is null"}
@@ -482,9 +505,9 @@ func (db *DB) ListThoughtsMissingEmbedding(ctx context.Context, model string, li
args = append(args, limit)
query := `
select t.guid, t.content, t.metadata, t.project_id, t.archived_at, t.created_at, t.updated_at
select t.id, t.guid, t.content, t.metadata, t.project_id, t.archived_at, t.created_at, t.updated_at
from thoughts t
left join embeddings e on e.thought_id = t.guid and e.model = $1
left join embeddings e on e.thought_id = t.id and e.model = $1
where ` + strings.Join(conditions, " and ") + `
order by t.created_at asc
limit $` + fmt.Sprintf("%d", len(args))
@@ -497,12 +520,12 @@ func (db *DB) ListThoughtsMissingEmbedding(ctx context.Context, model string, li
thoughts := make([]thoughttypes.Thought, 0, limit)
for rows.Next() {
var thought thoughttypes.Thought
var metadataBytes []byte
if err := rows.Scan(&thought.ID, &thought.Content, &metadataBytes, &thought.ProjectID, &thought.ArchivedAt, &thought.CreatedAt, &thought.UpdatedAt); err != nil {
var model generatedmodels.ModelPublicThoughts
if err := rows.Scan(&model.ID, &model.GUID, &model.Content, &model.Metadata, &model.ProjectID, &model.ArchivedAt, &model.CreatedAt, &model.UpdatedAt); err != nil {
return nil, fmt.Errorf("scan missing-embedding thought: %w", err)
}
if err := json.Unmarshal(metadataBytes, &thought.Metadata); err != nil {
thought, err := thoughtFromModel(model)
if err != nil {
return nil, fmt.Errorf("decode missing-embedding metadata: %w", err)
}
thoughts = append(thoughts, thought)
@@ -513,7 +536,7 @@ func (db *DB) ListThoughtsMissingEmbedding(ctx context.Context, model string, li
return thoughts, nil
}
func (db *DB) ListThoughtsForMetadataReparse(ctx context.Context, limit int, projectID *uuid.UUID, includeArchived bool, olderThanDays int) ([]thoughttypes.Thought, error) {
func (db *DB) ListThoughtsForMetadataReparse(ctx context.Context, limit int, projectID *int64, includeArchived bool, olderThanDays int) ([]thoughttypes.Thought, error) {
args := make([]any, 0, 3)
conditions := make([]string, 0, 4)
@@ -531,7 +554,7 @@ func (db *DB) ListThoughtsForMetadataReparse(ctx context.Context, limit int, pro
args = append(args, limit)
query := `
select guid, content, metadata, project_id, archived_at, created_at, updated_at
select id, guid, content, metadata, project_id, archived_at, created_at, updated_at
from thoughts
`
if len(conditions) > 0 {
@@ -547,12 +570,12 @@ func (db *DB) ListThoughtsForMetadataReparse(ctx context.Context, limit int, pro
thoughts := make([]thoughttypes.Thought, 0, limit)
for rows.Next() {
var thought thoughttypes.Thought
var metadataBytes []byte
if err := rows.Scan(&thought.ID, &thought.Content, &metadataBytes, &thought.ProjectID, &thought.ArchivedAt, &thought.CreatedAt, &thought.UpdatedAt); err != nil {
var model generatedmodels.ModelPublicThoughts
if err := rows.Scan(&model.ID, &model.GUID, &model.Content, &model.Metadata, &model.ProjectID, &model.ArchivedAt, &model.CreatedAt, &model.UpdatedAt); err != nil {
return nil, fmt.Errorf("scan metadata-reparse thought: %w", err)
}
if err := json.Unmarshal(metadataBytes, &thought.Metadata); err != nil {
thought, err := thoughtFromModel(model)
if err != nil {
return nil, fmt.Errorf("decode metadata-reparse thought metadata: %w", err)
}
thoughts = append(thoughts, thought)
@@ -564,7 +587,7 @@ func (db *DB) ListThoughtsForMetadataReparse(ctx context.Context, limit int, pro
return thoughts, nil
}
func (db *DB) UpsertEmbedding(ctx context.Context, thoughtID uuid.UUID, model string, embedding []float32) error {
func (db *DB) UpsertEmbedding(ctx context.Context, thoughtID int64, model string, embedding []float32) error {
_, err := db.pool.Exec(ctx, `
insert into embeddings (thought_id, model, dim, embedding)
values ($1, $2, $3, $4)
@@ -579,7 +602,7 @@ func (db *DB) UpsertEmbedding(ctx context.Context, thoughtID uuid.UUID, model st
return nil
}
func (db *DB) SearchThoughtsText(ctx context.Context, query string, limit int, projectID *uuid.UUID, excludeID *uuid.UUID) ([]thoughttypes.SearchResult, error) {
func (db *DB) SearchThoughtsText(ctx context.Context, query string, limit int, projectID *int64, excludeID *uuid.UUID) ([]thoughttypes.SearchResult, error) {
args := []any{query}
conditions := []string{
"t.archived_at is null",
@@ -596,11 +619,11 @@ func (db *DB) SearchThoughtsText(ctx context.Context, query string, limit int, p
args = append(args, limit)
q := `
select t.guid, t.content, t.metadata,
select t.id, t.content, t.metadata,
ts_rank_cd(to_tsvector('simple', t.content) || to_tsvector('simple', coalesce(p.name, '')), websearch_to_tsquery('simple', $1)) as similarity,
t.created_at
from thoughts t
left join projects p on t.project_id = p.guid
left join projects p on t.project_id = p.id
where ` + strings.Join(conditions, " and ") + `
order by similarity desc
limit $` + fmt.Sprintf("%d", len(args))