feat(memory/sqlc): expand schema + harden queries + add vet rules

Schema:
- Add agent runtime tables: conversations, messages, runs, run_states,
  state_transitions, checkpoints, tool_results (all BLOB PKs, CASCADE)
- Add jobs queue table with dedupe_key unique partial index
- Add conversation graph tables: forks, links, threads, thread_messages,
  mentions, message_revisions

sqlc config:
- emit_db_tags: true — all generated structs carry db:"col" tags
- Fix stale comment: "TEXT storage" → "BLOB storage" for UUID overrides
- Add column overrides for all new agent runtime + conversation graph tables
- Add CEL vet rules: no-unbounded-delete, one-select-requires-limit-1

Query hardening:
- Add LIMIT 1 to 5 :one queries (recall, archival, working_context, docs, kv)
- Bound 12 unbounded :many queries with LIMIT sqlc.arg(lim)
- Add new query files for all agent runtime + jobs + conversation graph tables

Delegate:
- Add agentID param to GetRecallItem, DeleteRecallItem, GetArchivalChunk,
  ListArchivalChunks, ListAllArchivalChunks, CountArchivalChunks
- Pass Lim param to ListDocumentsByCategory, ListAllDocuments (default 1000)
- Pass Lim:10000 to ListArchivalChunks (bounded but practically unlimited)

CI / Makefile:
- Add sqlc-vet Makefile target (sqlc vet -f sqlc.yaml)
- Add sqlc-vet step to sqlc-check CI job
- Integrate sqlc-vet into check meta-target

Tests:
- Fix integration_test: add SetAgentID(testAgent), fix ListArchivalChunks/
  GetArchivalChunk calls to pass agentID
- Add benchmark suite for delegate ops
This commit is contained in:
ZanzyTHEbar 2026-02-18 23:40:03 +00:00
parent 64f6c7ff5b
commit 626308ad95
43 changed files with 4040 additions and 389 deletions

View file

@ -38,6 +38,9 @@ jobs:
- name: Check sqlc generated code
run: make sqlc-check
- name: Run sqlc vet rules
run: make sqlc-vet
vet:
runs-on: ubuntu-latest
needs: fmt-check

View file

@ -152,6 +152,12 @@ sqlc-check:
@git diff --exit-code -- pkg/memory/sqlc/ || (echo "::error::sqlc generated code is stale. Run 'sqlc generate -f pkg/memory/sqlc/sqlc.yaml' and commit." && exit 1)
@echo "sqlc OK"
## sqlc-vet: Run sqlc vet rules (no-unbounded-delete, one-select-requires-limit-1)
sqlc-vet:
@echo "Running sqlc vet..."
@sqlc vet -f pkg/memory/sqlc/sqlc.yaml
@echo "sqlc vet OK"
# ---------------------------------------------------------------------------
# Fantasy SDK vendor management
# Usage: make fantasy-diff FANTASY_VERSION=v0.9.0
@ -181,8 +187,8 @@ test-integration:
@$(GO) test -tags integration -count=1 -timeout 120s -v ./pkg/memory/...
@echo "Integration tests OK"
## check: Run vet, fmt, and verify dependencies
check: deps fmt vet test
## check: Run vet, fmt, sqlc vet, and verify dependencies
check: deps fmt vet sqlc-vet test
## run: Build and run picoclaw
run: build

View file

@ -178,7 +178,7 @@ func TestNewFromConfig_LocalFullRoundTrip(t *testing.T) {
t.Fatalf("InsertRecallItem: %v", err)
}
got, err := d.GetRecallItem(ctx, item.ID)
got, err := d.GetRecallItem(ctx, "a1", item.ID)
if err != nil {
t.Fatalf("GetRecallItem: %v", err)
}

View file

@ -240,8 +240,8 @@ func (d *LibSQLDelegate) InsertRecallItem(ctx context.Context, item *memory.Reca
})
}
func (d *LibSQLDelegate) GetRecallItem(ctx context.Context, id ids.UUID) (*memory.RecallItem, error) {
row, err := d.queries.GetRecallItem(ctx, memsqlc.GetRecallItemParams{ID: id})
func (d *LibSQLDelegate) GetRecallItem(ctx context.Context, agentID string, id ids.UUID) (*memory.RecallItem, error) {
row, err := d.queries.GetRecallItem(ctx, memsqlc.GetRecallItemParams{ID: id, AgentID: agentID})
if err == sql.ErrNoRows {
return nil, nil
}
@ -254,6 +254,7 @@ func (d *LibSQLDelegate) GetRecallItem(ctx context.Context, id ids.UUID) (*memor
func (d *LibSQLDelegate) UpdateRecallItem(ctx context.Context, item *memory.RecallItem) error {
return d.queries.UpdateRecallItem(ctx, memsqlc.UpdateRecallItemParams{
ID: item.ID,
AgentID: item.AgentID,
Role: item.Role,
Sector: item.Sector,
Importance: item.Importance,
@ -264,8 +265,8 @@ func (d *LibSQLDelegate) UpdateRecallItem(ctx context.Context, item *memory.Reca
})
}
func (d *LibSQLDelegate) DeleteRecallItem(ctx context.Context, id ids.UUID) error {
return d.queries.DeleteRecallItem(ctx, memsqlc.DeleteRecallItemParams{ID: id})
func (d *LibSQLDelegate) DeleteRecallItem(ctx context.Context, agentID string, id ids.UUID) error {
return d.queries.DeleteRecallItem(ctx, memsqlc.DeleteRecallItemParams{ID: id, AgentID: agentID})
}
func (d *LibSQLDelegate) ListRecallItems(ctx context.Context, agentID, sessionKey string, limit, offset int) ([]*memory.RecallItem, error) {
@ -317,8 +318,8 @@ func (d *LibSQLDelegate) InsertArchivalChunk(ctx context.Context, chunk *memory.
})
}
func (d *LibSQLDelegate) GetArchivalChunk(ctx context.Context, id ids.UUID) (*memory.ArchivalChunk, error) {
row, err := d.queries.GetArchivalChunk(ctx, memsqlc.GetArchivalChunkParams{ID: id})
func (d *LibSQLDelegate) GetArchivalChunk(ctx context.Context, agentID string, id ids.UUID) (*memory.ArchivalChunk, error) {
row, err := d.queries.GetArchivalChunk(ctx, memsqlc.GetArchivalChunkParams{ID: id, AgentID: agentID})
if err == sql.ErrNoRows {
return nil, nil
}
@ -328,8 +329,8 @@ func (d *LibSQLDelegate) GetArchivalChunk(ctx context.Context, id ids.UUID) (*me
return sqlcChunkToMemory(row), nil
}
func (d *LibSQLDelegate) ListArchivalChunks(ctx context.Context, recallID ids.UUID) ([]*memory.ArchivalChunk, error) {
rows, err := d.queries.ListArchivalChunks(ctx, memsqlc.ListArchivalChunksParams{RecallID: recallID})
func (d *LibSQLDelegate) ListArchivalChunks(ctx context.Context, agentID string, recallID ids.UUID) ([]*memory.ArchivalChunk, error) {
rows, err := d.queries.ListArchivalChunks(ctx, memsqlc.ListArchivalChunksParams{RecallID: recallID, AgentID: agentID, Lim: 10000})
if err != nil {
return nil, err
}
@ -340,10 +341,11 @@ func (d *LibSQLDelegate) ListArchivalChunks(ctx context.Context, recallID ids.UU
return chunks, nil
}
func (d *LibSQLDelegate) ListAllArchivalChunks(ctx context.Context, limit, offset int) ([]*memory.ArchivalChunk, error) {
func (d *LibSQLDelegate) ListAllArchivalChunks(ctx context.Context, agentID string, limit, offset int) ([]*memory.ArchivalChunk, error) {
rows, err := d.queries.ListAllArchivalChunks(ctx, memsqlc.ListAllArchivalChunksParams{
Lim: int64(limit),
Off: int64(offset),
AgentID: agentID,
Lim: int64(limit),
Off: int64(offset),
})
if err != nil {
return nil, err
@ -406,8 +408,8 @@ func (d *LibSQLDelegate) CountRecallItems(ctx context.Context, agentID, sessionK
return int(count), err
}
func (d *LibSQLDelegate) CountArchivalChunks(ctx context.Context) (int, error) {
count, err := d.queries.CountArchivalChunks(ctx)
func (d *LibSQLDelegate) CountArchivalChunks(ctx context.Context, agentID string) (int, error) {
count, err := d.queries.CountArchivalChunks(ctx, memsqlc.CountArchivalChunksParams{AgentID: agentID})
return int(count), err
}
@ -495,6 +497,7 @@ func (d *LibSQLDelegate) ListDocumentsByCategory(ctx context.Context, agentID, c
rows, err := d.queries.ListDocumentsByCategory(ctx, memsqlc.ListDocumentsByCategoryParams{
AgentID: agentID,
Category: category,
Lim: 1000,
})
if err != nil {
return nil, err
@ -509,6 +512,7 @@ func (d *LibSQLDelegate) ListDocumentsByCategory(ctx context.Context, agentID, c
func (d *LibSQLDelegate) ListAllDocuments(ctx context.Context, agentID string) ([]*memory.AgentDocument, error) {
rows, err := d.queries.ListAllDocuments(ctx, memsqlc.ListAllDocumentsParams{
AgentID: agentID,
Lim: 1000,
})
if err != nil {
return nil, err

View file

@ -0,0 +1,104 @@
package delegate
import (
"context"
"testing"
"github.com/sipeed/picoclaw/pkg/ids"
"github.com/sipeed/picoclaw/pkg/memory"
)
func BenchmarkListRecallItems(b *testing.B) {
d := newBenchDelegate(b)
ctx := context.Background()
agent := "bench-agent"
session := "bench-sess"
for i := 0; i < 50; i++ {
_ = d.InsertRecallItem(ctx, &memory.RecallItem{
ID: ids.New(),
AgentID: agent,
SessionKey: session,
Role: "user",
Sector: memory.SectorEpisodic,
Importance: 0.5,
Content: "Benchmark recall content for testing delegate read performance.",
Tags: "bench",
})
}
b.ReportAllocs()
b.ResetTimer()
for b.Loop() {
_, _ = d.ListRecallItems(ctx, agent, session, 20, 0)
}
}
func BenchmarkGetWorkingContext(b *testing.B) {
d := newBenchDelegate(b)
ctx := context.Background()
agent := "bench-agent"
session := "bench-sess"
_ = d.UpsertWorkingContext(ctx, agent, session, "Working context content for benchmarking.")
b.ReportAllocs()
b.ResetTimer()
for b.Loop() {
_, _ = d.GetWorkingContext(ctx, agent, session)
}
}
func BenchmarkUpsertKV(b *testing.B) {
d := newBenchDelegate(b)
ctx := context.Background()
b.ReportAllocs()
b.ResetTimer()
for b.Loop() {
_ = d.UpsertKV(ctx, "bench-agent", "bench-key", "bench-value")
}
}
func BenchmarkGetKV(b *testing.B) {
d := newBenchDelegate(b)
ctx := context.Background()
_ = d.UpsertKV(ctx, "bench-agent", "bench-key", "bench-value")
b.ReportAllocs()
b.ResetTimer()
for b.Loop() {
_, _ = d.GetKV(ctx, "bench-agent", "bench-key")
}
}
func BenchmarkInsertAuditEntry(b *testing.B) {
d := newBenchDelegate(b)
ctx := context.Background()
b.ReportAllocs()
b.ResetTimer()
for b.Loop() {
_ = d.InsertAuditEntry(ctx, &memory.AuditEntry{
ID: ids.New(),
AgentID: "bench-agent",
SessionKey: "bench-sess",
Action: "tool_call",
Target: "read_file",
Input: `{"path": "/tmp/test"}`,
})
}
}
func newBenchDelegate(b *testing.B) *LibSQLDelegate {
b.Helper()
d, err := NewLibSQLInMemory()
if err != nil {
b.Fatal(err)
}
if err := d.Init(context.Background()); err != nil {
b.Fatal(err)
}
b.Cleanup(func() { d.Close() })
return d
}

View file

@ -85,7 +85,7 @@ func TestLibSQLDelegate_RecallItemCRUD(t *testing.T) {
}
// Get
got, err := d.GetRecallItem(ctx, item.ID)
got, err := d.GetRecallItem(ctx, "agent-1", item.ID)
if err != nil {
t.Fatalf("GetRecallItem: %v", err)
}
@ -109,7 +109,7 @@ func TestLibSQLDelegate_RecallItemCRUD(t *testing.T) {
t.Fatalf("UpdateRecallItem: %v", err)
}
got, err = d.GetRecallItem(ctx, item.ID)
got, err = d.GetRecallItem(ctx, "agent-1", item.ID)
if err != nil {
t.Fatalf("GetRecallItem after update: %v", err)
}
@ -130,11 +130,11 @@ func TestLibSQLDelegate_RecallItemCRUD(t *testing.T) {
}
// Delete
if err := d.DeleteRecallItem(ctx, item.ID); err != nil {
if err := d.DeleteRecallItem(ctx, "agent-1", item.ID); err != nil {
t.Fatalf("DeleteRecallItem: %v", err)
}
got, err = d.GetRecallItem(ctx, item.ID)
got, err = d.GetRecallItem(ctx, "agent-1", item.ID)
if err != nil {
t.Fatalf("GetRecallItem after delete: %v", err)
}
@ -159,11 +159,19 @@ func TestLibSQLDelegate_ArchivalChunkCRUD(t *testing.T) {
d := newTestDelegate(t)
ctx := context.Background()
parentRecall := &memory.RecallItem{
ID: ids.New(), AgentID: "agent-1", SessionKey: "sess-1",
Role: "system", Sector: memory.SectorSemantic, Content: "parent for archival",
}
if err := d.InsertRecallItem(ctx, parentRecall); err != nil {
t.Fatalf("InsertRecallItem (parent): %v", err)
}
embedding := testEmbedding768(0.1, 0.2, 0.3, -0.4, 0.5)
chunk := &memory.ArchivalChunk{
ID: ids.New(),
RecallID: ids.New(),
RecallID: parentRecall.ID,
ChunkIndex: 0,
Content: "This is chunk content for archival",
Embedding: embedding,
@ -171,13 +179,11 @@ func TestLibSQLDelegate_ArchivalChunkCRUD(t *testing.T) {
Hash: "abc123",
}
// Insert
if err := d.InsertArchivalChunk(ctx, chunk); err != nil {
t.Fatalf("InsertArchivalChunk: %v", err)
}
// Get
got, err := d.GetArchivalChunk(ctx, chunk.ID)
got, err := d.GetArchivalChunk(ctx, "agent-1", chunk.ID)
if err != nil {
t.Fatalf("GetArchivalChunk: %v", err)
}
@ -191,7 +197,6 @@ func TestLibSQLDelegate_ArchivalChunkCRUD(t *testing.T) {
t.Fatalf("source mismatch: %q", got.Source)
}
// Verify embedding round-trip (check first 5 seed values)
if len(got.Embedding) != 768 {
t.Fatalf("embedding length mismatch: %d vs 768", len(got.Embedding))
}
@ -202,8 +207,16 @@ func TestLibSQLDelegate_ArchivalChunkCRUD(t *testing.T) {
}
}
// List by recall ID
chunks, err := d.ListArchivalChunks(ctx, chunk.RecallID)
// Verify cross-agent isolation: wrong agentID should not find chunk
wrongAgent, err := d.GetArchivalChunk(ctx, "agent-WRONG", chunk.ID)
if err != nil {
t.Fatalf("GetArchivalChunk wrong agent: %v", err)
}
if wrongAgent != nil {
t.Fatal("expected nil for wrong agentID")
}
chunks, err := d.ListArchivalChunks(ctx, "agent-1", chunk.RecallID)
if err != nil {
t.Fatalf("ListArchivalChunks: %v", err)
}
@ -211,11 +224,10 @@ func TestLibSQLDelegate_ArchivalChunkCRUD(t *testing.T) {
t.Fatalf("expected 1 chunk, got %d", len(chunks))
}
// Delete
if err := d.DeleteArchivalChunks(ctx, chunk.RecallID); err != nil {
t.Fatalf("DeleteArchivalChunks: %v", err)
}
chunks, err = d.ListArchivalChunks(ctx, chunk.RecallID)
chunks, err = d.ListArchivalChunks(ctx, "agent-1", chunk.RecallID)
if err != nil {
t.Fatalf("ListArchivalChunks after delete: %v", err)
}
@ -291,7 +303,7 @@ func TestLibSQLDelegate_Counts(t *testing.T) {
t.Fatalf("expected 0 recall items, got %d", rc)
}
ac, err := d.CountArchivalChunks(ctx)
ac, err := d.CountArchivalChunks(ctx, "agent-1")
if err != nil {
t.Fatalf("CountArchivalChunks: %v", err)
}

View file

@ -28,6 +28,7 @@ func setupFullStack(t *testing.T) (*memstore.MemoryStore, *delegate.LibSQLDelega
chunker := memstore.NewMarkdownChunker(memstore.DefaultMarkdownChunkerConfig())
store := memstore.New(del, chunker, nil, memstore.DefaultConfig())
store.SetAgentID(testAgent)
return store, del
}
@ -59,6 +60,7 @@ func TestIntegration_GooseMigration_DownUpRoundTrip(t *testing.T) {
}
chunker := memstore.NewMarkdownChunker(memstore.DefaultMarkdownChunkerConfig())
store := memstore.New(del, chunker, nil, memstore.DefaultConfig())
store.SetAgentID(testAgent)
require.NoError(t, store.StoreRecall(ctx, item))
require.NoError(t, del.MigrateDown(ctx), "down migration should succeed")
@ -118,7 +120,7 @@ func TestIntegration_ArchivalChunking_EndToEnd(t *testing.T) {
require.NoError(t, err)
assert.False(t, recallID.IsZero(), "StoreArchival should return a valid recall ID")
chunks, err := del.ListArchivalChunks(ctx, recallID)
chunks, err := del.ListArchivalChunks(ctx, testAgent, recallID)
require.NoError(t, err)
assert.NotEmpty(t, chunks, "should create at least one archival chunk")
@ -179,14 +181,14 @@ func TestIntegration_CascadeDelete(t *testing.T) {
})
require.NoError(t, err)
chunks, err := del.ListArchivalChunks(ctx, recallID)
chunks, err := del.ListArchivalChunks(ctx, testAgent, recallID)
require.NoError(t, err)
assert.NotEmpty(t, chunks)
require.NoError(t, store.DeleteRecall(ctx, recallID))
for _, chunk := range chunks {
fetched, err := del.GetArchivalChunk(ctx, chunk.ID)
fetched, err := del.GetArchivalChunk(ctx, testAgent, chunk.ID)
require.NoError(t, err)
assert.Nil(t, fetched, "archival chunks should be cascade-deleted with parent recall item")
}

View file

@ -19,7 +19,7 @@ WHERE agent_id = ?1
`
type CountAuditEntriesParams struct {
AgentID string `json:"agent_id"`
AgentID string `db:"agent_id" json:"agent_id"`
}
// CountAuditEntries
@ -42,8 +42,8 @@ WHERE agent_id = ?1
`
type CountAuditEntriesByActionParams struct {
AgentID string `json:"agent_id"`
Action string `json:"action"`
AgentID string `db:"agent_id" json:"agent_id"`
Action string `db:"action" json:"action"`
}
// CountAuditEntriesByAction
@ -85,14 +85,14 @@ VALUES (
`
type InsertAuditEntryParams struct {
ID ids.UUID `json:"id"`
AgentID string `json:"agent_id"`
SessionKey string `json:"session_key"`
Action string `json:"action"`
Target string `json:"target"`
Input *string `json:"input"`
Output *string `json:"output"`
DurationMs *int64 `json:"duration_ms"`
ID ids.UUID `db:"id" json:"id"`
AgentID string `db:"agent_id" json:"agent_id"`
SessionKey string `db:"session_key" json:"session_key"`
Action string `db:"action" json:"action"`
Target string `db:"target" json:"target"`
Input *string `db:"input" json:"input"`
Output *string `db:"output" json:"output"`
DurationMs *int64 `db:"duration_ms" json:"duration_ms"`
}
// Agent Audit Log queries
@ -150,8 +150,8 @@ LIMIT ?2
`
type ListAuditEntriesParams struct {
AgentID string `json:"agent_id"`
Lim int64 `json:"lim"`
AgentID string `db:"agent_id" json:"agent_id"`
Lim int64 `db:"lim" json:"lim"`
}
// ListAuditEntries
@ -220,9 +220,9 @@ LIMIT ?3
`
type ListAuditEntriesByActionParams struct {
AgentID string `json:"agent_id"`
Action string `json:"action"`
Lim int64 `json:"lim"`
AgentID string `db:"agent_id" json:"agent_id"`
Action string `db:"action" json:"action"`
Lim int64 `db:"lim" json:"lim"`
}
// ListAuditEntriesByAction
@ -292,9 +292,9 @@ LIMIT ?3
`
type ListAuditEntriesBySessionParams struct {
AgentID string `json:"agent_id"`
SessionKey string `json:"session_key"`
Lim int64 `json:"lim"`
AgentID string `db:"agent_id" json:"agent_id"`
SessionKey string `db:"session_key" json:"session_key"`
Lim int64 `db:"lim" json:"lim"`
}
// ListAuditEntriesBySession
@ -353,8 +353,8 @@ WHERE agent_id = ?1
`
type PruneOldAuditEntriesParams struct {
AgentID string `json:"agent_id"`
Before time.Time `json:"before"`
AgentID string `db:"agent_id" json:"agent_id"`
Before time.Time `db:"before" json:"before"`
}
// PruneOldAuditEntries

View file

@ -0,0 +1,136 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.30.0
// source: agent_conversation_forks.sql
package sqlc
import (
"context"
"encoding/json"
"github.com/sipeed/picoclaw/pkg/ids"
)
const CreateAgentConversationFork = `-- name: CreateAgentConversationFork :one
INSERT INTO agent_conversation_forks (
id, parent_conversation_id, child_conversation_id, checkpoint_id, metadata_json
)
VALUES (?, ?, ?, ?, ?)
RETURNING id, parent_conversation_id, child_conversation_id, checkpoint_id, metadata_json, created_at, updated_at
`
type CreateAgentConversationForkParams struct {
ID ids.UUID `db:"id" json:"id"`
ParentConversationID ids.UUID `db:"parent_conversation_id" json:"parent_conversation_id"`
ChildConversationID ids.UUID `db:"child_conversation_id" json:"child_conversation_id"`
CheckpointID ids.UUID `db:"checkpoint_id" json:"checkpoint_id"`
MetadataJson json.RawMessage `db:"metadata_json" json:"metadata_json"`
}
// CreateAgentConversationFork
//
// INSERT INTO agent_conversation_forks (
// id, parent_conversation_id, child_conversation_id, checkpoint_id, metadata_json
// )
// VALUES (?, ?, ?, ?, ?)
// RETURNING id, parent_conversation_id, child_conversation_id, checkpoint_id, metadata_json, created_at, updated_at
func (q *Queries) CreateAgentConversationFork(ctx context.Context, arg CreateAgentConversationForkParams) (AgentConversationFork, error) {
row := q.db.QueryRowContext(ctx, CreateAgentConversationFork,
arg.ID,
arg.ParentConversationID,
arg.ChildConversationID,
arg.CheckpointID,
arg.MetadataJson,
)
var i AgentConversationFork
err := row.Scan(
&i.ID,
&i.ParentConversationID,
&i.ChildConversationID,
&i.CheckpointID,
&i.MetadataJson,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const GetAgentConversationForkByChildConversationID = `-- name: GetAgentConversationForkByChildConversationID :one
SELECT id, parent_conversation_id, child_conversation_id, checkpoint_id, metadata_json, created_at, updated_at FROM agent_conversation_forks
WHERE child_conversation_id = ?
LIMIT 1
`
type GetAgentConversationForkByChildConversationIDParams struct {
ChildConversationID ids.UUID `db:"child_conversation_id" json:"child_conversation_id"`
}
// GetAgentConversationForkByChildConversationID
//
// SELECT id, parent_conversation_id, child_conversation_id, checkpoint_id, metadata_json, created_at, updated_at FROM agent_conversation_forks
// WHERE child_conversation_id = ?
// LIMIT 1
func (q *Queries) GetAgentConversationForkByChildConversationID(ctx context.Context, arg GetAgentConversationForkByChildConversationIDParams) (AgentConversationFork, error) {
row := q.db.QueryRowContext(ctx, GetAgentConversationForkByChildConversationID, arg.ChildConversationID)
var i AgentConversationFork
err := row.Scan(
&i.ID,
&i.ParentConversationID,
&i.ChildConversationID,
&i.CheckpointID,
&i.MetadataJson,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const ListAgentConversationForksByParentConversationID = `-- name: ListAgentConversationForksByParentConversationID :many
SELECT id, parent_conversation_id, child_conversation_id, checkpoint_id, metadata_json, created_at, updated_at FROM agent_conversation_forks
WHERE parent_conversation_id = ?
ORDER BY created_at DESC
LIMIT ?2
`
type ListAgentConversationForksByParentConversationIDParams struct {
ParentConversationID ids.UUID `db:"parent_conversation_id" json:"parent_conversation_id"`
Lim int64 `db:"lim" json:"lim"`
}
// ListAgentConversationForksByParentConversationID
//
// SELECT id, parent_conversation_id, child_conversation_id, checkpoint_id, metadata_json, created_at, updated_at FROM agent_conversation_forks
// WHERE parent_conversation_id = ?
// ORDER BY created_at DESC
// LIMIT ?2
func (q *Queries) ListAgentConversationForksByParentConversationID(ctx context.Context, arg ListAgentConversationForksByParentConversationIDParams) ([]AgentConversationFork, error) {
rows, err := q.db.QueryContext(ctx, ListAgentConversationForksByParentConversationID, arg.ParentConversationID, arg.Lim)
if err != nil {
return nil, err
}
defer rows.Close()
items := []AgentConversationFork{}
for rows.Next() {
var i AgentConversationFork
if err := rows.Scan(
&i.ID,
&i.ParentConversationID,
&i.ChildConversationID,
&i.CheckpointID,
&i.MetadataJson,
&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
}

View file

@ -0,0 +1,126 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.30.0
// source: agent_conversation_links.sql
package sqlc
import (
"context"
"encoding/json"
"github.com/sipeed/picoclaw/pkg/ids"
)
const CreateAgentConversationLink = `-- name: CreateAgentConversationLink :one
INSERT INTO agent_conversation_links (
id, conversation_id, linked_conversation_id, kind, metadata_json
)
VALUES (?, ?, ?, ?, ?)
RETURNING id, conversation_id, linked_conversation_id, kind, metadata_json, created_at, updated_at
`
type CreateAgentConversationLinkParams struct {
ID ids.UUID `db:"id" json:"id"`
ConversationID ids.UUID `db:"conversation_id" json:"conversation_id"`
LinkedConversationID ids.UUID `db:"linked_conversation_id" json:"linked_conversation_id"`
Kind string `db:"kind" json:"kind"`
MetadataJson json.RawMessage `db:"metadata_json" json:"metadata_json"`
}
// CreateAgentConversationLink
//
// INSERT INTO agent_conversation_links (
// id, conversation_id, linked_conversation_id, kind, metadata_json
// )
// VALUES (?, ?, ?, ?, ?)
// RETURNING id, conversation_id, linked_conversation_id, kind, metadata_json, created_at, updated_at
func (q *Queries) CreateAgentConversationLink(ctx context.Context, arg CreateAgentConversationLinkParams) (AgentConversationLink, error) {
row := q.db.QueryRowContext(ctx, CreateAgentConversationLink,
arg.ID,
arg.ConversationID,
arg.LinkedConversationID,
arg.Kind,
arg.MetadataJson,
)
var i AgentConversationLink
err := row.Scan(
&i.ID,
&i.ConversationID,
&i.LinkedConversationID,
&i.Kind,
&i.MetadataJson,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const DeleteAgentConversationLink = `-- name: DeleteAgentConversationLink :exec
DELETE FROM agent_conversation_links
WHERE conversation_id = ? AND linked_conversation_id = ? AND kind = ?
`
type DeleteAgentConversationLinkParams struct {
ConversationID ids.UUID `db:"conversation_id" json:"conversation_id"`
LinkedConversationID ids.UUID `db:"linked_conversation_id" json:"linked_conversation_id"`
Kind string `db:"kind" json:"kind"`
}
// DeleteAgentConversationLink
//
// DELETE FROM agent_conversation_links
// WHERE conversation_id = ? AND linked_conversation_id = ? AND kind = ?
func (q *Queries) DeleteAgentConversationLink(ctx context.Context, arg DeleteAgentConversationLinkParams) error {
_, err := q.db.ExecContext(ctx, DeleteAgentConversationLink, arg.ConversationID, arg.LinkedConversationID, arg.Kind)
return err
}
const ListAgentConversationLinksByConversationID = `-- name: ListAgentConversationLinksByConversationID :many
SELECT id, conversation_id, linked_conversation_id, kind, metadata_json, created_at, updated_at FROM agent_conversation_links
WHERE conversation_id = ?
ORDER BY created_at DESC
LIMIT ?2
`
type ListAgentConversationLinksByConversationIDParams struct {
ConversationID ids.UUID `db:"conversation_id" json:"conversation_id"`
Lim int64 `db:"lim" json:"lim"`
}
// ListAgentConversationLinksByConversationID
//
// SELECT id, conversation_id, linked_conversation_id, kind, metadata_json, created_at, updated_at FROM agent_conversation_links
// WHERE conversation_id = ?
// ORDER BY created_at DESC
// LIMIT ?2
func (q *Queries) ListAgentConversationLinksByConversationID(ctx context.Context, arg ListAgentConversationLinksByConversationIDParams) ([]AgentConversationLink, error) {
rows, err := q.db.QueryContext(ctx, ListAgentConversationLinksByConversationID, arg.ConversationID, arg.Lim)
if err != nil {
return nil, err
}
defer rows.Close()
items := []AgentConversationLink{}
for rows.Next() {
var i AgentConversationLink
if err := rows.Scan(
&i.ID,
&i.ConversationID,
&i.LinkedConversationID,
&i.Kind,
&i.MetadataJson,
&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
}

View file

@ -0,0 +1,134 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.30.0
// source: agent_conversations.sql
package sqlc
import (
"context"
"github.com/sipeed/picoclaw/pkg/ids"
)
const CreateAgentConversation = `-- name: CreateAgentConversation :one
INSERT INTO agent_conversations (id, title)
VALUES (?, ?)
RETURNING id, title, created_at, updated_at
`
type CreateAgentConversationParams struct {
ID ids.UUID `db:"id" json:"id"`
Title *string `db:"title" json:"title"`
}
// CreateAgentConversation
//
// INSERT INTO agent_conversations (id, title)
// VALUES (?, ?)
// RETURNING id, title, created_at, updated_at
func (q *Queries) CreateAgentConversation(ctx context.Context, arg CreateAgentConversationParams) (AgentConversation, error) {
row := q.db.QueryRowContext(ctx, CreateAgentConversation, arg.ID, arg.Title)
var i AgentConversation
err := row.Scan(
&i.ID,
&i.Title,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const GetAgentConversation = `-- name: GetAgentConversation :one
SELECT id, title, created_at, updated_at FROM agent_conversations WHERE id = ? LIMIT 1
`
type GetAgentConversationParams struct {
ID ids.UUID `db:"id" json:"id"`
}
// GetAgentConversation
//
// SELECT id, title, created_at, updated_at FROM agent_conversations WHERE id = ? LIMIT 1
func (q *Queries) GetAgentConversation(ctx context.Context, arg GetAgentConversationParams) (AgentConversation, error) {
row := q.db.QueryRowContext(ctx, GetAgentConversation, arg.ID)
var i AgentConversation
err := row.Scan(
&i.ID,
&i.Title,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const ListAgentConversations = `-- name: ListAgentConversations :many
SELECT id, title, created_at, updated_at FROM agent_conversations ORDER BY created_at DESC LIMIT ?
`
type ListAgentConversationsParams struct {
Limit int64 `db:"limit" json:"limit"`
}
// ListAgentConversations
//
// SELECT id, title, created_at, updated_at FROM agent_conversations ORDER BY created_at DESC LIMIT ?
func (q *Queries) ListAgentConversations(ctx context.Context, arg ListAgentConversationsParams) ([]AgentConversation, error) {
rows, err := q.db.QueryContext(ctx, ListAgentConversations, arg.Limit)
if err != nil {
return nil, err
}
defer rows.Close()
items := []AgentConversation{}
for rows.Next() {
var i AgentConversation
if err := rows.Scan(
&i.ID,
&i.Title,
&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 UpdateAgentConversationTitle = `-- name: UpdateAgentConversationTitle :one
UPDATE agent_conversations
SET title = ?,
updated_at = (strftime('%Y-%m-%dT%H:%M:%fZ', 'now'))
WHERE id = ?
RETURNING id, title, created_at, updated_at
`
type UpdateAgentConversationTitleParams struct {
Title *string `db:"title" json:"title"`
ID ids.UUID `db:"id" json:"id"`
}
// UpdateAgentConversationTitle
//
// UPDATE agent_conversations
// SET title = ?,
// updated_at = (strftime('%Y-%m-%dT%H:%M:%fZ', 'now'))
// WHERE id = ?
// RETURNING id, title, created_at, updated_at
func (q *Queries) UpdateAgentConversationTitle(ctx context.Context, arg UpdateAgentConversationTitleParams) (AgentConversation, error) {
row := q.db.QueryRowContext(ctx, UpdateAgentConversationTitle, arg.Title, arg.ID)
var i AgentConversation
err := row.Scan(
&i.ID,
&i.Title,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}

View file

@ -18,8 +18,8 @@ WHERE agent_id = ?1
`
type DeleteDocumentParams struct {
AgentID string `json:"agent_id"`
Name string `json:"name"`
AgentID string `db:"agent_id" json:"agent_id"`
Name string `db:"name" json:"name"`
}
// DeleteDocument
@ -45,11 +45,12 @@ SELECT id,
FROM agent_documents
WHERE agent_id = ?1
AND name = ?2
LIMIT 1
`
type GetDocumentParams struct {
AgentID string `json:"agent_id"`
Name string `json:"name"`
AgentID string `db:"agent_id" json:"agent_id"`
Name string `db:"name" json:"name"`
}
// Agent Documents queries
@ -66,6 +67,7 @@ type GetDocumentParams struct {
// FROM agent_documents
// WHERE agent_id = ?1
// AND name = ?2
// LIMIT 1
func (q *Queries) GetDocument(ctx context.Context, arg GetDocumentParams) (AgentDocument, error) {
row := q.db.QueryRowContext(ctx, GetDocument, arg.AgentID, arg.Name)
var i AgentDocument
@ -98,10 +100,12 @@ WHERE agent_id = ?1
AND is_active = 1
ORDER BY category,
name
LIMIT ?2
`
type ListAllDocumentsParams struct {
AgentID string `json:"agent_id"`
AgentID string `db:"agent_id" json:"agent_id"`
Lim int64 `db:"lim" json:"lim"`
}
// ListAllDocuments
@ -120,8 +124,9 @@ type ListAllDocumentsParams struct {
// AND is_active = 1
// ORDER BY category,
// name
// LIMIT ?2
func (q *Queries) ListAllDocuments(ctx context.Context, arg ListAllDocumentsParams) ([]AgentDocument, error) {
rows, err := q.db.QueryContext(ctx, ListAllDocuments, arg.AgentID)
rows, err := q.db.QueryContext(ctx, ListAllDocuments, arg.AgentID, arg.Lim)
if err != nil {
return nil, err
}
@ -168,11 +173,13 @@ WHERE agent_id = ?1
AND category = ?2
AND is_active = 1
ORDER BY name
LIMIT ?3
`
type ListDocumentsByCategoryParams struct {
AgentID string `json:"agent_id"`
Category string `json:"category"`
AgentID string `db:"agent_id" json:"agent_id"`
Category string `db:"category" json:"category"`
Lim int64 `db:"lim" json:"lim"`
}
// ListDocumentsByCategory
@ -191,8 +198,9 @@ type ListDocumentsByCategoryParams struct {
// AND category = ?2
// AND is_active = 1
// ORDER BY name
// LIMIT ?3
func (q *Queries) ListDocumentsByCategory(ctx context.Context, arg ListDocumentsByCategoryParams) ([]AgentDocument, error) {
rows, err := q.db.QueryContext(ctx, ListDocumentsByCategory, arg.AgentID, arg.Category)
rows, err := q.db.QueryContext(ctx, ListDocumentsByCategory, arg.AgentID, arg.Category, arg.Lim)
if err != nil {
return nil, err
}
@ -256,11 +264,11 @@ SET content = excluded.content,
`
type UpsertDocumentParams struct {
ID ids.UUID `json:"id"`
AgentID string `json:"agent_id"`
Name string `json:"name"`
Category string `json:"category"`
Content string `json:"content"`
ID ids.UUID `db:"id" json:"id"`
AgentID string `db:"agent_id" json:"agent_id"`
Name string `db:"name" json:"name"`
Category string `db:"category" json:"category"`
Content string `db:"content" json:"content"`
}
// UpsertDocument

View file

@ -16,8 +16,8 @@ WHERE agent_id = ?1
`
type DeleteKVParams struct {
AgentID string `json:"agent_id"`
Key string `json:"key"`
AgentID string `db:"agent_id" json:"agent_id"`
Key string `db:"key" json:"key"`
}
// DeleteKV
@ -38,11 +38,12 @@ SELECT agent_id,
FROM agent_kv
WHERE agent_id = ?1
AND key = ?2
LIMIT 1
`
type GetKVParams struct {
AgentID string `json:"agent_id"`
Key string `json:"key"`
AgentID string `db:"agent_id" json:"agent_id"`
Key string `db:"key" json:"key"`
}
// Agent KV Store queries
@ -54,6 +55,7 @@ type GetKVParams struct {
// FROM agent_kv
// WHERE agent_id = ?1
// AND key = ?2
// LIMIT 1
func (q *Queries) GetKV(ctx context.Context, arg GetKVParams) (AgentKv, error) {
row := q.db.QueryRowContext(ctx, GetKV, arg.AgentID, arg.Key)
var i AgentKv
@ -79,9 +81,9 @@ LIMIT ?3
`
type ListKVByPrefixParams struct {
AgentID string `json:"agent_id"`
Prefix *string `json:"prefix"`
Lim int64 `json:"lim"`
AgentID string `db:"agent_id" json:"agent_id"`
Prefix *string `db:"prefix" json:"prefix"`
Lim int64 `db:"lim" json:"lim"`
}
// ListKVByPrefix
@ -137,9 +139,9 @@ SET value = excluded.value,
`
type UpsertKVParams struct {
AgentID string `json:"agent_id"`
Key string `json:"key"`
Value string `json:"value"`
AgentID string `db:"agent_id" json:"agent_id"`
Key string `db:"key" json:"key"`
Value string `db:"value" json:"value"`
}
// UpsertKV

View file

@ -0,0 +1,114 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.30.0
// source: agent_mentions.sql
package sqlc
import (
"context"
"encoding/json"
"github.com/sipeed/picoclaw/pkg/ids"
)
const AddAgentMention = `-- name: AddAgentMention :one
INSERT INTO agent_mentions (
id, conversation_id, message_id, kind, target_id, raw, metadata_json
)
VALUES (?, ?, ?, ?, ?, ?, ?)
RETURNING id, conversation_id, message_id, kind, target_id, raw, metadata_json, created_at, updated_at
`
type AddAgentMentionParams struct {
ID ids.UUID `db:"id" json:"id"`
ConversationID ids.UUID `db:"conversation_id" json:"conversation_id"`
MessageID ids.UUID `db:"message_id" json:"message_id"`
Kind string `db:"kind" json:"kind"`
TargetID ids.UUID `db:"target_id" json:"target_id"`
Raw string `db:"raw" json:"raw"`
MetadataJson json.RawMessage `db:"metadata_json" json:"metadata_json"`
}
// AddAgentMention
//
// INSERT INTO agent_mentions (
// id, conversation_id, message_id, kind, target_id, raw, metadata_json
// )
// VALUES (?, ?, ?, ?, ?, ?, ?)
// RETURNING id, conversation_id, message_id, kind, target_id, raw, metadata_json, created_at, updated_at
func (q *Queries) AddAgentMention(ctx context.Context, arg AddAgentMentionParams) (AgentMention, error) {
row := q.db.QueryRowContext(ctx, AddAgentMention,
arg.ID,
arg.ConversationID,
arg.MessageID,
arg.Kind,
arg.TargetID,
arg.Raw,
arg.MetadataJson,
)
var i AgentMention
err := row.Scan(
&i.ID,
&i.ConversationID,
&i.MessageID,
&i.Kind,
&i.TargetID,
&i.Raw,
&i.MetadataJson,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const ListAgentMentionsByConversationID = `-- name: ListAgentMentionsByConversationID :many
SELECT id, conversation_id, message_id, kind, target_id, raw, metadata_json, created_at, updated_at FROM agent_mentions
WHERE conversation_id = ?
ORDER BY created_at DESC
LIMIT ?2
`
type ListAgentMentionsByConversationIDParams struct {
ConversationID ids.UUID `db:"conversation_id" json:"conversation_id"`
Lim int64 `db:"lim" json:"lim"`
}
// ListAgentMentionsByConversationID
//
// SELECT id, conversation_id, message_id, kind, target_id, raw, metadata_json, created_at, updated_at FROM agent_mentions
// WHERE conversation_id = ?
// ORDER BY created_at DESC
// LIMIT ?2
func (q *Queries) ListAgentMentionsByConversationID(ctx context.Context, arg ListAgentMentionsByConversationIDParams) ([]AgentMention, error) {
rows, err := q.db.QueryContext(ctx, ListAgentMentionsByConversationID, arg.ConversationID, arg.Lim)
if err != nil {
return nil, err
}
defer rows.Close()
items := []AgentMention{}
for rows.Next() {
var i AgentMention
if err := rows.Scan(
&i.ID,
&i.ConversationID,
&i.MessageID,
&i.Kind,
&i.TargetID,
&i.Raw,
&i.MetadataJson,
&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
}

View file

@ -0,0 +1,110 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.30.0
// source: agent_message_revisions.sql
package sqlc
import (
"context"
"encoding/json"
"github.com/sipeed/picoclaw/pkg/ids"
)
const AddAgentMessageRevision = `-- name: AddAgentMessageRevision :one
INSERT INTO agent_message_revisions (
id, message_id, editor, old_content, new_content, metadata_json
)
VALUES (?, ?, ?, ?, ?, ?)
RETURNING id, message_id, editor, old_content, new_content, metadata_json, created_at, updated_at
`
type AddAgentMessageRevisionParams struct {
ID ids.UUID `db:"id" json:"id"`
MessageID ids.UUID `db:"message_id" json:"message_id"`
Editor string `db:"editor" json:"editor"`
OldContent string `db:"old_content" json:"old_content"`
NewContent string `db:"new_content" json:"new_content"`
MetadataJson json.RawMessage `db:"metadata_json" json:"metadata_json"`
}
// AddAgentMessageRevision
//
// INSERT INTO agent_message_revisions (
// id, message_id, editor, old_content, new_content, metadata_json
// )
// VALUES (?, ?, ?, ?, ?, ?)
// RETURNING id, message_id, editor, old_content, new_content, metadata_json, created_at, updated_at
func (q *Queries) AddAgentMessageRevision(ctx context.Context, arg AddAgentMessageRevisionParams) (AgentMessageRevision, error) {
row := q.db.QueryRowContext(ctx, AddAgentMessageRevision,
arg.ID,
arg.MessageID,
arg.Editor,
arg.OldContent,
arg.NewContent,
arg.MetadataJson,
)
var i AgentMessageRevision
err := row.Scan(
&i.ID,
&i.MessageID,
&i.Editor,
&i.OldContent,
&i.NewContent,
&i.MetadataJson,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const ListAgentMessageRevisionsByMessageID = `-- name: ListAgentMessageRevisionsByMessageID :many
SELECT id, message_id, editor, old_content, new_content, metadata_json, created_at, updated_at FROM agent_message_revisions
WHERE message_id = ?
ORDER BY created_at DESC
LIMIT ?2
`
type ListAgentMessageRevisionsByMessageIDParams struct {
MessageID ids.UUID `db:"message_id" json:"message_id"`
Lim int64 `db:"lim" json:"lim"`
}
// ListAgentMessageRevisionsByMessageID
//
// SELECT id, message_id, editor, old_content, new_content, metadata_json, created_at, updated_at FROM agent_message_revisions
// WHERE message_id = ?
// ORDER BY created_at DESC
// LIMIT ?2
func (q *Queries) ListAgentMessageRevisionsByMessageID(ctx context.Context, arg ListAgentMessageRevisionsByMessageIDParams) ([]AgentMessageRevision, error) {
rows, err := q.db.QueryContext(ctx, ListAgentMessageRevisionsByMessageID, arg.MessageID, arg.Lim)
if err != nil {
return nil, err
}
defer rows.Close()
items := []AgentMessageRevision{}
for rows.Next() {
var i AgentMessageRevision
if err := rows.Scan(
&i.ID,
&i.MessageID,
&i.Editor,
&i.OldContent,
&i.NewContent,
&i.MetadataJson,
&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
}

View file

@ -0,0 +1,148 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.30.0
// source: agent_messages.sql
package sqlc
import (
"context"
"encoding/json"
"github.com/sipeed/picoclaw/pkg/ids"
)
const AddAgentMessage = `-- name: AddAgentMessage :one
INSERT INTO agent_messages (id, conversation_id, role, content, metadata_json)
VALUES (?, ?, ?, ?, ?)
RETURNING id, conversation_id, role, content, metadata_json, created_at, updated_at
`
type AddAgentMessageParams struct {
ID ids.UUID `db:"id" json:"id"`
ConversationID ids.UUID `db:"conversation_id" json:"conversation_id"`
Role string `db:"role" json:"role"`
Content string `db:"content" json:"content"`
MetadataJson json.RawMessage `db:"metadata_json" json:"metadata_json"`
}
// AddAgentMessage
//
// INSERT INTO agent_messages (id, conversation_id, role, content, metadata_json)
// VALUES (?, ?, ?, ?, ?)
// RETURNING id, conversation_id, role, content, metadata_json, created_at, updated_at
func (q *Queries) AddAgentMessage(ctx context.Context, arg AddAgentMessageParams) (AgentMessage, error) {
row := q.db.QueryRowContext(ctx, AddAgentMessage,
arg.ID,
arg.ConversationID,
arg.Role,
arg.Content,
arg.MetadataJson,
)
var i AgentMessage
err := row.Scan(
&i.ID,
&i.ConversationID,
&i.Role,
&i.Content,
&i.MetadataJson,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const ListAgentMessagesByConversationID = `-- name: ListAgentMessagesByConversationID :many
SELECT id, conversation_id, role, content, metadata_json, created_at, updated_at FROM agent_messages
WHERE conversation_id = ?
ORDER BY created_at ASC
`
type ListAgentMessagesByConversationIDParams struct {
ConversationID ids.UUID `db:"conversation_id" json:"conversation_id"`
}
// ListAgentMessagesByConversationID
//
// SELECT id, conversation_id, role, content, metadata_json, created_at, updated_at FROM agent_messages
// WHERE conversation_id = ?
// ORDER BY created_at ASC
func (q *Queries) ListAgentMessagesByConversationID(ctx context.Context, arg ListAgentMessagesByConversationIDParams) ([]AgentMessage, error) {
rows, err := q.db.QueryContext(ctx, ListAgentMessagesByConversationID, arg.ConversationID)
if err != nil {
return nil, err
}
defer rows.Close()
items := []AgentMessage{}
for rows.Next() {
var i AgentMessage
if err := rows.Scan(
&i.ID,
&i.ConversationID,
&i.Role,
&i.Content,
&i.MetadataJson,
&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 ListAgentMessagesByConversationIDLimit = `-- name: ListAgentMessagesByConversationIDLimit :many
SELECT id, conversation_id, role, content, metadata_json, created_at, updated_at FROM agent_messages
WHERE conversation_id = ?
ORDER BY created_at ASC
LIMIT ?
`
type ListAgentMessagesByConversationIDLimitParams struct {
ConversationID ids.UUID `db:"conversation_id" json:"conversation_id"`
Limit int64 `db:"limit" json:"limit"`
}
// ListAgentMessagesByConversationIDLimit
//
// SELECT id, conversation_id, role, content, metadata_json, created_at, updated_at FROM agent_messages
// WHERE conversation_id = ?
// ORDER BY created_at ASC
// LIMIT ?
func (q *Queries) ListAgentMessagesByConversationIDLimit(ctx context.Context, arg ListAgentMessagesByConversationIDLimitParams) ([]AgentMessage, error) {
rows, err := q.db.QueryContext(ctx, ListAgentMessagesByConversationIDLimit, arg.ConversationID, arg.Limit)
if err != nil {
return nil, err
}
defer rows.Close()
items := []AgentMessage{}
for rows.Next() {
var i AgentMessage
if err := rows.Scan(
&i.ID,
&i.ConversationID,
&i.Role,
&i.Content,
&i.MetadataJson,
&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
}

View file

@ -0,0 +1,499 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.30.0
// source: agent_state.sql
package sqlc
import (
"context"
"encoding/json"
"time"
"github.com/sipeed/picoclaw/pkg/ids"
)
const AddAgentRunState = `-- name: AddAgentRunState :one
INSERT INTO agent_run_states (id, run_id, step_index, state, snapshot_json)
VALUES (?, ?, ?, ?, ?)
RETURNING id, run_id, step_index, state, snapshot_json, created_at, updated_at
`
type AddAgentRunStateParams struct {
ID ids.UUID `db:"id" json:"id"`
RunID ids.UUID `db:"run_id" json:"run_id"`
StepIndex int64 `db:"step_index" json:"step_index"`
State string `db:"state" json:"state"`
SnapshotJson json.RawMessage `db:"snapshot_json" json:"snapshot_json"`
}
// AddAgentRunState
//
// INSERT INTO agent_run_states (id, run_id, step_index, state, snapshot_json)
// VALUES (?, ?, ?, ?, ?)
// RETURNING id, run_id, step_index, state, snapshot_json, created_at, updated_at
func (q *Queries) AddAgentRunState(ctx context.Context, arg AddAgentRunStateParams) (AgentRunState, error) {
row := q.db.QueryRowContext(ctx, AddAgentRunState,
arg.ID,
arg.RunID,
arg.StepIndex,
arg.State,
arg.SnapshotJson,
)
var i AgentRunState
err := row.Scan(
&i.ID,
&i.RunID,
&i.StepIndex,
&i.State,
&i.SnapshotJson,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const AddAgentStateTransition = `-- name: AddAgentStateTransition :one
INSERT INTO agent_state_transitions (
id, run_id, step_index, from_state, to_state, trigger, at, meta_json, error
)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
RETURNING id, run_id, step_index, from_state, to_state, "trigger", at, meta_json, error, created_at, updated_at
`
type AddAgentStateTransitionParams struct {
ID ids.UUID `db:"id" json:"id"`
RunID ids.UUID `db:"run_id" json:"run_id"`
StepIndex int64 `db:"step_index" json:"step_index"`
FromState string `db:"from_state" json:"from_state"`
ToState string `db:"to_state" json:"to_state"`
Trigger string `db:"trigger" json:"trigger"`
At time.Time `db:"at" json:"at"`
MetaJson json.RawMessage `db:"meta_json" json:"meta_json"`
Error *string `db:"error" json:"error"`
}
// AddAgentStateTransition
//
// INSERT INTO agent_state_transitions (
// id, run_id, step_index, from_state, to_state, trigger, at, meta_json, error
// )
// VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
// RETURNING id, run_id, step_index, from_state, to_state, "trigger", at, meta_json, error, created_at, updated_at
func (q *Queries) AddAgentStateTransition(ctx context.Context, arg AddAgentStateTransitionParams) (AgentStateTransition, error) {
row := q.db.QueryRowContext(ctx, AddAgentStateTransition,
arg.ID,
arg.RunID,
arg.StepIndex,
arg.FromState,
arg.ToState,
arg.Trigger,
arg.At,
arg.MetaJson,
arg.Error,
)
var i AgentStateTransition
err := row.Scan(
&i.ID,
&i.RunID,
&i.StepIndex,
&i.FromState,
&i.ToState,
&i.Trigger,
&i.At,
&i.MetaJson,
&i.Error,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const CreateAgentCheckpoint = `-- name: CreateAgentCheckpoint :one
INSERT INTO agent_checkpoints (id, conversation_id, name, run_state_id, metadata_json)
VALUES (?, ?, ?, ?, ?)
RETURNING id, conversation_id, name, run_state_id, metadata_json, created_at, updated_at
`
type CreateAgentCheckpointParams struct {
ID ids.UUID `db:"id" json:"id"`
ConversationID ids.UUID `db:"conversation_id" json:"conversation_id"`
Name string `db:"name" json:"name"`
RunStateID ids.UUID `db:"run_state_id" json:"run_state_id"`
MetadataJson json.RawMessage `db:"metadata_json" json:"metadata_json"`
}
// CreateAgentCheckpoint
//
// INSERT INTO agent_checkpoints (id, conversation_id, name, run_state_id, metadata_json)
// VALUES (?, ?, ?, ?, ?)
// RETURNING id, conversation_id, name, run_state_id, metadata_json, created_at, updated_at
func (q *Queries) CreateAgentCheckpoint(ctx context.Context, arg CreateAgentCheckpointParams) (AgentCheckpoint, error) {
row := q.db.QueryRowContext(ctx, CreateAgentCheckpoint,
arg.ID,
arg.ConversationID,
arg.Name,
arg.RunStateID,
arg.MetadataJson,
)
var i AgentCheckpoint
err := row.Scan(
&i.ID,
&i.ConversationID,
&i.Name,
&i.RunStateID,
&i.MetadataJson,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const CreateAgentRun = `-- name: CreateAgentRun :one
INSERT INTO agent_runs (id, conversation_id, status, metadata_json)
VALUES (?, ?, ?, ?)
RETURNING id, conversation_id, status, metadata_json, created_at, updated_at
`
type CreateAgentRunParams struct {
ID ids.UUID `db:"id" json:"id"`
ConversationID ids.UUID `db:"conversation_id" json:"conversation_id"`
Status string `db:"status" json:"status"`
MetadataJson json.RawMessage `db:"metadata_json" json:"metadata_json"`
}
// CreateAgentRun
//
// INSERT INTO agent_runs (id, conversation_id, status, metadata_json)
// VALUES (?, ?, ?, ?)
// RETURNING id, conversation_id, status, metadata_json, created_at, updated_at
func (q *Queries) CreateAgentRun(ctx context.Context, arg CreateAgentRunParams) (AgentRun, error) {
row := q.db.QueryRowContext(ctx, CreateAgentRun,
arg.ID,
arg.ConversationID,
arg.Status,
arg.MetadataJson,
)
var i AgentRun
err := row.Scan(
&i.ID,
&i.ConversationID,
&i.Status,
&i.MetadataJson,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const GetAgentCheckpointByConversationIDAndName = `-- name: GetAgentCheckpointByConversationIDAndName :one
SELECT id, conversation_id, name, run_state_id, metadata_json, created_at, updated_at FROM agent_checkpoints
WHERE conversation_id = ? AND name = ?
LIMIT 1
`
type GetAgentCheckpointByConversationIDAndNameParams struct {
ConversationID ids.UUID `db:"conversation_id" json:"conversation_id"`
Name string `db:"name" json:"name"`
}
// GetAgentCheckpointByConversationIDAndName
//
// SELECT id, conversation_id, name, run_state_id, metadata_json, created_at, updated_at FROM agent_checkpoints
// WHERE conversation_id = ? AND name = ?
// LIMIT 1
func (q *Queries) GetAgentCheckpointByConversationIDAndName(ctx context.Context, arg GetAgentCheckpointByConversationIDAndNameParams) (AgentCheckpoint, error) {
row := q.db.QueryRowContext(ctx, GetAgentCheckpointByConversationIDAndName, arg.ConversationID, arg.Name)
var i AgentCheckpoint
err := row.Scan(
&i.ID,
&i.ConversationID,
&i.Name,
&i.RunStateID,
&i.MetadataJson,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const GetAgentRunStateByID = `-- name: GetAgentRunStateByID :one
SELECT id, run_id, step_index, state, snapshot_json, created_at, updated_at FROM agent_run_states
WHERE id = ?
LIMIT 1
`
type GetAgentRunStateByIDParams struct {
ID ids.UUID `db:"id" json:"id"`
}
// GetAgentRunStateByID
//
// SELECT id, run_id, step_index, state, snapshot_json, created_at, updated_at FROM agent_run_states
// WHERE id = ?
// LIMIT 1
func (q *Queries) GetAgentRunStateByID(ctx context.Context, arg GetAgentRunStateByIDParams) (AgentRunState, error) {
row := q.db.QueryRowContext(ctx, GetAgentRunStateByID, arg.ID)
var i AgentRunState
err := row.Scan(
&i.ID,
&i.RunID,
&i.StepIndex,
&i.State,
&i.SnapshotJson,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const GetLatestAgentRunByConversationID = `-- name: GetLatestAgentRunByConversationID :one
SELECT id, conversation_id, status, metadata_json, created_at, updated_at FROM agent_runs
WHERE conversation_id = ?
ORDER BY created_at DESC
LIMIT 1
`
type GetLatestAgentRunByConversationIDParams struct {
ConversationID ids.UUID `db:"conversation_id" json:"conversation_id"`
}
// GetLatestAgentRunByConversationID
//
// SELECT id, conversation_id, status, metadata_json, created_at, updated_at FROM agent_runs
// WHERE conversation_id = ?
// ORDER BY created_at DESC
// LIMIT 1
func (q *Queries) GetLatestAgentRunByConversationID(ctx context.Context, arg GetLatestAgentRunByConversationIDParams) (AgentRun, error) {
row := q.db.QueryRowContext(ctx, GetLatestAgentRunByConversationID, arg.ConversationID)
var i AgentRun
err := row.Scan(
&i.ID,
&i.ConversationID,
&i.Status,
&i.MetadataJson,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const GetLatestAgentRunStateByRunID = `-- name: GetLatestAgentRunStateByRunID :one
SELECT id, run_id, step_index, state, snapshot_json, created_at, updated_at FROM agent_run_states
WHERE run_id = ?
ORDER BY step_index DESC
LIMIT 1
`
type GetLatestAgentRunStateByRunIDParams struct {
RunID ids.UUID `db:"run_id" json:"run_id"`
}
// GetLatestAgentRunStateByRunID
//
// SELECT id, run_id, step_index, state, snapshot_json, created_at, updated_at FROM agent_run_states
// WHERE run_id = ?
// ORDER BY step_index DESC
// LIMIT 1
func (q *Queries) GetLatestAgentRunStateByRunID(ctx context.Context, arg GetLatestAgentRunStateByRunIDParams) (AgentRunState, error) {
row := q.db.QueryRowContext(ctx, GetLatestAgentRunStateByRunID, arg.RunID)
var i AgentRunState
err := row.Scan(
&i.ID,
&i.RunID,
&i.StepIndex,
&i.State,
&i.SnapshotJson,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const ListAgentCheckpointsByConversationID = `-- name: ListAgentCheckpointsByConversationID :many
SELECT id, conversation_id, name, run_state_id, metadata_json, created_at, updated_at FROM agent_checkpoints
WHERE conversation_id = ?
ORDER BY created_at DESC
LIMIT ?2
`
type ListAgentCheckpointsByConversationIDParams struct {
ConversationID ids.UUID `db:"conversation_id" json:"conversation_id"`
Lim int64 `db:"lim" json:"lim"`
}
// ListAgentCheckpointsByConversationID
//
// SELECT id, conversation_id, name, run_state_id, metadata_json, created_at, updated_at FROM agent_checkpoints
// WHERE conversation_id = ?
// ORDER BY created_at DESC
// LIMIT ?2
func (q *Queries) ListAgentCheckpointsByConversationID(ctx context.Context, arg ListAgentCheckpointsByConversationIDParams) ([]AgentCheckpoint, error) {
rows, err := q.db.QueryContext(ctx, ListAgentCheckpointsByConversationID, arg.ConversationID, arg.Lim)
if err != nil {
return nil, err
}
defer rows.Close()
items := []AgentCheckpoint{}
for rows.Next() {
var i AgentCheckpoint
if err := rows.Scan(
&i.ID,
&i.ConversationID,
&i.Name,
&i.RunStateID,
&i.MetadataJson,
&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 ListAgentRunStatesByRunID = `-- name: ListAgentRunStatesByRunID :many
SELECT id, run_id, step_index, state, snapshot_json, created_at, updated_at FROM agent_run_states
WHERE run_id = ?
ORDER BY step_index ASC
LIMIT ?2
`
type ListAgentRunStatesByRunIDParams struct {
RunID ids.UUID `db:"run_id" json:"run_id"`
Lim int64 `db:"lim" json:"lim"`
}
// ListAgentRunStatesByRunID
//
// SELECT id, run_id, step_index, state, snapshot_json, created_at, updated_at FROM agent_run_states
// WHERE run_id = ?
// ORDER BY step_index ASC
// LIMIT ?2
func (q *Queries) ListAgentRunStatesByRunID(ctx context.Context, arg ListAgentRunStatesByRunIDParams) ([]AgentRunState, error) {
rows, err := q.db.QueryContext(ctx, ListAgentRunStatesByRunID, arg.RunID, arg.Lim)
if err != nil {
return nil, err
}
defer rows.Close()
items := []AgentRunState{}
for rows.Next() {
var i AgentRunState
if err := rows.Scan(
&i.ID,
&i.RunID,
&i.StepIndex,
&i.State,
&i.SnapshotJson,
&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 ListAgentStateTransitionsByRunID = `-- name: ListAgentStateTransitionsByRunID :many
SELECT id, run_id, step_index, from_state, to_state, "trigger", at, meta_json, error, created_at, updated_at FROM agent_state_transitions
WHERE run_id = ?
ORDER BY at ASC
LIMIT ?2
`
type ListAgentStateTransitionsByRunIDParams struct {
RunID ids.UUID `db:"run_id" json:"run_id"`
Lim int64 `db:"lim" json:"lim"`
}
// ListAgentStateTransitionsByRunID
//
// SELECT id, run_id, step_index, from_state, to_state, "trigger", at, meta_json, error, created_at, updated_at FROM agent_state_transitions
// WHERE run_id = ?
// ORDER BY at ASC
// LIMIT ?2
func (q *Queries) ListAgentStateTransitionsByRunID(ctx context.Context, arg ListAgentStateTransitionsByRunIDParams) ([]AgentStateTransition, error) {
rows, err := q.db.QueryContext(ctx, ListAgentStateTransitionsByRunID, arg.RunID, arg.Lim)
if err != nil {
return nil, err
}
defer rows.Close()
items := []AgentStateTransition{}
for rows.Next() {
var i AgentStateTransition
if err := rows.Scan(
&i.ID,
&i.RunID,
&i.StepIndex,
&i.FromState,
&i.ToState,
&i.Trigger,
&i.At,
&i.MetaJson,
&i.Error,
&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 UpdateAgentRunStatus = `-- name: UpdateAgentRunStatus :one
UPDATE agent_runs
SET status = ?,
metadata_json = ?,
updated_at = (strftime('%Y-%m-%dT%H:%M:%fZ', 'now'))
WHERE id = ?
RETURNING id, conversation_id, status, metadata_json, created_at, updated_at
`
type UpdateAgentRunStatusParams struct {
Status string `db:"status" json:"status"`
MetadataJson json.RawMessage `db:"metadata_json" json:"metadata_json"`
ID ids.UUID `db:"id" json:"id"`
}
// UpdateAgentRunStatus
//
// UPDATE agent_runs
// SET status = ?,
// metadata_json = ?,
// updated_at = (strftime('%Y-%m-%dT%H:%M:%fZ', 'now'))
// WHERE id = ?
// RETURNING id, conversation_id, status, metadata_json, created_at, updated_at
func (q *Queries) UpdateAgentRunStatus(ctx context.Context, arg UpdateAgentRunStatusParams) (AgentRun, error) {
row := q.db.QueryRowContext(ctx, UpdateAgentRunStatus, arg.Status, arg.MetadataJson, arg.ID)
var i AgentRun
err := row.Scan(
&i.ID,
&i.ConversationID,
&i.Status,
&i.MetadataJson,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}

View file

@ -0,0 +1,233 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.30.0
// source: agent_threads.sql
package sqlc
import (
"context"
"encoding/json"
"github.com/sipeed/picoclaw/pkg/ids"
)
const AddAgentThreadMessage = `-- name: AddAgentThreadMessage :one
INSERT INTO agent_thread_messages (id, thread_id, role, content, metadata_json)
VALUES (?, ?, ?, ?, ?)
RETURNING id, thread_id, role, content, metadata_json, created_at, updated_at
`
type AddAgentThreadMessageParams struct {
ID ids.UUID `db:"id" json:"id"`
ThreadID ids.UUID `db:"thread_id" json:"thread_id"`
Role string `db:"role" json:"role"`
Content string `db:"content" json:"content"`
MetadataJson json.RawMessage `db:"metadata_json" json:"metadata_json"`
}
// AddAgentThreadMessage
//
// INSERT INTO agent_thread_messages (id, thread_id, role, content, metadata_json)
// VALUES (?, ?, ?, ?, ?)
// RETURNING id, thread_id, role, content, metadata_json, created_at, updated_at
func (q *Queries) AddAgentThreadMessage(ctx context.Context, arg AddAgentThreadMessageParams) (AgentThreadMessage, error) {
row := q.db.QueryRowContext(ctx, AddAgentThreadMessage,
arg.ID,
arg.ThreadID,
arg.Role,
arg.Content,
arg.MetadataJson,
)
var i AgentThreadMessage
err := row.Scan(
&i.ID,
&i.ThreadID,
&i.Role,
&i.Content,
&i.MetadataJson,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const CreateAgentThread = `-- name: CreateAgentThread :one
INSERT INTO agent_threads (id, conversation_id, title, metadata_json)
VALUES (?, ?, ?, ?)
RETURNING id, conversation_id, title, metadata_json, created_at, updated_at
`
type CreateAgentThreadParams struct {
ID ids.UUID `db:"id" json:"id"`
ConversationID ids.UUID `db:"conversation_id" json:"conversation_id"`
Title *string `db:"title" json:"title"`
MetadataJson json.RawMessage `db:"metadata_json" json:"metadata_json"`
}
// CreateAgentThread
//
// INSERT INTO agent_threads (id, conversation_id, title, metadata_json)
// VALUES (?, ?, ?, ?)
// RETURNING id, conversation_id, title, metadata_json, created_at, updated_at
func (q *Queries) CreateAgentThread(ctx context.Context, arg CreateAgentThreadParams) (AgentThread, error) {
row := q.db.QueryRowContext(ctx, CreateAgentThread,
arg.ID,
arg.ConversationID,
arg.Title,
arg.MetadataJson,
)
var i AgentThread
err := row.Scan(
&i.ID,
&i.ConversationID,
&i.Title,
&i.MetadataJson,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const ListAgentThreadMessagesByThreadID = `-- name: ListAgentThreadMessagesByThreadID :many
SELECT id, thread_id, role, content, metadata_json, created_at, updated_at FROM agent_thread_messages
WHERE thread_id = ?
ORDER BY created_at ASC
`
type ListAgentThreadMessagesByThreadIDParams struct {
ThreadID ids.UUID `db:"thread_id" json:"thread_id"`
}
// ListAgentThreadMessagesByThreadID
//
// SELECT id, thread_id, role, content, metadata_json, created_at, updated_at FROM agent_thread_messages
// WHERE thread_id = ?
// ORDER BY created_at ASC
func (q *Queries) ListAgentThreadMessagesByThreadID(ctx context.Context, arg ListAgentThreadMessagesByThreadIDParams) ([]AgentThreadMessage, error) {
rows, err := q.db.QueryContext(ctx, ListAgentThreadMessagesByThreadID, arg.ThreadID)
if err != nil {
return nil, err
}
defer rows.Close()
items := []AgentThreadMessage{}
for rows.Next() {
var i AgentThreadMessage
if err := rows.Scan(
&i.ID,
&i.ThreadID,
&i.Role,
&i.Content,
&i.MetadataJson,
&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 ListAgentThreadMessagesByThreadIDDescLimit = `-- name: ListAgentThreadMessagesByThreadIDDescLimit :many
SELECT id, thread_id, role, content, metadata_json, created_at, updated_at FROM agent_thread_messages
WHERE thread_id = ?
ORDER BY created_at DESC
LIMIT ?
`
type ListAgentThreadMessagesByThreadIDDescLimitParams struct {
ThreadID ids.UUID `db:"thread_id" json:"thread_id"`
Limit int64 `db:"limit" json:"limit"`
}
// ListAgentThreadMessagesByThreadIDDescLimit
//
// SELECT id, thread_id, role, content, metadata_json, created_at, updated_at FROM agent_thread_messages
// WHERE thread_id = ?
// ORDER BY created_at DESC
// LIMIT ?
func (q *Queries) ListAgentThreadMessagesByThreadIDDescLimit(ctx context.Context, arg ListAgentThreadMessagesByThreadIDDescLimitParams) ([]AgentThreadMessage, error) {
rows, err := q.db.QueryContext(ctx, ListAgentThreadMessagesByThreadIDDescLimit, arg.ThreadID, arg.Limit)
if err != nil {
return nil, err
}
defer rows.Close()
items := []AgentThreadMessage{}
for rows.Next() {
var i AgentThreadMessage
if err := rows.Scan(
&i.ID,
&i.ThreadID,
&i.Role,
&i.Content,
&i.MetadataJson,
&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 ListAgentThreadsByConversationID = `-- name: ListAgentThreadsByConversationID :many
SELECT id, conversation_id, title, metadata_json, created_at, updated_at FROM agent_threads
WHERE conversation_id = ?
ORDER BY created_at DESC
LIMIT ?2
`
type ListAgentThreadsByConversationIDParams struct {
ConversationID ids.UUID `db:"conversation_id" json:"conversation_id"`
Lim int64 `db:"lim" json:"lim"`
}
// ListAgentThreadsByConversationID
//
// SELECT id, conversation_id, title, metadata_json, created_at, updated_at FROM agent_threads
// WHERE conversation_id = ?
// ORDER BY created_at DESC
// LIMIT ?2
func (q *Queries) ListAgentThreadsByConversationID(ctx context.Context, arg ListAgentThreadsByConversationIDParams) ([]AgentThread, error) {
rows, err := q.db.QueryContext(ctx, ListAgentThreadsByConversationID, arg.ConversationID, arg.Lim)
if err != nil {
return nil, err
}
defer rows.Close()
items := []AgentThread{}
for rows.Next() {
var i AgentThread
if err := rows.Scan(
&i.ID,
&i.ConversationID,
&i.Title,
&i.MetadataJson,
&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
}

View file

@ -0,0 +1,269 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.30.0
// source: agent_tool_results.sql
package sqlc
import (
"context"
"encoding/json"
"github.com/sipeed/picoclaw/pkg/ids"
)
const AddAgentToolResult = `-- name: AddAgentToolResult :one
INSERT INTO agent_tool_results (
id, conversation_id, run_id, step_index,
tool_call_id, tool_name, full_key, preview, chunk_count, metadata_json
)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
RETURNING id, conversation_id, run_id, step_index, tool_call_id, tool_name, full_key, preview, chunk_count, metadata_json, created_at, updated_at
`
type AddAgentToolResultParams struct {
ID ids.UUID `db:"id" json:"id"`
ConversationID ids.UUID `db:"conversation_id" json:"conversation_id"`
RunID ids.UUID `db:"run_id" json:"run_id"`
StepIndex int64 `db:"step_index" json:"step_index"`
ToolCallID string `db:"tool_call_id" json:"tool_call_id"`
ToolName string `db:"tool_name" json:"tool_name"`
FullKey string `db:"full_key" json:"full_key"`
Preview *string `db:"preview" json:"preview"`
ChunkCount int64 `db:"chunk_count" json:"chunk_count"`
MetadataJson json.RawMessage `db:"metadata_json" json:"metadata_json"`
}
// AddAgentToolResult
//
// INSERT INTO agent_tool_results (
// id, conversation_id, run_id, step_index,
// tool_call_id, tool_name, full_key, preview, chunk_count, metadata_json
// )
// VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
// RETURNING id, conversation_id, run_id, step_index, tool_call_id, tool_name, full_key, preview, chunk_count, metadata_json, created_at, updated_at
func (q *Queries) AddAgentToolResult(ctx context.Context, arg AddAgentToolResultParams) (AgentToolResult, error) {
row := q.db.QueryRowContext(ctx, AddAgentToolResult,
arg.ID,
arg.ConversationID,
arg.RunID,
arg.StepIndex,
arg.ToolCallID,
arg.ToolName,
arg.FullKey,
arg.Preview,
arg.ChunkCount,
arg.MetadataJson,
)
var i AgentToolResult
err := row.Scan(
&i.ID,
&i.ConversationID,
&i.RunID,
&i.StepIndex,
&i.ToolCallID,
&i.ToolName,
&i.FullKey,
&i.Preview,
&i.ChunkCount,
&i.MetadataJson,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const GetAgentToolResultByRunIDAndToolCallID = `-- name: GetAgentToolResultByRunIDAndToolCallID :one
SELECT id, conversation_id, run_id, step_index, tool_call_id, tool_name, full_key, preview, chunk_count, metadata_json, created_at, updated_at FROM agent_tool_results
WHERE run_id = ? AND tool_call_id = ?
LIMIT 1
`
type GetAgentToolResultByRunIDAndToolCallIDParams struct {
RunID ids.UUID `db:"run_id" json:"run_id"`
ToolCallID string `db:"tool_call_id" json:"tool_call_id"`
}
// GetAgentToolResultByRunIDAndToolCallID
//
// SELECT id, conversation_id, run_id, step_index, tool_call_id, tool_name, full_key, preview, chunk_count, metadata_json, created_at, updated_at FROM agent_tool_results
// WHERE run_id = ? AND tool_call_id = ?
// LIMIT 1
func (q *Queries) GetAgentToolResultByRunIDAndToolCallID(ctx context.Context, arg GetAgentToolResultByRunIDAndToolCallIDParams) (AgentToolResult, error) {
row := q.db.QueryRowContext(ctx, GetAgentToolResultByRunIDAndToolCallID, arg.RunID, arg.ToolCallID)
var i AgentToolResult
err := row.Scan(
&i.ID,
&i.ConversationID,
&i.RunID,
&i.StepIndex,
&i.ToolCallID,
&i.ToolName,
&i.FullKey,
&i.Preview,
&i.ChunkCount,
&i.MetadataJson,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const ListAgentToolResultsByConversationID = `-- name: ListAgentToolResultsByConversationID :many
SELECT id, conversation_id, run_id, step_index, tool_call_id, tool_name, full_key, preview, chunk_count, metadata_json, created_at, updated_at FROM agent_tool_results
WHERE conversation_id = ?
ORDER BY created_at DESC
`
type ListAgentToolResultsByConversationIDParams struct {
ConversationID ids.UUID `db:"conversation_id" json:"conversation_id"`
}
// ListAgentToolResultsByConversationID
//
// SELECT id, conversation_id, run_id, step_index, tool_call_id, tool_name, full_key, preview, chunk_count, metadata_json, created_at, updated_at FROM agent_tool_results
// WHERE conversation_id = ?
// ORDER BY created_at DESC
func (q *Queries) ListAgentToolResultsByConversationID(ctx context.Context, arg ListAgentToolResultsByConversationIDParams) ([]AgentToolResult, error) {
rows, err := q.db.QueryContext(ctx, ListAgentToolResultsByConversationID, arg.ConversationID)
if err != nil {
return nil, err
}
defer rows.Close()
items := []AgentToolResult{}
for rows.Next() {
var i AgentToolResult
if err := rows.Scan(
&i.ID,
&i.ConversationID,
&i.RunID,
&i.StepIndex,
&i.ToolCallID,
&i.ToolName,
&i.FullKey,
&i.Preview,
&i.ChunkCount,
&i.MetadataJson,
&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 ListAgentToolResultsByConversationIDLimit = `-- name: ListAgentToolResultsByConversationIDLimit :many
SELECT id, conversation_id, run_id, step_index, tool_call_id, tool_name, full_key, preview, chunk_count, metadata_json, created_at, updated_at FROM agent_tool_results
WHERE conversation_id = ?
ORDER BY created_at DESC
LIMIT ?
`
type ListAgentToolResultsByConversationIDLimitParams struct {
ConversationID ids.UUID `db:"conversation_id" json:"conversation_id"`
Limit int64 `db:"limit" json:"limit"`
}
// ListAgentToolResultsByConversationIDLimit
//
// SELECT id, conversation_id, run_id, step_index, tool_call_id, tool_name, full_key, preview, chunk_count, metadata_json, created_at, updated_at FROM agent_tool_results
// WHERE conversation_id = ?
// ORDER BY created_at DESC
// LIMIT ?
func (q *Queries) ListAgentToolResultsByConversationIDLimit(ctx context.Context, arg ListAgentToolResultsByConversationIDLimitParams) ([]AgentToolResult, error) {
rows, err := q.db.QueryContext(ctx, ListAgentToolResultsByConversationIDLimit, arg.ConversationID, arg.Limit)
if err != nil {
return nil, err
}
defer rows.Close()
items := []AgentToolResult{}
for rows.Next() {
var i AgentToolResult
if err := rows.Scan(
&i.ID,
&i.ConversationID,
&i.RunID,
&i.StepIndex,
&i.ToolCallID,
&i.ToolName,
&i.FullKey,
&i.Preview,
&i.ChunkCount,
&i.MetadataJson,
&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 ListAgentToolResultsByRunID = `-- name: ListAgentToolResultsByRunID :many
SELECT id, conversation_id, run_id, step_index, tool_call_id, tool_name, full_key, preview, chunk_count, metadata_json, created_at, updated_at FROM agent_tool_results
WHERE run_id = ?
ORDER BY step_index ASC, created_at ASC
LIMIT ?2
`
type ListAgentToolResultsByRunIDParams struct {
RunID ids.UUID `db:"run_id" json:"run_id"`
Lim int64 `db:"lim" json:"lim"`
}
// ListAgentToolResultsByRunID
//
// SELECT id, conversation_id, run_id, step_index, tool_call_id, tool_name, full_key, preview, chunk_count, metadata_json, created_at, updated_at FROM agent_tool_results
// WHERE run_id = ?
// ORDER BY step_index ASC, created_at ASC
// LIMIT ?2
func (q *Queries) ListAgentToolResultsByRunID(ctx context.Context, arg ListAgentToolResultsByRunIDParams) ([]AgentToolResult, error) {
rows, err := q.db.QueryContext(ctx, ListAgentToolResultsByRunID, arg.RunID, arg.Lim)
if err != nil {
return nil, err
}
defer rows.Close()
items := []AgentToolResult{}
for rows.Next() {
var i AgentToolResult
if err := rows.Scan(
&i.ID,
&i.ConversationID,
&i.RunID,
&i.StepIndex,
&i.ToolCallID,
&i.ToolName,
&i.FullKey,
&i.Preview,
&i.ChunkCount,
&i.MetadataJson,
&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
}

View file

@ -15,15 +15,23 @@ import (
const CountArchivalChunks = `-- name: CountArchivalChunks :one
SELECT COUNT(*)
FROM archival_chunks
FROM archival_chunks ac
JOIN recall_items ri ON ac.recall_id = ri.id
WHERE ri.agent_id = ?1
`
type CountArchivalChunksParams struct {
AgentID string `db:"agent_id" json:"agent_id"`
}
// CountArchivalChunks
//
// SELECT COUNT(*)
// FROM archival_chunks
func (q *Queries) CountArchivalChunks(ctx context.Context) (int64, error) {
row := q.db.QueryRowContext(ctx, CountArchivalChunks)
// FROM archival_chunks ac
// JOIN recall_items ri ON ac.recall_id = ri.id
// WHERE ri.agent_id = ?1
func (q *Queries) CountArchivalChunks(ctx context.Context, arg CountArchivalChunksParams) (int64, error) {
row := q.db.QueryRowContext(ctx, CountArchivalChunks, arg.AgentID)
var count int64
err := row.Scan(&count)
return count, err
@ -35,7 +43,7 @@ WHERE recall_id = ?1
`
type DeleteArchivalChunksByRecallParams struct {
RecallID ids.UUID `json:"recall_id"`
RecallID ids.UUID `db:"recall_id" json:"recall_id"`
}
// DeleteArchivalChunksByRecall
@ -48,36 +56,43 @@ func (q *Queries) DeleteArchivalChunksByRecall(ctx context.Context, arg DeleteAr
}
const GetArchivalChunk = `-- name: GetArchivalChunk :one
SELECT id,
recall_id,
chunk_index,
content,
embedding,
source,
hash,
created_at
FROM archival_chunks
WHERE id = ?1
SELECT ac.id,
ac.recall_id,
ac.chunk_index,
ac.content,
ac.embedding,
ac.source,
ac.hash,
ac.created_at
FROM archival_chunks ac
JOIN recall_items ri ON ac.recall_id = ri.id
WHERE ac.id = ?1
AND ri.agent_id = ?2
LIMIT 1
`
type GetArchivalChunkParams struct {
ID ids.UUID `json:"id"`
ID ids.UUID `db:"id" json:"id"`
AgentID string `db:"agent_id" json:"agent_id"`
}
// GetArchivalChunk
//
// SELECT id,
// recall_id,
// chunk_index,
// content,
// embedding,
// source,
// hash,
// created_at
// FROM archival_chunks
// WHERE id = ?1
// SELECT ac.id,
// ac.recall_id,
// ac.chunk_index,
// ac.content,
// ac.embedding,
// ac.source,
// ac.hash,
// ac.created_at
// FROM archival_chunks ac
// JOIN recall_items ri ON ac.recall_id = ri.id
// WHERE ac.id = ?1
// AND ri.agent_id = ?2
// LIMIT 1
func (q *Queries) GetArchivalChunk(ctx context.Context, arg GetArchivalChunkParams) (ArchivalChunk, error) {
row := q.db.QueryRowContext(ctx, GetArchivalChunk, arg.ID)
row := q.db.QueryRowContext(ctx, GetArchivalChunk, arg.ID, arg.AgentID)
var i ArchivalChunk
err := row.Scan(
&i.ID,
@ -93,34 +108,39 @@ func (q *Queries) GetArchivalChunk(ctx context.Context, arg GetArchivalChunkPara
}
const GetArchivalChunksByIDs = `-- name: GetArchivalChunksByIDs :many
SELECT id,
recall_id,
chunk_index,
content,
embedding,
source,
hash,
created_at
FROM archival_chunks
WHERE id IN (/*SLICE:ids*/?)
SELECT ac.id,
ac.recall_id,
ac.chunk_index,
ac.content,
ac.embedding,
ac.source,
ac.hash,
ac.created_at
FROM archival_chunks ac
JOIN recall_items ri ON ac.recall_id = ri.id
WHERE ac.id IN (/*SLICE:ids*/?)
AND ri.agent_id = ?2
`
type GetArchivalChunksByIDsParams struct {
Ids []ids.UUID `json:"ids"`
Ids []ids.UUID `db:"ids" json:"ids"`
AgentID string `db:"agent_id" json:"agent_id"`
}
// GetArchivalChunksByIDs
//
// SELECT id,
// recall_id,
// chunk_index,
// content,
// embedding,
// source,
// hash,
// created_at
// FROM archival_chunks
// WHERE id IN (/*SLICE:ids*/?)
// SELECT ac.id,
// ac.recall_id,
// ac.chunk_index,
// ac.content,
// ac.embedding,
// ac.source,
// ac.hash,
// ac.created_at
// FROM archival_chunks ac
// JOIN recall_items ri ON ac.recall_id = ri.id
// WHERE ac.id IN (/*SLICE:ids*/?)
// AND ri.agent_id = ?2
func (q *Queries) GetArchivalChunksByIDs(ctx context.Context, arg GetArchivalChunksByIDsParams) ([]ArchivalChunk, error) {
query := GetArchivalChunksByIDs
var queryParams []interface{}
@ -132,6 +152,7 @@ func (q *Queries) GetArchivalChunksByIDs(ctx context.Context, arg GetArchivalChu
} else {
query = strings.Replace(query, "/*SLICE:ids*/?", "NULL", 1)
}
queryParams = append(queryParams, arg.AgentID)
rows, err := q.db.QueryContext(ctx, query, queryParams...)
if err != nil {
return nil, err
@ -187,13 +208,13 @@ VALUES (
`
type InsertArchivalChunkParams struct {
ID ids.UUID `json:"id"`
RecallID ids.UUID `json:"recall_id"`
ChunkIndex int64 `json:"chunk_index"`
Content string `json:"content"`
Embedding memory.Embedding `json:"embedding"`
Source string `json:"source"`
Hash string `json:"hash"`
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"`
}
// Archival Chunk queries
@ -232,39 +253,44 @@ func (q *Queries) InsertArchivalChunk(ctx context.Context, arg InsertArchivalChu
}
const ListAllArchivalChunks = `-- name: ListAllArchivalChunks :many
SELECT id,
recall_id,
chunk_index,
content,
embedding,
source,
hash,
created_at
FROM archival_chunks
ORDER BY created_at DESC
LIMIT ?2 OFFSET ?1
SELECT ac.id,
ac.recall_id,
ac.chunk_index,
ac.content,
ac.embedding,
ac.source,
ac.hash,
ac.created_at
FROM archival_chunks ac
JOIN recall_items ri ON ac.recall_id = ri.id
WHERE ri.agent_id = ?1
ORDER BY ac.created_at DESC
LIMIT ?3 OFFSET ?2
`
type ListAllArchivalChunksParams struct {
Off int64 `json:"off"`
Lim int64 `json:"lim"`
AgentID string `db:"agent_id" json:"agent_id"`
Off int64 `db:"off" json:"off"`
Lim int64 `db:"lim" json:"lim"`
}
// ListAllArchivalChunks
//
// SELECT id,
// recall_id,
// chunk_index,
// content,
// embedding,
// source,
// hash,
// created_at
// FROM archival_chunks
// ORDER BY created_at DESC
// LIMIT ?2 OFFSET ?1
// SELECT ac.id,
// ac.recall_id,
// ac.chunk_index,
// ac.content,
// ac.embedding,
// ac.source,
// ac.hash,
// ac.created_at
// FROM archival_chunks ac
// JOIN recall_items ri ON ac.recall_id = ri.id
// WHERE ri.agent_id = ?1
// ORDER BY ac.created_at DESC
// LIMIT ?3 OFFSET ?2
func (q *Queries) ListAllArchivalChunks(ctx context.Context, arg ListAllArchivalChunksParams) ([]ArchivalChunk, error) {
rows, err := q.db.QueryContext(ctx, ListAllArchivalChunks, arg.Off, arg.Lim)
rows, err := q.db.QueryContext(ctx, ListAllArchivalChunks, arg.AgentID, arg.Off, arg.Lim)
if err != nil {
return nil, err
}
@ -296,38 +322,46 @@ func (q *Queries) ListAllArchivalChunks(ctx context.Context, arg ListAllArchival
}
const ListArchivalChunks = `-- name: ListArchivalChunks :many
SELECT id,
recall_id,
chunk_index,
content,
embedding,
source,
hash,
created_at
FROM archival_chunks
WHERE recall_id = ?1
ORDER BY chunk_index
SELECT ac.id,
ac.recall_id,
ac.chunk_index,
ac.content,
ac.embedding,
ac.source,
ac.hash,
ac.created_at
FROM archival_chunks ac
JOIN recall_items ri ON ac.recall_id = ri.id
WHERE ac.recall_id = ?1
AND ri.agent_id = ?2
ORDER BY ac.chunk_index
LIMIT ?3
`
type ListArchivalChunksParams struct {
RecallID ids.UUID `json:"recall_id"`
RecallID ids.UUID `db:"recall_id" json:"recall_id"`
AgentID string `db:"agent_id" json:"agent_id"`
Lim int64 `db:"lim" json:"lim"`
}
// ListArchivalChunks
//
// SELECT id,
// recall_id,
// chunk_index,
// content,
// embedding,
// source,
// hash,
// created_at
// FROM archival_chunks
// WHERE recall_id = ?1
// ORDER BY chunk_index
// SELECT ac.id,
// ac.recall_id,
// ac.chunk_index,
// ac.content,
// ac.embedding,
// ac.source,
// ac.hash,
// ac.created_at
// FROM archival_chunks ac
// JOIN recall_items ri ON ac.recall_id = ri.id
// WHERE ac.recall_id = ?1
// AND ri.agent_id = ?2
// ORDER BY ac.chunk_index
// LIMIT ?3
func (q *Queries) ListArchivalChunks(ctx context.Context, arg ListArchivalChunksParams) ([]ArchivalChunk, error) {
rows, err := q.db.QueryContext(ctx, ListArchivalChunks, arg.RecallID)
rows, err := q.db.QueryContext(ctx, ListArchivalChunks, arg.RecallID, arg.AgentID, arg.Lim)
if err != nil {
return nil, err
}

432
pkg/memory/sqlc/jobs.sql.go Normal file
View file

@ -0,0 +1,432 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.30.0
// source: jobs.sql
package sqlc
import (
"context"
"time"
"github.com/sipeed/picoclaw/pkg/ids"
)
const ClaimJobByID = `-- name: ClaimJobByID :one
UPDATE jobs
SET status = 'running',
attempts = attempts + 1,
locked_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now'),
locked_by = ?1,
updated_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now'),
last_error = NULL
WHERE id = ?2 AND status = 'queued'
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
`
type ClaimJobByIDParams struct {
LockedBy *string `db:"locked_by" json:"locked_by"`
ID ids.UUID `db:"id" json:"id"`
}
// ClaimJobByID
//
// UPDATE jobs
// SET status = 'running',
// attempts = attempts + 1,
// locked_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now'),
// locked_by = ?1,
// updated_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now'),
// last_error = NULL
// WHERE id = ?2 AND status = 'queued'
// 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
func (q *Queries) ClaimJobByID(ctx context.Context, arg ClaimJobByIDParams) (Job, error) {
row := q.db.QueryRowContext(ctx, ClaimJobByID, arg.LockedBy, arg.ID)
var i Job
err := row.Scan(
&i.ID,
&i.Kind,
&i.Status,
&i.RunAt,
&i.Attempts,
&i.MaxAttempts,
&i.LockedAt,
&i.LockedBy,
&i.PayloadJson,
&i.DedupeKey,
&i.LastError,
&i.CreatedAt,
&i.UpdatedAt,
&i.CompletedAt,
)
return i, err
}
const CountJobsByStatus = `-- name: CountJobsByStatus :many
SELECT status, count(*) AS count FROM jobs GROUP BY status
`
type CountJobsByStatusRow struct {
Status string `db:"status" json:"status"`
Count int64 `db:"count" json:"count"`
}
// CountJobsByStatus
//
// SELECT status, count(*) AS count FROM jobs GROUP BY status
func (q *Queries) CountJobsByStatus(ctx context.Context) ([]CountJobsByStatusRow, error) {
rows, err := q.db.QueryContext(ctx, CountJobsByStatus)
if err != nil {
return nil, err
}
defer rows.Close()
items := []CountJobsByStatusRow{}
for rows.Next() {
var i CountJobsByStatusRow
if err := rows.Scan(&i.Status, &i.Count); 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 EnqueueJob = `-- name: EnqueueJob :one
INSERT INTO jobs (
id, kind, status, run_at, max_attempts, payload_json, dedupe_key
)
VALUES (
?1,
?2,
'queued',
coalesce(?3, strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
coalesce(?4, 3),
coalesce(?5, '{}'),
?6
) ON CONFLICT(kind, dedupe_key)
WHERE dedupe_key IS NOT NULL DO UPDATE
SET status = 'queued',
run_at = excluded.run_at,
max_attempts = excluded.max_attempts,
payload_json = excluded.payload_json,
attempts = 0,
last_error = NULL,
updated_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now')
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
`
type EnqueueJobParams struct {
ID ids.UUID `db:"id" json:"id"`
Kind string `db:"kind" json:"kind"`
RunAt interface{} `db:"run_at" json:"run_at"`
MaxAttempts interface{} `db:"max_attempts" json:"max_attempts"`
PayloadJson interface{} `db:"payload_json" json:"payload_json"`
DedupeKey *string `db:"dedupe_key" json:"dedupe_key"`
}
// EnqueueJob
//
// INSERT INTO jobs (
// id, kind, status, run_at, max_attempts, payload_json, dedupe_key
// )
// VALUES (
// ?1,
// ?2,
// 'queued',
// coalesce(?3, strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
// coalesce(?4, 3),
// coalesce(?5, '{}'),
// ?6
// ) ON CONFLICT(kind, dedupe_key)
// WHERE dedupe_key IS NOT NULL DO UPDATE
// SET status = 'queued',
// run_at = excluded.run_at,
// max_attempts = excluded.max_attempts,
// payload_json = excluded.payload_json,
// attempts = 0,
// last_error = NULL,
// updated_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now')
// 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
func (q *Queries) EnqueueJob(ctx context.Context, arg EnqueueJobParams) (Job, error) {
row := q.db.QueryRowContext(ctx, EnqueueJob,
arg.ID,
arg.Kind,
arg.RunAt,
arg.MaxAttempts,
arg.PayloadJson,
arg.DedupeKey,
)
var i Job
err := row.Scan(
&i.ID,
&i.Kind,
&i.Status,
&i.RunAt,
&i.Attempts,
&i.MaxAttempts,
&i.LockedAt,
&i.LockedBy,
&i.PayloadJson,
&i.DedupeKey,
&i.LastError,
&i.CreatedAt,
&i.UpdatedAt,
&i.CompletedAt,
)
return i, err
}
const FindNextRunnableJob = `-- name: FindNextRunnableJob :one
SELECT id FROM jobs
WHERE status = 'queued'
AND run_at <= strftime('%Y-%m-%dT%H:%M:%fZ', 'now')
ORDER BY run_at ASC, created_at ASC
LIMIT 1
`
// FindNextRunnableJob
//
// SELECT id FROM jobs
// WHERE status = 'queued'
// AND run_at <= strftime('%Y-%m-%dT%H:%M:%fZ', 'now')
// ORDER BY run_at ASC, created_at ASC
// LIMIT 1
func (q *Queries) FindNextRunnableJob(ctx context.Context) (ids.UUID, error) {
row := q.db.QueryRowContext(ctx, FindNextRunnableJob)
var id ids.UUID
err := row.Scan(&id)
return id, err
}
const GetJob = `-- name: GetJob :one
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 FROM jobs WHERE id = ?1 LIMIT 1
`
type GetJobParams struct {
ID ids.UUID `db:"id" json:"id"`
}
// 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 FROM jobs WHERE id = ?1 LIMIT 1
func (q *Queries) GetJob(ctx context.Context, arg GetJobParams) (Job, error) {
row := q.db.QueryRowContext(ctx, GetJob, arg.ID)
var i Job
err := row.Scan(
&i.ID,
&i.Kind,
&i.Status,
&i.RunAt,
&i.Attempts,
&i.MaxAttempts,
&i.LockedAt,
&i.LockedBy,
&i.PayloadJson,
&i.DedupeKey,
&i.LastError,
&i.CreatedAt,
&i.UpdatedAt,
&i.CompletedAt,
)
return i, err
}
const ListJobs = `-- name: ListJobs :many
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 FROM jobs ORDER BY created_at DESC LIMIT ?2 OFFSET ?1
`
type ListJobsParams struct {
Off int64 `db:"off" json:"off"`
Lim int64 `db:"lim" json:"lim"`
}
// 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 FROM jobs ORDER BY created_at DESC LIMIT ?2 OFFSET ?1
func (q *Queries) ListJobs(ctx context.Context, arg ListJobsParams) ([]Job, error) {
rows, err := q.db.QueryContext(ctx, ListJobs, arg.Off, arg.Lim)
if err != nil {
return nil, err
}
defer rows.Close()
items := []Job{}
for rows.Next() {
var i Job
if err := rows.Scan(
&i.ID,
&i.Kind,
&i.Status,
&i.RunAt,
&i.Attempts,
&i.MaxAttempts,
&i.LockedAt,
&i.LockedBy,
&i.PayloadJson,
&i.DedupeKey,
&i.LastError,
&i.CreatedAt,
&i.UpdatedAt,
&i.CompletedAt,
); 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 MarkJobFailed = `-- name: MarkJobFailed :one
UPDATE jobs
SET status = 'failed',
completed_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now'),
updated_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now'),
last_error = ?1
WHERE id = ?2
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
`
type MarkJobFailedParams struct {
LastError *string `db:"last_error" json:"last_error"`
ID ids.UUID `db:"id" json:"id"`
}
// MarkJobFailed
//
// UPDATE jobs
// SET status = 'failed',
// completed_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now'),
// updated_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now'),
// last_error = ?1
// WHERE id = ?2
// 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
func (q *Queries) MarkJobFailed(ctx context.Context, arg MarkJobFailedParams) (Job, error) {
row := q.db.QueryRowContext(ctx, MarkJobFailed, arg.LastError, arg.ID)
var i Job
err := row.Scan(
&i.ID,
&i.Kind,
&i.Status,
&i.RunAt,
&i.Attempts,
&i.MaxAttempts,
&i.LockedAt,
&i.LockedBy,
&i.PayloadJson,
&i.DedupeKey,
&i.LastError,
&i.CreatedAt,
&i.UpdatedAt,
&i.CompletedAt,
)
return i, err
}
const MarkJobSucceeded = `-- name: MarkJobSucceeded :one
UPDATE jobs
SET status = 'succeeded',
completed_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now'),
updated_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now'),
last_error = NULL
WHERE id = ?1
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
`
type MarkJobSucceededParams struct {
ID ids.UUID `db:"id" json:"id"`
}
// MarkJobSucceeded
//
// UPDATE jobs
// SET status = 'succeeded',
// completed_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now'),
// updated_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now'),
// last_error = NULL
// WHERE id = ?1
// 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
func (q *Queries) MarkJobSucceeded(ctx context.Context, arg MarkJobSucceededParams) (Job, error) {
row := q.db.QueryRowContext(ctx, MarkJobSucceeded, arg.ID)
var i Job
err := row.Scan(
&i.ID,
&i.Kind,
&i.Status,
&i.RunAt,
&i.Attempts,
&i.MaxAttempts,
&i.LockedAt,
&i.LockedBy,
&i.PayloadJson,
&i.DedupeKey,
&i.LastError,
&i.CreatedAt,
&i.UpdatedAt,
&i.CompletedAt,
)
return i, err
}
const RequeueJob = `-- name: RequeueJob :one
UPDATE jobs
SET status = 'queued',
run_at = coalesce(?1, strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
updated_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now'),
last_error = ?2,
locked_at = NULL,
locked_by = NULL,
completed_at = NULL
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
`
type RequeueJobParams struct {
RunAt time.Time `db:"run_at" json:"run_at"`
LastError *string `db:"last_error" json:"last_error"`
ID ids.UUID `db:"id" json:"id"`
}
// RequeueJob
//
// UPDATE jobs
// SET status = 'queued',
// run_at = coalesce(?1, strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
// updated_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now'),
// last_error = ?2,
// locked_at = NULL,
// locked_by = NULL,
// completed_at = NULL
// 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
func (q *Queries) RequeueJob(ctx context.Context, arg RequeueJobParams) (Job, error) {
row := q.db.QueryRowContext(ctx, RequeueJob, arg.RunAt, arg.LastError, arg.ID)
var i Job
err := row.Scan(
&i.ID,
&i.Kind,
&i.Status,
&i.RunAt,
&i.Attempts,
&i.MaxAttempts,
&i.LockedAt,
&i.LockedBy,
&i.PayloadJson,
&i.DedupeKey,
&i.LastError,
&i.CreatedAt,
&i.UpdatedAt,
&i.CompletedAt,
)
return i, err
}

View file

@ -5,6 +5,7 @@
package sqlc
import (
"encoding/json"
"time"
"github.com/sipeed/picoclaw/pkg/ids"
@ -12,75 +13,229 @@ import (
)
type AgentAuditLog struct {
ID ids.UUID `json:"id"`
AgentID string `json:"agent_id"`
SessionKey string `json:"session_key"`
Action string `json:"action"`
Target string `json:"target"`
Input *string `json:"input"`
Output *string `json:"output"`
DurationMs *int64 `json:"duration_ms"`
CreatedAt time.Time `json:"created_at"`
ID ids.UUID `db:"id" json:"id"`
AgentID string `db:"agent_id" json:"agent_id"`
SessionKey string `db:"session_key" json:"session_key"`
Action string `db:"action" json:"action"`
Target string `db:"target" json:"target"`
Input *string `db:"input" json:"input"`
Output *string `db:"output" json:"output"`
DurationMs *int64 `db:"duration_ms" json:"duration_ms"`
CreatedAt time.Time `db:"created_at" json:"created_at"`
}
type AgentCheckpoint struct {
ID ids.UUID `db:"id" json:"id"`
ConversationID ids.UUID `db:"conversation_id" json:"conversation_id"`
Name string `db:"name" json:"name"`
RunStateID ids.UUID `db:"run_state_id" json:"run_state_id"`
MetadataJson json.RawMessage `db:"metadata_json" json:"metadata_json"`
CreatedAt time.Time `db:"created_at" json:"created_at"`
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
}
type AgentConversation struct {
ID ids.UUID `db:"id" json:"id"`
Title *string `db:"title" json:"title"`
CreatedAt time.Time `db:"created_at" json:"created_at"`
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
}
type AgentConversationFork struct {
ID ids.UUID `db:"id" json:"id"`
ParentConversationID ids.UUID `db:"parent_conversation_id" json:"parent_conversation_id"`
ChildConversationID ids.UUID `db:"child_conversation_id" json:"child_conversation_id"`
CheckpointID ids.UUID `db:"checkpoint_id" json:"checkpoint_id"`
MetadataJson json.RawMessage `db:"metadata_json" json:"metadata_json"`
CreatedAt time.Time `db:"created_at" json:"created_at"`
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
}
type AgentConversationLink struct {
ID ids.UUID `db:"id" json:"id"`
ConversationID ids.UUID `db:"conversation_id" json:"conversation_id"`
LinkedConversationID ids.UUID `db:"linked_conversation_id" json:"linked_conversation_id"`
Kind string `db:"kind" json:"kind"`
MetadataJson json.RawMessage `db:"metadata_json" json:"metadata_json"`
CreatedAt time.Time `db:"created_at" json:"created_at"`
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
}
type AgentDocument struct {
ID ids.UUID `json:"id"`
AgentID string `json:"agent_id"`
Name string `json:"name"`
Category string `json:"category"`
Content string `json:"content"`
Version int64 `json:"version"`
IsActive bool `json:"is_active"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
ID ids.UUID `db:"id" json:"id"`
AgentID string `db:"agent_id" json:"agent_id"`
Name string `db:"name" json:"name"`
Category string `db:"category" json:"category"`
Content string `db:"content" json:"content"`
Version int64 `db:"version" json:"version"`
IsActive bool `db:"is_active" json:"is_active"`
CreatedAt time.Time `db:"created_at" json:"created_at"`
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
}
type AgentKv struct {
AgentID string `json:"agent_id"`
Key string `json:"key"`
Value string `json:"value"`
UpdatedAt time.Time `json:"updated_at"`
AgentID string `db:"agent_id" json:"agent_id"`
Key string `db:"key" json:"key"`
Value string `db:"value" json:"value"`
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
}
type AgentMention struct {
ID ids.UUID `db:"id" json:"id"`
ConversationID ids.UUID `db:"conversation_id" json:"conversation_id"`
MessageID ids.UUID `db:"message_id" json:"message_id"`
Kind string `db:"kind" json:"kind"`
TargetID ids.UUID `db:"target_id" json:"target_id"`
Raw string `db:"raw" json:"raw"`
MetadataJson json.RawMessage `db:"metadata_json" json:"metadata_json"`
CreatedAt time.Time `db:"created_at" json:"created_at"`
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
}
type AgentMessage struct {
ID ids.UUID `db:"id" json:"id"`
ConversationID ids.UUID `db:"conversation_id" json:"conversation_id"`
Role string `db:"role" json:"role"`
Content string `db:"content" json:"content"`
MetadataJson json.RawMessage `db:"metadata_json" json:"metadata_json"`
CreatedAt time.Time `db:"created_at" json:"created_at"`
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
}
type AgentMessageRevision struct {
ID ids.UUID `db:"id" json:"id"`
MessageID ids.UUID `db:"message_id" json:"message_id"`
Editor string `db:"editor" json:"editor"`
OldContent string `db:"old_content" json:"old_content"`
NewContent string `db:"new_content" json:"new_content"`
MetadataJson json.RawMessage `db:"metadata_json" json:"metadata_json"`
CreatedAt time.Time `db:"created_at" json:"created_at"`
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
}
type AgentRun struct {
ID ids.UUID `db:"id" json:"id"`
ConversationID ids.UUID `db:"conversation_id" json:"conversation_id"`
Status string `db:"status" json:"status"`
MetadataJson json.RawMessage `db:"metadata_json" json:"metadata_json"`
CreatedAt time.Time `db:"created_at" json:"created_at"`
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
}
type AgentRunState struct {
ID ids.UUID `db:"id" json:"id"`
RunID ids.UUID `db:"run_id" json:"run_id"`
StepIndex int64 `db:"step_index" json:"step_index"`
State string `db:"state" json:"state"`
SnapshotJson json.RawMessage `db:"snapshot_json" json:"snapshot_json"`
CreatedAt time.Time `db:"created_at" json:"created_at"`
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
}
type AgentStateTransition struct {
ID ids.UUID `db:"id" json:"id"`
RunID ids.UUID `db:"run_id" json:"run_id"`
StepIndex int64 `db:"step_index" json:"step_index"`
FromState string `db:"from_state" json:"from_state"`
ToState string `db:"to_state" json:"to_state"`
Trigger string `db:"trigger" json:"trigger"`
At time.Time `db:"at" json:"at"`
MetaJson json.RawMessage `db:"meta_json" json:"meta_json"`
Error *string `db:"error" json:"error"`
CreatedAt time.Time `db:"created_at" json:"created_at"`
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
}
type AgentThread struct {
ID ids.UUID `db:"id" json:"id"`
ConversationID ids.UUID `db:"conversation_id" json:"conversation_id"`
Title *string `db:"title" json:"title"`
MetadataJson json.RawMessage `db:"metadata_json" json:"metadata_json"`
CreatedAt time.Time `db:"created_at" json:"created_at"`
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
}
type AgentThreadMessage struct {
ID ids.UUID `db:"id" json:"id"`
ThreadID ids.UUID `db:"thread_id" json:"thread_id"`
Role string `db:"role" json:"role"`
Content string `db:"content" json:"content"`
MetadataJson json.RawMessage `db:"metadata_json" json:"metadata_json"`
CreatedAt time.Time `db:"created_at" json:"created_at"`
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
}
type AgentToolResult struct {
ID ids.UUID `db:"id" json:"id"`
ConversationID ids.UUID `db:"conversation_id" json:"conversation_id"`
RunID ids.UUID `db:"run_id" json:"run_id"`
StepIndex int64 `db:"step_index" json:"step_index"`
ToolCallID string `db:"tool_call_id" json:"tool_call_id"`
ToolName string `db:"tool_name" json:"tool_name"`
FullKey string `db:"full_key" json:"full_key"`
Preview *string `db:"preview" json:"preview"`
ChunkCount int64 `db:"chunk_count" json:"chunk_count"`
MetadataJson json.RawMessage `db:"metadata_json" json:"metadata_json"`
CreatedAt time.Time `db:"created_at" json:"created_at"`
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
}
type ArchivalChunk struct {
ID ids.UUID `json:"id"`
RecallID ids.UUID `json:"recall_id"`
ChunkIndex int64 `json:"chunk_index"`
Content string `json:"content"`
Embedding memory.Embedding `json:"embedding"`
Source string `json:"source"`
Hash string `json:"hash"`
CreatedAt time.Time `json:"created_at"`
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"`
}
type Job struct {
ID ids.UUID `db:"id" json:"id"`
Kind string `db:"kind" json:"kind"`
Status string `db:"status" json:"status"`
RunAt time.Time `db:"run_at" json:"run_at"`
Attempts int64 `db:"attempts" json:"attempts"`
MaxAttempts int64 `db:"max_attempts" json:"max_attempts"`
LockedAt *time.Time `db:"locked_at" json:"locked_at"`
LockedBy *string `db:"locked_by" json:"locked_by"`
PayloadJson json.RawMessage `db:"payload_json" json:"payload_json"`
DedupeKey *string `db:"dedupe_key" json:"dedupe_key"`
LastError *string `db:"last_error" json:"last_error"`
CreatedAt time.Time `db:"created_at" json:"created_at"`
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
CompletedAt *time.Time `db:"completed_at" json:"completed_at"`
}
type MemorySummary struct {
ID ids.UUID `json:"id"`
AgentID string `json:"agent_id"`
SessionKey string `json:"session_key"`
Content string `json:"content"`
FromMsgIdx int64 `json:"from_msg_idx"`
ToMsgIdx int64 `json:"to_msg_idx"`
CreatedAt time.Time `json:"created_at"`
ID ids.UUID `db:"id" json:"id"`
AgentID string `db:"agent_id" json:"agent_id"`
SessionKey string `db:"session_key" json:"session_key"`
Content string `db:"content" json:"content"`
FromMsgIdx int64 `db:"from_msg_idx" json:"from_msg_idx"`
ToMsgIdx int64 `db:"to_msg_idx" json:"to_msg_idx"`
CreatedAt time.Time `db:"created_at" json:"created_at"`
}
type RecallItem struct {
ID ids.UUID `json:"id"`
AgentID string `json:"agent_id"`
SessionKey string `json:"session_key"`
Role string `json:"role"`
Sector memory.Sector `json:"sector"`
Importance float64 `json:"importance"`
Salience float64 `json:"salience"`
DecayRate float64 `json:"decay_rate"`
Content string `json:"content"`
Tags string `json:"tags"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
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"`
}
type WorkingContext struct {
AgentID string `json:"agent_id"`
SessionKey string `json:"session_key"`
Content string `json:"content"`
UpdatedAt time.Time `json:"updated_at"`
AgentID string `db:"agent_id" json:"agent_id"`
SessionKey string `db:"session_key" json:"session_key"`
Content string `db:"content" json:"content"`
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
}

View file

@ -6,14 +6,81 @@ package sqlc
import (
"context"
"github.com/sipeed/picoclaw/pkg/ids"
)
type Querier interface {
//AddAgentMention
//
// INSERT INTO agent_mentions (
// id, conversation_id, message_id, kind, target_id, raw, metadata_json
// )
// VALUES (?, ?, ?, ?, ?, ?, ?)
// RETURNING id, conversation_id, message_id, kind, target_id, raw, metadata_json, created_at, updated_at
AddAgentMention(ctx context.Context, arg AddAgentMentionParams) (AgentMention, error)
//AddAgentMessage
//
// INSERT INTO agent_messages (id, conversation_id, role, content, metadata_json)
// VALUES (?, ?, ?, ?, ?)
// RETURNING id, conversation_id, role, content, metadata_json, created_at, updated_at
AddAgentMessage(ctx context.Context, arg AddAgentMessageParams) (AgentMessage, error)
//AddAgentMessageRevision
//
// INSERT INTO agent_message_revisions (
// id, message_id, editor, old_content, new_content, metadata_json
// )
// VALUES (?, ?, ?, ?, ?, ?)
// RETURNING id, message_id, editor, old_content, new_content, metadata_json, created_at, updated_at
AddAgentMessageRevision(ctx context.Context, arg AddAgentMessageRevisionParams) (AgentMessageRevision, error)
//AddAgentRunState
//
// INSERT INTO agent_run_states (id, run_id, step_index, state, snapshot_json)
// VALUES (?, ?, ?, ?, ?)
// RETURNING id, run_id, step_index, state, snapshot_json, created_at, updated_at
AddAgentRunState(ctx context.Context, arg AddAgentRunStateParams) (AgentRunState, error)
//AddAgentStateTransition
//
// INSERT INTO agent_state_transitions (
// id, run_id, step_index, from_state, to_state, trigger, at, meta_json, error
// )
// VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
// RETURNING id, run_id, step_index, from_state, to_state, "trigger", at, meta_json, error, created_at, updated_at
AddAgentStateTransition(ctx context.Context, arg AddAgentStateTransitionParams) (AgentStateTransition, error)
//AddAgentThreadMessage
//
// INSERT INTO agent_thread_messages (id, thread_id, role, content, metadata_json)
// VALUES (?, ?, ?, ?, ?)
// RETURNING id, thread_id, role, content, metadata_json, created_at, updated_at
AddAgentThreadMessage(ctx context.Context, arg AddAgentThreadMessageParams) (AgentThreadMessage, error)
//AddAgentToolResult
//
// INSERT INTO agent_tool_results (
// id, conversation_id, run_id, step_index,
// tool_call_id, tool_name, full_key, preview, chunk_count, metadata_json
// )
// VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
// RETURNING id, conversation_id, run_id, step_index, tool_call_id, tool_name, full_key, preview, chunk_count, metadata_json, created_at, updated_at
AddAgentToolResult(ctx context.Context, arg AddAgentToolResultParams) (AgentToolResult, error)
//ClaimJobByID
//
// UPDATE jobs
// SET status = 'running',
// attempts = attempts + 1,
// locked_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now'),
// locked_by = ?1,
// updated_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now'),
// last_error = NULL
// WHERE id = ?2 AND status = 'queued'
// 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
ClaimJobByID(ctx context.Context, arg ClaimJobByIDParams) (Job, error)
//CountArchivalChunks
//
// SELECT COUNT(*)
// FROM archival_chunks
CountArchivalChunks(ctx context.Context) (int64, error)
// FROM archival_chunks ac
// JOIN recall_items ri ON ac.recall_id = ri.id
// WHERE ri.agent_id = ?1
CountArchivalChunks(ctx context.Context, arg CountArchivalChunksParams) (int64, error)
//CountAuditEntries
//
// SELECT COUNT(*)
@ -27,6 +94,10 @@ type Querier interface {
// WHERE agent_id = ?1
// AND action = ?2
CountAuditEntriesByAction(ctx context.Context, arg CountAuditEntriesByActionParams) (int64, error)
//CountJobsByStatus
//
// SELECT status, count(*) AS count FROM jobs GROUP BY status
CountJobsByStatus(ctx context.Context) ([]CountJobsByStatusRow, error)
//CountRecallItems
//
// SELECT COUNT(*)
@ -45,6 +116,51 @@ type Querier interface {
// AND session_key = ?2
// AND tags = 'session-message'
CountSessionMessages(ctx context.Context, arg CountSessionMessagesParams) (int64, error)
//CreateAgentCheckpoint
//
// INSERT INTO agent_checkpoints (id, conversation_id, name, run_state_id, metadata_json)
// VALUES (?, ?, ?, ?, ?)
// RETURNING id, conversation_id, name, run_state_id, metadata_json, created_at, updated_at
CreateAgentCheckpoint(ctx context.Context, arg CreateAgentCheckpointParams) (AgentCheckpoint, error)
//CreateAgentConversation
//
// INSERT INTO agent_conversations (id, title)
// VALUES (?, ?)
// RETURNING id, title, created_at, updated_at
CreateAgentConversation(ctx context.Context, arg CreateAgentConversationParams) (AgentConversation, error)
//CreateAgentConversationFork
//
// INSERT INTO agent_conversation_forks (
// id, parent_conversation_id, child_conversation_id, checkpoint_id, metadata_json
// )
// VALUES (?, ?, ?, ?, ?)
// RETURNING id, parent_conversation_id, child_conversation_id, checkpoint_id, metadata_json, created_at, updated_at
CreateAgentConversationFork(ctx context.Context, arg CreateAgentConversationForkParams) (AgentConversationFork, error)
//CreateAgentConversationLink
//
// INSERT INTO agent_conversation_links (
// id, conversation_id, linked_conversation_id, kind, metadata_json
// )
// VALUES (?, ?, ?, ?, ?)
// RETURNING id, conversation_id, linked_conversation_id, kind, metadata_json, created_at, updated_at
CreateAgentConversationLink(ctx context.Context, arg CreateAgentConversationLinkParams) (AgentConversationLink, error)
//CreateAgentRun
//
// INSERT INTO agent_runs (id, conversation_id, status, metadata_json)
// VALUES (?, ?, ?, ?)
// RETURNING id, conversation_id, status, metadata_json, created_at, updated_at
CreateAgentRun(ctx context.Context, arg CreateAgentRunParams) (AgentRun, error)
//CreateAgentThread
//
// INSERT INTO agent_threads (id, conversation_id, title, metadata_json)
// VALUES (?, ?, ?, ?)
// RETURNING id, conversation_id, title, metadata_json, created_at, updated_at
CreateAgentThread(ctx context.Context, arg CreateAgentThreadParams) (AgentThread, error)
//DeleteAgentConversationLink
//
// DELETE FROM agent_conversation_links
// WHERE conversation_id = ? AND linked_conversation_id = ? AND kind = ?
DeleteAgentConversationLink(ctx context.Context, arg DeleteAgentConversationLinkParams) error
//DeleteArchivalChunksByRecall
//
// DELETE FROM archival_chunks
@ -66,32 +182,98 @@ type Querier interface {
//
// DELETE FROM recall_items
// WHERE id = ?1
// AND agent_id = ?2
DeleteRecallItem(ctx context.Context, arg DeleteRecallItemParams) error
//EnqueueJob
//
// INSERT INTO jobs (
// id, kind, status, run_at, max_attempts, payload_json, dedupe_key
// )
// VALUES (
// ?1,
// ?2,
// 'queued',
// coalesce(?3, strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
// coalesce(?4, 3),
// coalesce(?5, '{}'),
// ?6
// ) ON CONFLICT(kind, dedupe_key)
// WHERE dedupe_key IS NOT NULL DO UPDATE
// SET status = 'queued',
// run_at = excluded.run_at,
// max_attempts = excluded.max_attempts,
// payload_json = excluded.payload_json,
// attempts = 0,
// last_error = NULL,
// updated_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now')
// 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
EnqueueJob(ctx context.Context, arg EnqueueJobParams) (Job, error)
//FindNextRunnableJob
//
// SELECT id FROM jobs
// WHERE status = 'queued'
// AND run_at <= strftime('%Y-%m-%dT%H:%M:%fZ', 'now')
// ORDER BY run_at ASC, created_at ASC
// LIMIT 1
FindNextRunnableJob(ctx context.Context) (ids.UUID, error)
//GetAgentCheckpointByConversationIDAndName
//
// SELECT id, conversation_id, name, run_state_id, metadata_json, created_at, updated_at FROM agent_checkpoints
// WHERE conversation_id = ? AND name = ?
// LIMIT 1
GetAgentCheckpointByConversationIDAndName(ctx context.Context, arg GetAgentCheckpointByConversationIDAndNameParams) (AgentCheckpoint, error)
//GetAgentConversation
//
// SELECT id, title, created_at, updated_at FROM agent_conversations WHERE id = ? LIMIT 1
GetAgentConversation(ctx context.Context, arg GetAgentConversationParams) (AgentConversation, error)
//GetAgentConversationForkByChildConversationID
//
// SELECT id, parent_conversation_id, child_conversation_id, checkpoint_id, metadata_json, created_at, updated_at FROM agent_conversation_forks
// WHERE child_conversation_id = ?
// LIMIT 1
GetAgentConversationForkByChildConversationID(ctx context.Context, arg GetAgentConversationForkByChildConversationIDParams) (AgentConversationFork, error)
//GetAgentRunStateByID
//
// SELECT id, run_id, step_index, state, snapshot_json, created_at, updated_at FROM agent_run_states
// WHERE id = ?
// LIMIT 1
GetAgentRunStateByID(ctx context.Context, arg GetAgentRunStateByIDParams) (AgentRunState, error)
//GetAgentToolResultByRunIDAndToolCallID
//
// SELECT id, conversation_id, run_id, step_index, tool_call_id, tool_name, full_key, preview, chunk_count, metadata_json, created_at, updated_at FROM agent_tool_results
// WHERE run_id = ? AND tool_call_id = ?
// LIMIT 1
GetAgentToolResultByRunIDAndToolCallID(ctx context.Context, arg GetAgentToolResultByRunIDAndToolCallIDParams) (AgentToolResult, error)
//GetArchivalChunk
//
// SELECT id,
// recall_id,
// chunk_index,
// content,
// embedding,
// source,
// hash,
// created_at
// FROM archival_chunks
// WHERE id = ?1
// SELECT ac.id,
// ac.recall_id,
// ac.chunk_index,
// ac.content,
// ac.embedding,
// ac.source,
// ac.hash,
// ac.created_at
// FROM archival_chunks ac
// JOIN recall_items ri ON ac.recall_id = ri.id
// WHERE ac.id = ?1
// AND ri.agent_id = ?2
// LIMIT 1
GetArchivalChunk(ctx context.Context, arg GetArchivalChunkParams) (ArchivalChunk, error)
//GetArchivalChunksByIDs
//
// SELECT id,
// recall_id,
// chunk_index,
// content,
// embedding,
// source,
// hash,
// created_at
// FROM archival_chunks
// WHERE id IN (/*SLICE:ids*/?)
// SELECT ac.id,
// ac.recall_id,
// ac.chunk_index,
// ac.content,
// ac.embedding,
// ac.source,
// ac.hash,
// ac.created_at
// FROM archival_chunks ac
// JOIN recall_items ri ON ac.recall_id = ri.id
// WHERE ac.id IN (/*SLICE:ids*/?)
// AND ri.agent_id = ?2
GetArchivalChunksByIDs(ctx context.Context, arg GetArchivalChunksByIDsParams) ([]ArchivalChunk, error)
// Agent Documents queries
//
@ -107,7 +289,12 @@ type Querier interface {
// FROM agent_documents
// WHERE agent_id = ?1
// AND name = ?2
// LIMIT 1
GetDocument(ctx context.Context, arg GetDocumentParams) (AgentDocument, error)
//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 FROM jobs WHERE id = ?1 LIMIT 1
GetJob(ctx context.Context, arg GetJobParams) (Job, error)
// Agent KV Store queries
//
// SELECT agent_id,
@ -117,7 +304,22 @@ type Querier interface {
// FROM agent_kv
// WHERE agent_id = ?1
// AND key = ?2
// LIMIT 1
GetKV(ctx context.Context, arg GetKVParams) (AgentKv, error)
//GetLatestAgentRunByConversationID
//
// SELECT id, conversation_id, status, metadata_json, created_at, updated_at FROM agent_runs
// WHERE conversation_id = ?
// ORDER BY created_at DESC
// LIMIT 1
GetLatestAgentRunByConversationID(ctx context.Context, arg GetLatestAgentRunByConversationIDParams) (AgentRun, error)
//GetLatestAgentRunStateByRunID
//
// SELECT id, run_id, step_index, state, snapshot_json, created_at, updated_at FROM agent_run_states
// WHERE run_id = ?
// ORDER BY step_index DESC
// LIMIT 1
GetLatestAgentRunStateByRunID(ctx context.Context, arg GetLatestAgentRunStateByRunIDParams) (AgentRunState, error)
//GetRecallItem
//
// SELECT id,
@ -134,6 +336,8 @@ type Querier interface {
// updated_at
// FROM recall_items
// WHERE id = ?1
// AND agent_id = ?2
// LIMIT 1
GetRecallItem(ctx context.Context, arg GetRecallItemParams) (RecallItem, error)
//GetRecallItemsByIDs
//
@ -151,6 +355,7 @@ type Querier interface {
// updated_at
// FROM recall_items
// WHERE id IN (/*SLICE:ids*/?)
// AND agent_id = ?2
GetRecallItemsByIDs(ctx context.Context, arg GetRecallItemsByIDsParams) ([]RecallItem, error)
// Working Context queries
//
@ -161,6 +366,7 @@ type Querier interface {
// FROM working_context
// WHERE agent_id = ?1
// AND session_key = ?2
// LIMIT 1
GetWorkingContext(ctx context.Context, arg GetWorkingContextParams) (WorkingContext, error)
// Archival Chunk queries
//
@ -293,19 +499,127 @@ type Querier interface {
// datetime('now')
// )
InsertSummary(ctx context.Context, arg InsertSummaryParams) error
//ListAgentCheckpointsByConversationID
//
// SELECT id, conversation_id, name, run_state_id, metadata_json, created_at, updated_at FROM agent_checkpoints
// WHERE conversation_id = ?
// ORDER BY created_at DESC
// LIMIT ?2
ListAgentCheckpointsByConversationID(ctx context.Context, arg ListAgentCheckpointsByConversationIDParams) ([]AgentCheckpoint, error)
//ListAgentConversationForksByParentConversationID
//
// SELECT id, parent_conversation_id, child_conversation_id, checkpoint_id, metadata_json, created_at, updated_at FROM agent_conversation_forks
// WHERE parent_conversation_id = ?
// ORDER BY created_at DESC
// LIMIT ?2
ListAgentConversationForksByParentConversationID(ctx context.Context, arg ListAgentConversationForksByParentConversationIDParams) ([]AgentConversationFork, error)
//ListAgentConversationLinksByConversationID
//
// SELECT id, conversation_id, linked_conversation_id, kind, metadata_json, created_at, updated_at FROM agent_conversation_links
// WHERE conversation_id = ?
// ORDER BY created_at DESC
// LIMIT ?2
ListAgentConversationLinksByConversationID(ctx context.Context, arg ListAgentConversationLinksByConversationIDParams) ([]AgentConversationLink, error)
//ListAgentConversations
//
// SELECT id, title, created_at, updated_at FROM agent_conversations ORDER BY created_at DESC LIMIT ?
ListAgentConversations(ctx context.Context, arg ListAgentConversationsParams) ([]AgentConversation, error)
//ListAgentMentionsByConversationID
//
// SELECT id, conversation_id, message_id, kind, target_id, raw, metadata_json, created_at, updated_at FROM agent_mentions
// WHERE conversation_id = ?
// ORDER BY created_at DESC
// LIMIT ?2
ListAgentMentionsByConversationID(ctx context.Context, arg ListAgentMentionsByConversationIDParams) ([]AgentMention, error)
//ListAgentMessageRevisionsByMessageID
//
// SELECT id, message_id, editor, old_content, new_content, metadata_json, created_at, updated_at FROM agent_message_revisions
// WHERE message_id = ?
// ORDER BY created_at DESC
// LIMIT ?2
ListAgentMessageRevisionsByMessageID(ctx context.Context, arg ListAgentMessageRevisionsByMessageIDParams) ([]AgentMessageRevision, error)
//ListAgentMessagesByConversationID
//
// SELECT id, conversation_id, role, content, metadata_json, created_at, updated_at FROM agent_messages
// WHERE conversation_id = ?
// ORDER BY created_at ASC
ListAgentMessagesByConversationID(ctx context.Context, arg ListAgentMessagesByConversationIDParams) ([]AgentMessage, error)
//ListAgentMessagesByConversationIDLimit
//
// SELECT id, conversation_id, role, content, metadata_json, created_at, updated_at FROM agent_messages
// WHERE conversation_id = ?
// ORDER BY created_at ASC
// LIMIT ?
ListAgentMessagesByConversationIDLimit(ctx context.Context, arg ListAgentMessagesByConversationIDLimitParams) ([]AgentMessage, error)
//ListAgentRunStatesByRunID
//
// SELECT id, run_id, step_index, state, snapshot_json, created_at, updated_at FROM agent_run_states
// WHERE run_id = ?
// ORDER BY step_index ASC
// LIMIT ?2
ListAgentRunStatesByRunID(ctx context.Context, arg ListAgentRunStatesByRunIDParams) ([]AgentRunState, error)
//ListAgentStateTransitionsByRunID
//
// SELECT id, run_id, step_index, from_state, to_state, "trigger", at, meta_json, error, created_at, updated_at FROM agent_state_transitions
// WHERE run_id = ?
// ORDER BY at ASC
// LIMIT ?2
ListAgentStateTransitionsByRunID(ctx context.Context, arg ListAgentStateTransitionsByRunIDParams) ([]AgentStateTransition, error)
//ListAgentThreadMessagesByThreadID
//
// SELECT id, thread_id, role, content, metadata_json, created_at, updated_at FROM agent_thread_messages
// WHERE thread_id = ?
// ORDER BY created_at ASC
ListAgentThreadMessagesByThreadID(ctx context.Context, arg ListAgentThreadMessagesByThreadIDParams) ([]AgentThreadMessage, error)
//ListAgentThreadMessagesByThreadIDDescLimit
//
// SELECT id, thread_id, role, content, metadata_json, created_at, updated_at FROM agent_thread_messages
// WHERE thread_id = ?
// ORDER BY created_at DESC
// LIMIT ?
ListAgentThreadMessagesByThreadIDDescLimit(ctx context.Context, arg ListAgentThreadMessagesByThreadIDDescLimitParams) ([]AgentThreadMessage, error)
//ListAgentThreadsByConversationID
//
// SELECT id, conversation_id, title, metadata_json, created_at, updated_at FROM agent_threads
// WHERE conversation_id = ?
// ORDER BY created_at DESC
// LIMIT ?2
ListAgentThreadsByConversationID(ctx context.Context, arg ListAgentThreadsByConversationIDParams) ([]AgentThread, error)
//ListAgentToolResultsByConversationID
//
// SELECT id, conversation_id, run_id, step_index, tool_call_id, tool_name, full_key, preview, chunk_count, metadata_json, created_at, updated_at FROM agent_tool_results
// WHERE conversation_id = ?
// ORDER BY created_at DESC
ListAgentToolResultsByConversationID(ctx context.Context, arg ListAgentToolResultsByConversationIDParams) ([]AgentToolResult, error)
//ListAgentToolResultsByConversationIDLimit
//
// SELECT id, conversation_id, run_id, step_index, tool_call_id, tool_name, full_key, preview, chunk_count, metadata_json, created_at, updated_at FROM agent_tool_results
// WHERE conversation_id = ?
// ORDER BY created_at DESC
// LIMIT ?
ListAgentToolResultsByConversationIDLimit(ctx context.Context, arg ListAgentToolResultsByConversationIDLimitParams) ([]AgentToolResult, error)
//ListAgentToolResultsByRunID
//
// SELECT id, conversation_id, run_id, step_index, tool_call_id, tool_name, full_key, preview, chunk_count, metadata_json, created_at, updated_at FROM agent_tool_results
// WHERE run_id = ?
// ORDER BY step_index ASC, created_at ASC
// LIMIT ?2
ListAgentToolResultsByRunID(ctx context.Context, arg ListAgentToolResultsByRunIDParams) ([]AgentToolResult, error)
//ListAllArchivalChunks
//
// SELECT id,
// recall_id,
// chunk_index,
// content,
// embedding,
// source,
// hash,
// created_at
// FROM archival_chunks
// ORDER BY created_at DESC
// LIMIT ?2 OFFSET ?1
// SELECT ac.id,
// ac.recall_id,
// ac.chunk_index,
// ac.content,
// ac.embedding,
// ac.source,
// ac.hash,
// ac.created_at
// FROM archival_chunks ac
// JOIN recall_items ri ON ac.recall_id = ri.id
// WHERE ri.agent_id = ?1
// ORDER BY ac.created_at DESC
// LIMIT ?3 OFFSET ?2
ListAllArchivalChunks(ctx context.Context, arg ListAllArchivalChunksParams) ([]ArchivalChunk, error)
//ListAllDocuments
//
@ -323,20 +637,24 @@ type Querier interface {
// AND is_active = 1
// ORDER BY category,
// name
// LIMIT ?2
ListAllDocuments(ctx context.Context, arg ListAllDocumentsParams) ([]AgentDocument, error)
//ListArchivalChunks
//
// SELECT id,
// recall_id,
// chunk_index,
// content,
// embedding,
// source,
// hash,
// created_at
// FROM archival_chunks
// WHERE recall_id = ?1
// ORDER BY chunk_index
// SELECT ac.id,
// ac.recall_id,
// ac.chunk_index,
// ac.content,
// ac.embedding,
// ac.source,
// ac.hash,
// ac.created_at
// FROM archival_chunks ac
// JOIN recall_items ri ON ac.recall_id = ri.id
// WHERE ac.recall_id = ?1
// AND ri.agent_id = ?2
// ORDER BY ac.chunk_index
// LIMIT ?3
ListArchivalChunks(ctx context.Context, arg ListArchivalChunksParams) ([]ArchivalChunk, error)
//ListAuditEntries
//
@ -404,7 +722,12 @@ type Querier interface {
// AND category = ?2
// AND is_active = 1
// ORDER BY name
// LIMIT ?3
ListDocumentsByCategory(ctx context.Context, arg ListDocumentsByCategoryParams) ([]AgentDocument, error)
//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 FROM jobs ORDER BY created_at DESC LIMIT ?2 OFFSET ?1
ListJobs(ctx context.Context, arg ListJobsParams) ([]Job, error)
//ListKVByPrefix
//
// SELECT agent_id,
@ -483,12 +806,45 @@ type Querier interface {
// ORDER BY created_at DESC
// LIMIT ?3
ListSummaries(ctx context.Context, arg ListSummariesParams) ([]MemorySummary, error)
//MarkJobFailed
//
// UPDATE jobs
// SET status = 'failed',
// completed_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now'),
// updated_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now'),
// last_error = ?1
// WHERE id = ?2
// 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
MarkJobFailed(ctx context.Context, arg MarkJobFailedParams) (Job, error)
//MarkJobSucceeded
//
// UPDATE jobs
// SET status = 'succeeded',
// completed_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now'),
// updated_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now'),
// last_error = NULL
// WHERE id = ?1
// 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
MarkJobSucceeded(ctx context.Context, arg MarkJobSucceededParams) (Job, error)
//PruneOldAuditEntries
//
// DELETE FROM agent_audit_log
// WHERE agent_id = ?1
// AND created_at < ?2
PruneOldAuditEntries(ctx context.Context, arg PruneOldAuditEntriesParams) error
//RequeueJob
//
// UPDATE jobs
// SET status = 'queued',
// run_at = coalesce(?1, strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
// updated_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now'),
// last_error = ?2,
// locked_at = NULL,
// locked_by = NULL,
// completed_at = NULL
// 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
RequeueJob(ctx context.Context, arg RequeueJobParams) (Job, error)
//SearchRecallByKeyword
//
// SELECT ri.id,
@ -509,6 +865,23 @@ type Querier interface {
// ORDER BY ri.importance DESC
// LIMIT ?3
SearchRecallByKeyword(ctx context.Context, arg SearchRecallByKeywordParams) ([]RecallItem, error)
//UpdateAgentConversationTitle
//
// UPDATE agent_conversations
// SET title = ?,
// updated_at = (strftime('%Y-%m-%dT%H:%M:%fZ', 'now'))
// WHERE id = ?
// RETURNING id, title, created_at, updated_at
UpdateAgentConversationTitle(ctx context.Context, arg UpdateAgentConversationTitleParams) (AgentConversation, error)
//UpdateAgentRunStatus
//
// UPDATE agent_runs
// SET status = ?,
// metadata_json = ?,
// updated_at = (strftime('%Y-%m-%dT%H:%M:%fZ', 'now'))
// WHERE id = ?
// RETURNING id, conversation_id, status, metadata_json, created_at, updated_at
UpdateAgentRunStatus(ctx context.Context, arg UpdateAgentRunStatusParams) (AgentRun, error)
//UpdateRecallItem
//
// UPDATE recall_items
@ -521,6 +894,7 @@ type Querier interface {
// tags = ?7,
// updated_at = datetime('now')
// WHERE id = ?8
// AND agent_id = ?9
UpdateRecallItem(ctx context.Context, arg UpdateRecallItemParams) error
//UpsertDocument
//

View file

@ -0,0 +1,21 @@
-- name: CreateAgentConversationFork :one
INSERT INTO agent_conversation_forks (
id,
parent_conversation_id,
child_conversation_id,
checkpoint_id,
metadata_json
)
VALUES (?, ?, ?, ?, ?)
RETURNING *;
-- name: ListAgentConversationForksByParentConversationID :many
SELECT *
FROM agent_conversation_forks
WHERE parent_conversation_id = ?
ORDER BY created_at DESC
LIMIT sqlc.arg(lim);
-- name: GetAgentConversationForkByChildConversationID :one
SELECT *
FROM agent_conversation_forks
WHERE child_conversation_id = ?
LIMIT 1;

View file

@ -0,0 +1,21 @@
-- name: CreateAgentConversationLink :one
INSERT INTO agent_conversation_links (
id,
conversation_id,
linked_conversation_id,
kind,
metadata_json
)
VALUES (?, ?, ?, ?, ?)
RETURNING *;
-- name: ListAgentConversationLinksByConversationID :many
SELECT *
FROM agent_conversation_links
WHERE conversation_id = ?
ORDER BY created_at DESC
LIMIT sqlc.arg(lim);
-- name: DeleteAgentConversationLink :exec
DELETE FROM agent_conversation_links
WHERE conversation_id = ?
AND linked_conversation_id = ?
AND kind = ?;

View file

@ -0,0 +1,20 @@
-- name: CreateAgentConversation :one
INSERT INTO agent_conversations (id, title)
VALUES (?, ?)
RETURNING *;
-- name: GetAgentConversation :one
SELECT *
FROM agent_conversations
WHERE id = ?
LIMIT 1;
-- name: ListAgentConversations :many
SELECT *
FROM agent_conversations
ORDER BY created_at DESC
LIMIT ?;
-- name: UpdateAgentConversationTitle :one
UPDATE agent_conversations
SET title = ?,
updated_at = (strftime('%Y-%m-%dT%H:%M:%fZ', 'now'))
WHERE id = ?
RETURNING *;

View file

@ -11,7 +11,8 @@ SELECT id,
updated_at
FROM agent_documents
WHERE agent_id = sqlc.arg(agent_id)
AND name = sqlc.arg(name);
AND name = sqlc.arg(name)
LIMIT 1;
-- name: UpsertDocument :exec
INSERT INTO agent_documents (
id,
@ -55,7 +56,8 @@ FROM agent_documents
WHERE agent_id = sqlc.arg(agent_id)
AND category = sqlc.arg(category)
AND is_active = 1
ORDER BY name;
ORDER BY name
LIMIT sqlc.arg(lim);
-- name: DeleteDocument :exec
DELETE FROM agent_documents
WHERE agent_id = sqlc.arg(agent_id)
@ -74,4 +76,5 @@ FROM agent_documents
WHERE agent_id = sqlc.arg(agent_id)
AND is_active = 1
ORDER BY category,
name;
name
LIMIT sqlc.arg(lim);

View file

@ -6,7 +6,8 @@ SELECT agent_id,
updated_at
FROM agent_kv
WHERE agent_id = sqlc.arg(agent_id)
AND key = sqlc.arg(key);
AND key = sqlc.arg(key)
LIMIT 1;
-- name: UpsertKV :exec
INSERT INTO agent_kv (agent_id, key, value, updated_at)
VALUES (

View file

@ -0,0 +1,18 @@
-- name: AddAgentMention :one
INSERT INTO agent_mentions (
id,
conversation_id,
message_id,
kind,
target_id,
raw,
metadata_json
)
VALUES (?, ?, ?, ?, ?, ?, ?)
RETURNING *;
-- name: ListAgentMentionsByConversationID :many
SELECT *
FROM agent_mentions
WHERE conversation_id = ?
ORDER BY created_at DESC
LIMIT sqlc.arg(lim);

View file

@ -0,0 +1,17 @@
-- name: AddAgentMessageRevision :one
INSERT INTO agent_message_revisions (
id,
message_id,
editor,
old_content,
new_content,
metadata_json
)
VALUES (?, ?, ?, ?, ?, ?)
RETURNING *;
-- name: ListAgentMessageRevisionsByMessageID :many
SELECT *
FROM agent_message_revisions
WHERE message_id = ?
ORDER BY created_at DESC
LIMIT sqlc.arg(lim);

View file

@ -0,0 +1,21 @@
-- name: AddAgentMessage :one
INSERT INTO agent_messages (
id,
conversation_id,
role,
content,
metadata_json
)
VALUES (?, ?, ?, ?, ?)
RETURNING *;
-- name: ListAgentMessagesByConversationID :many
SELECT *
FROM agent_messages
WHERE conversation_id = ?
ORDER BY created_at ASC;
-- name: ListAgentMessagesByConversationIDLimit :many
SELECT *
FROM agent_messages
WHERE conversation_id = ?
ORDER BY created_at ASC
LIMIT ?;

View file

@ -0,0 +1,80 @@
-- name: CreateAgentRun :one
INSERT INTO agent_runs (id, conversation_id, status, metadata_json)
VALUES (?, ?, ?, ?)
RETURNING *;
-- name: UpdateAgentRunStatus :one
UPDATE agent_runs
SET status = ?,
metadata_json = ?,
updated_at = (strftime('%Y-%m-%dT%H:%M:%fZ', 'now'))
WHERE id = ?
RETURNING *;
-- name: GetLatestAgentRunByConversationID :one
SELECT *
FROM agent_runs
WHERE conversation_id = ?
ORDER BY created_at DESC
LIMIT 1;
-- name: AddAgentRunState :one
INSERT INTO agent_run_states (id, run_id, step_index, state, snapshot_json)
VALUES (?, ?, ?, ?, ?)
RETURNING *;
-- name: ListAgentRunStatesByRunID :many
SELECT *
FROM agent_run_states
WHERE run_id = ?
ORDER BY step_index ASC
LIMIT sqlc.arg(lim);
-- name: GetLatestAgentRunStateByRunID :one
SELECT *
FROM agent_run_states
WHERE run_id = ?
ORDER BY step_index DESC
LIMIT 1;
-- name: GetAgentRunStateByID :one
SELECT *
FROM agent_run_states
WHERE id = ?
LIMIT 1;
-- name: AddAgentStateTransition :one
INSERT INTO agent_state_transitions (
id,
run_id,
step_index,
from_state,
to_state,
trigger,
at,
meta_json,
error
)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
RETURNING *;
-- name: ListAgentStateTransitionsByRunID :many
SELECT *
FROM agent_state_transitions
WHERE run_id = ?
ORDER BY at ASC
LIMIT sqlc.arg(lim);
-- name: CreateAgentCheckpoint :one
INSERT INTO agent_checkpoints (
id,
conversation_id,
name,
run_state_id,
metadata_json
)
VALUES (?, ?, ?, ?, ?)
RETURNING *;
-- name: ListAgentCheckpointsByConversationID :many
SELECT *
FROM agent_checkpoints
WHERE conversation_id = ?
ORDER BY created_at DESC
LIMIT sqlc.arg(lim);
-- name: GetAgentCheckpointByConversationIDAndName :one
SELECT *
FROM agent_checkpoints
WHERE conversation_id = ?
AND name = ?
LIMIT 1;

View file

@ -0,0 +1,25 @@
-- name: CreateAgentThread :one
INSERT INTO agent_threads (id, conversation_id, title, metadata_json)
VALUES (?, ?, ?, ?)
RETURNING *;
-- name: ListAgentThreadsByConversationID :many
SELECT *
FROM agent_threads
WHERE conversation_id = ?
ORDER BY created_at DESC
LIMIT sqlc.arg(lim);
-- name: AddAgentThreadMessage :one
INSERT INTO agent_thread_messages (id, thread_id, role, content, metadata_json)
VALUES (?, ?, ?, ?, ?)
RETURNING *;
-- name: ListAgentThreadMessagesByThreadID :many
SELECT *
FROM agent_thread_messages
WHERE thread_id = ?
ORDER BY created_at ASC;
-- name: ListAgentThreadMessagesByThreadIDDescLimit :many
SELECT *
FROM agent_thread_messages
WHERE thread_id = ?
ORDER BY created_at DESC
LIMIT ?;

View file

@ -0,0 +1,39 @@
-- name: AddAgentToolResult :one
INSERT INTO agent_tool_results (
id,
conversation_id,
run_id,
step_index,
tool_call_id,
tool_name,
full_key,
preview,
chunk_count,
metadata_json
)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
RETURNING *;
-- name: GetAgentToolResultByRunIDAndToolCallID :one
SELECT *
FROM agent_tool_results
WHERE run_id = ?
AND tool_call_id = ?
LIMIT 1;
-- name: ListAgentToolResultsByConversationID :many
SELECT *
FROM agent_tool_results
WHERE conversation_id = ?
ORDER BY created_at DESC;
-- name: ListAgentToolResultsByConversationIDLimit :many
SELECT *
FROM agent_tool_results
WHERE conversation_id = ?
ORDER BY created_at DESC
LIMIT ?;
-- name: ListAgentToolResultsByRunID :many
SELECT *
FROM agent_tool_results
WHERE run_id = ?
ORDER BY step_index ASC,
created_at ASC
LIMIT sqlc.arg(lim);

View file

@ -21,54 +21,66 @@ VALUES (
datetime('now')
);
-- name: GetArchivalChunk :one
SELECT id,
recall_id,
chunk_index,
content,
embedding,
source,
hash,
created_at
FROM archival_chunks
WHERE id = sqlc.arg(id);
SELECT ac.id,
ac.recall_id,
ac.chunk_index,
ac.content,
ac.embedding,
ac.source,
ac.hash,
ac.created_at
FROM archival_chunks ac
JOIN recall_items ri ON ac.recall_id = ri.id
WHERE ac.id = sqlc.arg(id)
AND ri.agent_id = sqlc.arg(agent_id)
LIMIT 1;
-- name: ListArchivalChunks :many
SELECT id,
recall_id,
chunk_index,
content,
embedding,
source,
hash,
created_at
FROM archival_chunks
WHERE recall_id = sqlc.arg(recall_id)
ORDER BY chunk_index;
SELECT ac.id,
ac.recall_id,
ac.chunk_index,
ac.content,
ac.embedding,
ac.source,
ac.hash,
ac.created_at
FROM archival_chunks ac
JOIN recall_items ri ON ac.recall_id = ri.id
WHERE ac.recall_id = sqlc.arg(recall_id)
AND ri.agent_id = sqlc.arg(agent_id)
ORDER BY ac.chunk_index
LIMIT sqlc.arg(lim);
-- name: DeleteArchivalChunksByRecall :exec
DELETE FROM archival_chunks
WHERE recall_id = sqlc.arg(recall_id);
-- name: CountArchivalChunks :one
SELECT COUNT(*)
FROM archival_chunks;
FROM archival_chunks ac
JOIN recall_items ri ON ac.recall_id = ri.id
WHERE ri.agent_id = sqlc.arg(agent_id);
-- name: ListAllArchivalChunks :many
SELECT id,
recall_id,
chunk_index,
content,
embedding,
source,
hash,
created_at
FROM archival_chunks
ORDER BY created_at DESC
SELECT ac.id,
ac.recall_id,
ac.chunk_index,
ac.content,
ac.embedding,
ac.source,
ac.hash,
ac.created_at
FROM archival_chunks ac
JOIN recall_items ri ON ac.recall_id = ri.id
WHERE ri.agent_id = sqlc.arg(agent_id)
ORDER BY ac.created_at DESC
LIMIT sqlc.arg(lim) OFFSET sqlc.arg(off);
-- name: GetArchivalChunksByIDs :many
SELECT id,
recall_id,
chunk_index,
content,
embedding,
source,
hash,
created_at
FROM archival_chunks
WHERE id IN (sqlc.slice('ids'));
SELECT ac.id,
ac.recall_id,
ac.chunk_index,
ac.content,
ac.embedding,
ac.source,
ac.hash,
ac.created_at
FROM archival_chunks ac
JOIN recall_items ri ON ac.recall_id = ri.id
WHERE ac.id IN (sqlc.slice('ids'))
AND ri.agent_id = sqlc.arg(agent_id);

View file

@ -0,0 +1,96 @@
-- name: EnqueueJob :one
INSERT INTO jobs (
id,
kind,
status,
run_at,
max_attempts,
payload_json,
dedupe_key
)
VALUES (
sqlc.arg(id),
sqlc.arg(kind),
'queued',
coalesce(
sqlc.arg(run_at),
strftime('%Y-%m-%dT%H:%M:%fZ', 'now')
),
coalesce(sqlc.arg(max_attempts), 3),
coalesce(sqlc.arg(payload_json), '{}'),
sqlc.arg(dedupe_key)
) ON CONFLICT(kind, dedupe_key)
WHERE dedupe_key IS NOT NULL DO
UPDATE
SET status = 'queued',
run_at = excluded.run_at,
max_attempts = excluded.max_attempts,
payload_json = excluded.payload_json,
attempts = 0,
last_error = NULL,
updated_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now')
RETURNING *;
-- name: FindNextRunnableJob :one
SELECT id
FROM jobs
WHERE status = 'queued'
AND run_at <= strftime('%Y-%m-%dT%H:%M:%fZ', 'now')
ORDER BY run_at ASC,
created_at ASC
LIMIT 1;
-- name: ClaimJobByID :one
UPDATE jobs
SET status = 'running',
attempts = attempts + 1,
locked_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now'),
locked_by = sqlc.arg(locked_by),
updated_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now'),
last_error = NULL
WHERE id = sqlc.arg(id)
AND status = 'queued'
RETURNING *;
-- name: MarkJobSucceeded :one
UPDATE jobs
SET status = 'succeeded',
completed_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now'),
updated_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now'),
last_error = NULL
WHERE id = sqlc.arg(id)
RETURNING *;
-- name: RequeueJob :one
UPDATE jobs
SET status = 'queued',
run_at = coalesce(
sqlc.arg(run_at),
strftime('%Y-%m-%dT%H:%M:%fZ', 'now')
),
updated_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now'),
last_error = sqlc.arg(last_error),
locked_at = NULL,
locked_by = NULL,
completed_at = NULL
WHERE id = sqlc.arg(id)
RETURNING *;
-- name: MarkJobFailed :one
UPDATE jobs
SET status = 'failed',
completed_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now'),
updated_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now'),
last_error = sqlc.arg(last_error)
WHERE id = sqlc.arg(id)
RETURNING *;
-- name: GetJob :one
SELECT *
FROM jobs
WHERE id = sqlc.arg(id)
LIMIT 1;
-- name: ListJobs :many
SELECT *
FROM jobs
ORDER BY created_at DESC
LIMIT sqlc.arg(lim) OFFSET sqlc.arg(off);
-- name: CountJobsByStatus :many
SELECT status,
count(*) AS count
FROM jobs
GROUP BY status;

View file

@ -42,7 +42,9 @@ SELECT id,
created_at,
updated_at
FROM recall_items
WHERE id = sqlc.arg(id);
WHERE id = sqlc.arg(id)
AND agent_id = sqlc.arg(agent_id)
LIMIT 1;
-- name: UpdateRecallItem :exec
UPDATE recall_items
SET role = sqlc.arg(role),
@ -53,10 +55,12 @@ SET role = sqlc.arg(role),
content = sqlc.arg(content),
tags = sqlc.arg(tags),
updated_at = datetime('now')
WHERE id = sqlc.arg(id);
WHERE id = sqlc.arg(id)
AND agent_id = sqlc.arg(agent_id);
-- name: DeleteRecallItem :exec
DELETE FROM recall_items
WHERE id = sqlc.arg(id);
WHERE id = sqlc.arg(id)
AND agent_id = sqlc.arg(agent_id);
-- name: ListRecallItems :many
SELECT id,
agent_id,
@ -118,7 +122,8 @@ SELECT id,
created_at,
updated_at
FROM recall_items
WHERE id IN (sqlc.slice('ids'));
WHERE id IN (sqlc.slice('ids'))
AND agent_id = sqlc.arg(agent_id);
-- name: InsertSessionMessage :exec
INSERT INTO recall_items (
id,

View file

@ -6,7 +6,8 @@ SELECT agent_id,
updated_at
FROM working_context
WHERE agent_id = sqlc.arg(agent_id)
AND session_key = sqlc.arg(session_key);
AND session_key = sqlc.arg(session_key)
LIMIT 1;
-- name: UpsertWorkingContext :exec
INSERT INTO working_context (agent_id, session_key, content, updated_at)
VALUES (

View file

@ -24,8 +24,8 @@ WHERE agent_id = ?1
`
type CountRecallItemsParams struct {
AgentID string `json:"agent_id"`
SessionKey string `json:"session_key"`
AgentID string `db:"agent_id" json:"agent_id"`
SessionKey string `db:"session_key" json:"session_key"`
}
// CountRecallItems
@ -53,8 +53,8 @@ WHERE agent_id = ?1
`
type CountSessionMessagesParams struct {
AgentID string `json:"agent_id"`
SessionKey string `json:"session_key"`
AgentID string `db:"agent_id" json:"agent_id"`
SessionKey string `db:"session_key" json:"session_key"`
}
// CountSessionMessages
@ -74,18 +74,21 @@ func (q *Queries) CountSessionMessages(ctx context.Context, arg CountSessionMess
const DeleteRecallItem = `-- name: DeleteRecallItem :exec
DELETE FROM recall_items
WHERE id = ?1
AND agent_id = ?2
`
type DeleteRecallItemParams struct {
ID ids.UUID `json:"id"`
ID ids.UUID `db:"id" json:"id"`
AgentID string `db:"agent_id" json:"agent_id"`
}
// DeleteRecallItem
//
// DELETE FROM recall_items
// WHERE id = ?1
// AND agent_id = ?2
func (q *Queries) DeleteRecallItem(ctx context.Context, arg DeleteRecallItemParams) error {
_, err := q.db.ExecContext(ctx, DeleteRecallItem, arg.ID)
_, err := q.db.ExecContext(ctx, DeleteRecallItem, arg.ID, arg.AgentID)
return err
}
@ -104,10 +107,13 @@ SELECT id,
updated_at
FROM recall_items
WHERE id = ?1
AND agent_id = ?2
LIMIT 1
`
type GetRecallItemParams struct {
ID ids.UUID `json:"id"`
ID ids.UUID `db:"id" json:"id"`
AgentID string `db:"agent_id" json:"agent_id"`
}
// GetRecallItem
@ -126,8 +132,10 @@ type GetRecallItemParams struct {
// updated_at
// FROM recall_items
// WHERE id = ?1
// AND agent_id = ?2
// LIMIT 1
func (q *Queries) GetRecallItem(ctx context.Context, arg GetRecallItemParams) (RecallItem, error) {
row := q.db.QueryRowContext(ctx, GetRecallItem, arg.ID)
row := q.db.QueryRowContext(ctx, GetRecallItem, arg.ID, arg.AgentID)
var i RecallItem
err := row.Scan(
&i.ID,
@ -161,10 +169,12 @@ SELECT id,
updated_at
FROM recall_items
WHERE id IN (/*SLICE:ids*/?)
AND agent_id = ?2
`
type GetRecallItemsByIDsParams struct {
Ids []ids.UUID `json:"ids"`
Ids []ids.UUID `db:"ids" json:"ids"`
AgentID string `db:"agent_id" json:"agent_id"`
}
// GetRecallItemsByIDs
@ -183,6 +193,7 @@ type GetRecallItemsByIDsParams struct {
// updated_at
// FROM recall_items
// WHERE id IN (/*SLICE:ids*/?)
// AND agent_id = ?2
func (q *Queries) GetRecallItemsByIDs(ctx context.Context, arg GetRecallItemsByIDsParams) ([]RecallItem, error) {
query := GetRecallItemsByIDs
var queryParams []interface{}
@ -194,6 +205,7 @@ func (q *Queries) GetRecallItemsByIDs(ctx context.Context, arg GetRecallItemsByI
} else {
query = strings.Replace(query, "/*SLICE:ids*/?", "NULL", 1)
}
queryParams = append(queryParams, arg.AgentID)
rows, err := q.db.QueryContext(ctx, query, queryParams...)
if err != nil {
return nil, err
@ -261,16 +273,16 @@ VALUES (
`
type InsertRecallItemParams struct {
ID ids.UUID `json:"id"`
AgentID string `json:"agent_id"`
SessionKey string `json:"session_key"`
Role string `json:"role"`
Sector memory.Sector `json:"sector"`
Importance float64 `json:"importance"`
Salience float64 `json:"salience"`
DecayRate float64 `json:"decay_rate"`
Content string `json:"content"`
Tags string `json:"tags"`
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"`
}
// Recall Item queries
@ -351,11 +363,11 @@ VALUES (
`
type InsertSessionMessageParams struct {
ID ids.UUID `json:"id"`
AgentID string `json:"agent_id"`
SessionKey string `json:"session_key"`
Role string `json:"role"`
Content string `json:"content"`
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"`
Content string `db:"content" json:"content"`
}
// InsertSessionMessage
@ -423,10 +435,10 @@ LIMIT ?4 OFFSET ?3
`
type ListRecallItemsParams struct {
AgentID string `json:"agent_id"`
SessionKey string `json:"session_key"`
Off int64 `json:"off"`
Lim int64 `json:"lim"`
AgentID string `db:"agent_id" json:"agent_id"`
SessionKey string `db:"session_key" json:"session_key"`
Off int64 `db:"off" json:"off"`
Lim int64 `db:"lim" json:"lim"`
}
// ListRecallItems
@ -518,10 +530,10 @@ LIMIT ?4
`
type ListSessionMessagesParams struct {
AgentID string `json:"agent_id"`
SessionKey string `json:"session_key"`
Role string `json:"role"`
Lim int64 `json:"lim"`
AgentID string `db:"agent_id" json:"agent_id"`
SessionKey string `db:"session_key" json:"session_key"`
Role string `db:"role" json:"role"`
Lim int64 `db:"lim" json:"lim"`
}
// ListSessionMessages
@ -610,9 +622,9 @@ LIMIT ?3
`
type SearchRecallByKeywordParams struct {
Keyword *string `json:"keyword"`
AgentID string `json:"agent_id"`
Lim int64 `json:"lim"`
Keyword *string `db:"keyword" json:"keyword"`
AgentID string `db:"agent_id" json:"agent_id"`
Lim int64 `db:"lim" json:"lim"`
}
// SearchRecallByKeyword
@ -681,17 +693,19 @@ SET role = ?1,
tags = ?7,
updated_at = datetime('now')
WHERE id = ?8
AND agent_id = ?9
`
type UpdateRecallItemParams struct {
Role string `json:"role"`
Sector memory.Sector `json:"sector"`
Importance float64 `json:"importance"`
Salience float64 `json:"salience"`
DecayRate float64 `json:"decay_rate"`
Content string `json:"content"`
Tags string `json:"tags"`
ID ids.UUID `json:"id"`
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"`
ID ids.UUID `db:"id" json:"id"`
AgentID string `db:"agent_id" json:"agent_id"`
}
// UpdateRecallItem
@ -706,6 +720,7 @@ type UpdateRecallItemParams struct {
// tags = ?7,
// updated_at = datetime('now')
// WHERE id = ?8
// AND agent_id = ?9
func (q *Queries) UpdateRecallItem(ctx context.Context, arg UpdateRecallItemParams) error {
_, err := q.db.ExecContext(ctx, UpdateRecallItem,
arg.Role,
@ -716,6 +731,7 @@ func (q *Queries) UpdateRecallItem(ctx context.Context, arg UpdateRecallItemPara
arg.Content,
arg.Tags,
arg.ID,
arg.AgentID,
)
return err
}

View file

@ -95,4 +95,190 @@ CREATE TABLE IF NOT EXISTS agent_audit_log (
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX IF NOT EXISTS idx_audit_agent_time ON agent_audit_log(agent_id, created_at DESC);
CREATE INDEX IF NOT EXISTS idx_audit_action ON agent_audit_log(action);
CREATE INDEX IF NOT EXISTS idx_audit_action ON agent_audit_log(action);
-- ============================================================================
-- Agent Runtime State Tables
-- ============================================================================
-- Conversations: minimal parent entity for agent runs and messages.
CREATE TABLE IF NOT EXISTS agent_conversations (
id BLOB PRIMARY KEY,
title TEXT,
created_at DATETIME NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
updated_at DATETIME NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now'))
);
-- Messages: conversation turns.
CREATE TABLE IF NOT EXISTS agent_messages (
id BLOB PRIMARY KEY,
conversation_id BLOB NOT NULL REFERENCES agent_conversations(id) ON DELETE CASCADE,
role TEXT NOT NULL,
content TEXT NOT NULL,
metadata_json JSON NOT NULL DEFAULT '{}',
created_at DATETIME NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
updated_at DATETIME NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now'))
);
CREATE INDEX IF NOT EXISTS idx_agent_messages_conversation_created_at ON agent_messages(conversation_id, created_at);
-- Runs: a single invocation of the agent runtime (one RunTurn call).
CREATE TABLE IF NOT EXISTS agent_runs (
id BLOB PRIMARY KEY,
conversation_id BLOB NOT NULL REFERENCES agent_conversations(id) ON DELETE CASCADE,
status TEXT NOT NULL DEFAULT 'running',
metadata_json JSON NOT NULL DEFAULT '{}',
created_at DATETIME NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
updated_at DATETIME NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now'))
);
CREATE INDEX IF NOT EXISTS idx_agent_runs_conversation_created_at ON agent_runs(conversation_id, created_at);
-- Run states: snapshots captured per step.
CREATE TABLE IF NOT EXISTS agent_run_states (
id BLOB PRIMARY KEY,
run_id BLOB NOT NULL REFERENCES agent_runs(id) ON DELETE CASCADE,
step_index INTEGER NOT NULL,
state TEXT NOT NULL,
snapshot_json JSON NOT NULL DEFAULT '{}',
created_at DATETIME NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
updated_at DATETIME NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
UNIQUE(run_id, step_index)
);
CREATE INDEX IF NOT EXISTS idx_agent_run_states_run_step ON agent_run_states(run_id, step_index);
-- Transition log: debugging and resumability.
CREATE TABLE IF NOT EXISTS agent_state_transitions (
id BLOB PRIMARY KEY,
run_id BLOB NOT NULL REFERENCES agent_runs(id) ON DELETE CASCADE,
step_index INTEGER NOT NULL,
from_state TEXT NOT NULL,
to_state TEXT NOT NULL,
trigger TEXT NOT NULL,
at DATETIME NOT NULL,
meta_json JSON NOT NULL DEFAULT '{}',
error TEXT,
created_at DATETIME NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
updated_at DATETIME NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now'))
);
CREATE INDEX IF NOT EXISTS idx_agent_state_transitions_run_step_at ON agent_state_transitions(run_id, step_index, at);
-- Checkpoints: named snapshots for later restore.
CREATE TABLE IF NOT EXISTS agent_checkpoints (
id BLOB PRIMARY KEY,
conversation_id BLOB NOT NULL REFERENCES agent_conversations(id) ON DELETE CASCADE,
name TEXT NOT NULL,
run_state_id BLOB NOT NULL REFERENCES agent_run_states(id) ON DELETE RESTRICT,
metadata_json JSON NOT NULL DEFAULT '{}',
created_at DATETIME NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
updated_at DATETIME NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
UNIQUE(conversation_id, name)
);
CREATE INDEX IF NOT EXISTS idx_agent_checkpoints_conversation_created_at ON agent_checkpoints(conversation_id, created_at);
-- Tool results: offloaded tool outputs.
CREATE TABLE IF NOT EXISTS agent_tool_results (
id BLOB PRIMARY KEY,
conversation_id BLOB NOT NULL REFERENCES agent_conversations(id) ON DELETE CASCADE,
run_id BLOB NOT NULL REFERENCES agent_runs(id) ON DELETE CASCADE,
step_index INTEGER NOT NULL,
tool_call_id TEXT NOT NULL,
tool_name TEXT NOT NULL,
full_key TEXT NOT NULL,
preview TEXT,
chunk_count INTEGER NOT NULL DEFAULT 0,
metadata_json JSON NOT NULL DEFAULT '{}',
created_at DATETIME NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
updated_at DATETIME NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
UNIQUE(run_id, tool_call_id)
);
CREATE INDEX IF NOT EXISTS idx_agent_tool_results_conversation_created_at ON agent_tool_results(conversation_id, created_at);
CREATE INDEX IF NOT EXISTS idx_agent_tool_results_run_step ON agent_tool_results(run_id, step_index);
CREATE INDEX IF NOT EXISTS idx_agent_tool_results_tool_name ON agent_tool_results(tool_name);
-- ============================================================================
-- Job Queue
-- ============================================================================
CREATE TABLE IF NOT EXISTS jobs (
id BLOB PRIMARY KEY,
kind TEXT NOT NULL,
status TEXT NOT NULL,
run_at DATETIME NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
attempts INTEGER NOT NULL DEFAULT 0,
max_attempts INTEGER NOT NULL DEFAULT 3,
locked_at DATETIME,
locked_by TEXT,
payload_json JSON NOT NULL DEFAULT '{}',
dedupe_key TEXT,
last_error TEXT,
created_at DATETIME NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
updated_at DATETIME NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
completed_at DATETIME
);
CREATE INDEX IF NOT EXISTS idx_jobs_status_run_at ON jobs(status, run_at);
CREATE UNIQUE INDEX IF NOT EXISTS idx_jobs_kind_dedupe ON jobs(kind, dedupe_key)
WHERE dedupe_key IS NOT NULL;
-- ============================================================================
-- Conversation Graph (forks, links, threads, mentions, edits)
-- ============================================================================
-- Forks: parent→child conversation via checkpoint.
CREATE TABLE IF NOT EXISTS agent_conversation_forks (
id BLOB PRIMARY KEY,
parent_conversation_id BLOB NOT NULL REFERENCES agent_conversations(id) ON DELETE CASCADE,
child_conversation_id BLOB NOT NULL REFERENCES agent_conversations(id) ON DELETE CASCADE,
checkpoint_id BLOB NOT NULL REFERENCES agent_checkpoints(id) ON DELETE RESTRICT,
metadata_json JSON NOT NULL DEFAULT '{}',
created_at DATETIME NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
updated_at DATETIME NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
UNIQUE(child_conversation_id)
);
CREATE INDEX IF NOT EXISTS idx_agent_conversation_forks_parent_created_at ON agent_conversation_forks(parent_conversation_id, created_at DESC);
-- Links: user-created relationships between conversations (merge, reference, etc.).
CREATE TABLE IF NOT EXISTS agent_conversation_links (
id BLOB PRIMARY KEY,
conversation_id BLOB NOT NULL REFERENCES agent_conversations(id) ON DELETE CASCADE,
linked_conversation_id BLOB NOT NULL REFERENCES agent_conversations(id) ON DELETE CASCADE,
kind TEXT NOT NULL DEFAULT 'merge',
metadata_json JSON NOT NULL DEFAULT '{}',
created_at DATETIME NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
updated_at DATETIME NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
UNIQUE(conversation_id, linked_conversation_id, kind)
);
CREATE INDEX IF NOT EXISTS idx_agent_conversation_links_conversation_id_created_at ON agent_conversation_links(conversation_id, created_at DESC);
-- Threads: sub-conversations within a main conversation.
CREATE TABLE IF NOT EXISTS agent_threads (
id BLOB PRIMARY KEY,
conversation_id BLOB NOT NULL REFERENCES agent_conversations(id) ON DELETE CASCADE,
title TEXT,
metadata_json JSON NOT NULL DEFAULT '{}',
created_at DATETIME NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
updated_at DATETIME NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now'))
);
CREATE INDEX IF NOT EXISTS idx_agent_threads_conversation_id_created_at ON agent_threads(conversation_id, created_at DESC);
-- Thread messages.
CREATE TABLE IF NOT EXISTS agent_thread_messages (
id BLOB PRIMARY KEY,
thread_id BLOB NOT NULL REFERENCES agent_threads(id) ON DELETE CASCADE,
role TEXT NOT NULL,
content TEXT NOT NULL,
metadata_json JSON NOT NULL DEFAULT '{}',
created_at DATETIME NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
updated_at DATETIME NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now'))
);
CREATE INDEX IF NOT EXISTS idx_agent_thread_messages_thread_id_created_at ON agent_thread_messages(thread_id, created_at ASC);
-- Mentions: captured from messages (conversation, thread, file references).
CREATE TABLE IF NOT EXISTS agent_mentions (
id BLOB PRIMARY KEY,
conversation_id BLOB NOT NULL REFERENCES agent_conversations(id) ON DELETE CASCADE,
message_id BLOB REFERENCES agent_messages(id) ON DELETE
SET NULL,
kind TEXT NOT NULL,
target_id BLOB NOT NULL,
raw TEXT NOT NULL,
metadata_json JSON NOT NULL DEFAULT '{}',
created_at DATETIME NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
updated_at DATETIME NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now'))
);
CREATE INDEX IF NOT EXISTS idx_agent_mentions_conversation_id_created_at ON agent_mentions(conversation_id, created_at DESC);
CREATE INDEX IF NOT EXISTS idx_agent_mentions_kind_target_id ON agent_mentions(kind, target_id);
-- Message revisions: edit history.
CREATE TABLE IF NOT EXISTS agent_message_revisions (
id BLOB PRIMARY KEY,
message_id BLOB NOT NULL REFERENCES agent_messages(id) ON DELETE CASCADE,
editor TEXT NOT NULL,
old_content TEXT NOT NULL,
new_content TEXT NOT NULL,
metadata_json JSON NOT NULL DEFAULT '{}',
created_at DATETIME NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
updated_at DATETIME NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now'))
);
CREATE INDEX IF NOT EXISTS idx_agent_message_revisions_message_id_created_at ON agent_message_revisions(message_id, created_at DESC);

View file

@ -9,6 +9,7 @@ sql:
out: "."
sql_package: "database/sql"
emit_json_tags: true
emit_db_tags: true
json_tags_case_style: "snake"
emit_empty_slices: true
emit_interface: true
@ -22,7 +23,7 @@ sql:
query_parameter_limit: 0
initialisms: ["id", "url", "api", "sql", "fts", "uuid"]
overrides:
# Entity IDs: UUIDv7 via ids.UUID (TEXT storage with Valuer/Scanner)
# Entity IDs: UUIDv7 via ids.UUID (BLOB storage with Valuer/Scanner)
# Only entity-owned PKs and their FKs — NOT agent_id/session_key (external identifiers)
- column: "recall_items.id"
go_type:
@ -48,6 +49,152 @@ sql:
go_type:
import: "github.com/sipeed/picoclaw/pkg/ids"
type: "UUID"
# Agent conversations
- column: "agent_conversations.id"
go_type:
import: "github.com/sipeed/picoclaw/pkg/ids"
type: "UUID"
# Agent messages
- column: "agent_messages.id"
go_type:
import: "github.com/sipeed/picoclaw/pkg/ids"
type: "UUID"
- column: "agent_messages.conversation_id"
go_type:
import: "github.com/sipeed/picoclaw/pkg/ids"
type: "UUID"
# Agent runs
- column: "agent_runs.id"
go_type:
import: "github.com/sipeed/picoclaw/pkg/ids"
type: "UUID"
- column: "agent_runs.conversation_id"
go_type:
import: "github.com/sipeed/picoclaw/pkg/ids"
type: "UUID"
# Agent run states
- column: "agent_run_states.id"
go_type:
import: "github.com/sipeed/picoclaw/pkg/ids"
type: "UUID"
- column: "agent_run_states.run_id"
go_type:
import: "github.com/sipeed/picoclaw/pkg/ids"
type: "UUID"
# Agent state transitions
- column: "agent_state_transitions.id"
go_type:
import: "github.com/sipeed/picoclaw/pkg/ids"
type: "UUID"
- column: "agent_state_transitions.run_id"
go_type:
import: "github.com/sipeed/picoclaw/pkg/ids"
type: "UUID"
# Agent checkpoints
- column: "agent_checkpoints.id"
go_type:
import: "github.com/sipeed/picoclaw/pkg/ids"
type: "UUID"
- column: "agent_checkpoints.conversation_id"
go_type:
import: "github.com/sipeed/picoclaw/pkg/ids"
type: "UUID"
- column: "agent_checkpoints.run_state_id"
go_type:
import: "github.com/sipeed/picoclaw/pkg/ids"
type: "UUID"
# Agent tool results
- column: "agent_tool_results.id"
go_type:
import: "github.com/sipeed/picoclaw/pkg/ids"
type: "UUID"
- column: "agent_tool_results.conversation_id"
go_type:
import: "github.com/sipeed/picoclaw/pkg/ids"
type: "UUID"
- column: "agent_tool_results.run_id"
go_type:
import: "github.com/sipeed/picoclaw/pkg/ids"
type: "UUID"
# Jobs
- column: "jobs.id"
go_type:
import: "github.com/sipeed/picoclaw/pkg/ids"
type: "UUID"
# Conversation forks
- column: "agent_conversation_forks.id"
go_type:
import: "github.com/sipeed/picoclaw/pkg/ids"
type: "UUID"
- column: "agent_conversation_forks.parent_conversation_id"
go_type:
import: "github.com/sipeed/picoclaw/pkg/ids"
type: "UUID"
- column: "agent_conversation_forks.child_conversation_id"
go_type:
import: "github.com/sipeed/picoclaw/pkg/ids"
type: "UUID"
- column: "agent_conversation_forks.checkpoint_id"
go_type:
import: "github.com/sipeed/picoclaw/pkg/ids"
type: "UUID"
# Conversation links
- column: "agent_conversation_links.id"
go_type:
import: "github.com/sipeed/picoclaw/pkg/ids"
type: "UUID"
- column: "agent_conversation_links.conversation_id"
go_type:
import: "github.com/sipeed/picoclaw/pkg/ids"
type: "UUID"
- column: "agent_conversation_links.linked_conversation_id"
go_type:
import: "github.com/sipeed/picoclaw/pkg/ids"
type: "UUID"
# Threads
- column: "agent_threads.id"
go_type:
import: "github.com/sipeed/picoclaw/pkg/ids"
type: "UUID"
- column: "agent_threads.conversation_id"
go_type:
import: "github.com/sipeed/picoclaw/pkg/ids"
type: "UUID"
# Thread messages
- column: "agent_thread_messages.id"
go_type:
import: "github.com/sipeed/picoclaw/pkg/ids"
type: "UUID"
- column: "agent_thread_messages.thread_id"
go_type:
import: "github.com/sipeed/picoclaw/pkg/ids"
type: "UUID"
# Mentions
- column: "agent_mentions.id"
go_type:
import: "github.com/sipeed/picoclaw/pkg/ids"
type: "UUID"
- column: "agent_mentions.conversation_id"
go_type:
import: "github.com/sipeed/picoclaw/pkg/ids"
type: "UUID"
- column: "agent_mentions.message_id"
go_type:
import: "github.com/sipeed/picoclaw/pkg/ids"
type: "UUID"
- column: "agent_mentions.target_id"
go_type:
import: "github.com/sipeed/picoclaw/pkg/ids"
type: "UUID"
# Message revisions
- column: "agent_message_revisions.id"
go_type:
import: "github.com/sipeed/picoclaw/pkg/ids"
type: "UUID"
- column: "agent_message_revisions.message_id"
go_type:
import: "github.com/sipeed/picoclaw/pkg/ids"
type: "UUID"
# Domain type: recall_items.sector → memory.Sector
- column: "recall_items.sector"
go_type:
@ -77,3 +224,18 @@ sql:
go_type:
import: "encoding/json"
type: "RawMessage"
rules:
- no-unbounded-delete
- one-select-requires-limit-1
rules:
- name: no-unbounded-delete
message: "DELETE statements must include a WHERE clause"
rule: >
query.sql.contains("DELETE") && !query.sql.contains("WHERE")
- name: one-select-requires-limit-1
message: ":one SELECT queries must include LIMIT 1 (except aggregates)"
rule: >
query.cmd == "one"
&& query.sql.contains("SELECT")
&& !query.sql.contains("LIMIT 1")
&& !query.sql.contains("COUNT(")

View file

@ -33,12 +33,12 @@ VALUES (
`
type InsertSummaryParams struct {
ID ids.UUID `json:"id"`
AgentID string `json:"agent_id"`
SessionKey string `json:"session_key"`
Content string `json:"content"`
FromMsgIdx int64 `json:"from_msg_idx"`
ToMsgIdx int64 `json:"to_msg_idx"`
ID ids.UUID `db:"id" json:"id"`
AgentID string `db:"agent_id" json:"agent_id"`
SessionKey string `db:"session_key" json:"session_key"`
Content string `db:"content" json:"content"`
FromMsgIdx int64 `db:"from_msg_idx" json:"from_msg_idx"`
ToMsgIdx int64 `db:"to_msg_idx" json:"to_msg_idx"`
}
// Memory Summary queries
@ -92,9 +92,9 @@ LIMIT ?3
`
type ListSummariesParams struct {
AgentID string `json:"agent_id"`
SessionKey string `json:"session_key"`
Lim int64 `json:"lim"`
AgentID string `db:"agent_id" json:"agent_id"`
SessionKey string `db:"session_key" json:"session_key"`
Lim int64 `db:"lim" json:"lim"`
}
// ListSummaries

View file

@ -17,11 +17,12 @@ SELECT agent_id,
FROM working_context
WHERE agent_id = ?1
AND session_key = ?2
LIMIT 1
`
type GetWorkingContextParams struct {
AgentID string `json:"agent_id"`
SessionKey string `json:"session_key"`
AgentID string `db:"agent_id" json:"agent_id"`
SessionKey string `db:"session_key" json:"session_key"`
}
// Working Context queries
@ -33,6 +34,7 @@ type GetWorkingContextParams struct {
// FROM working_context
// WHERE agent_id = ?1
// AND session_key = ?2
// LIMIT 1
func (q *Queries) GetWorkingContext(ctx context.Context, arg GetWorkingContextParams) (WorkingContext, error) {
row := q.db.QueryRowContext(ctx, GetWorkingContext, arg.AgentID, arg.SessionKey)
var i WorkingContext
@ -59,9 +61,9 @@ SET content = excluded.content,
`
type UpsertWorkingContextParams struct {
AgentID string `json:"agent_id"`
SessionKey string `json:"session_key"`
Content string `json:"content"`
AgentID string `db:"agent_id" json:"agent_id"`
SessionKey string `db:"session_key" json:"session_key"`
Content string `db:"content" json:"content"`
}
// UpsertWorkingContext