Documentation
¶
Overview ¶
Package agentloopsql is a SQLite-backed agentloop.SessionStore and agentloop.StepStore: the durable counterpart to agentloopmem, for a CLI or a single-host service that wants sessions to outlive the process.
It uses modernc.org/sqlite, a pure-Go driver, so a binary embedding this package still cross-compiles with nothing but GOOS and GOARCH.
Both interfaces are implemented by one *Store over one database, so a session and its trace stay in a single file that can be copied, inspected with the sqlite3 CLI, or deleted wholesale.
Step ordering ¶
Steps are ordered by insertion, not by RunStep.StepIndex. That is not a stylistic choice: the loop derives the next index from the number of steps its history window returned, so a session that outgrows that window restarts numbering and writes indices it has already used. A (session_id, step_index) primary key would reject every write from that point on. StepIndex is stored as recorded and read back unchanged; the row's own autoincrement id is what LastN orders by.
Index ¶
- Variables
- type SessionInfo
- type Store
- func (s *Store) Append(ctx context.Context, step agentloop.RunStep) error
- func (s *Store) Close() error
- func (s *Store) DB() *sql.DB
- func (s *Store) Delete(ctx context.Context, id string) error
- func (s *Store) Exists(ctx context.Context, id string) (bool, error)
- func (s *Store) Finalize(ctx context.Context, id string, sum agentloop.FinalizeSummary) error
- func (s *Store) Get(ctx context.Context, id string) (agentloop.Session, error)
- func (s *Store) Grant(ctx context.Context, sessionID, prompt string) error
- func (s *Store) Grants(ctx context.Context, sessionID string) ([]string, error)
- func (s *Store) IsGranted(ctx context.Context, sessionID, prompt string) (bool, error)
- func (s *Store) LastN(ctx context.Context, sessionID string, n int) ([]agentloop.RunStep, error)
- func (s *Store) List(ctx context.Context, limit int) ([]SessionInfo, error)
- func (s *Store) MostRecent(ctx context.Context) (string, error)
- func (s *Store) Revoke(ctx context.Context, sessionID string) error
- func (s *Store) Steps(ctx context.Context, sessionID string) ([]agentloop.RunStep, error)
- func (s *Store) UpdateData(ctx context.Context, id string, snapshot json.RawMessage) error
Constants ¶
This section is empty.
Variables ¶
var ErrNoSession = errors.New("agentloopsql: no such session")
ErrNoSession reports that no session matched. Callers distinguish "you asked for a session that isn't here" from a database failure with errors.Is.
Functions ¶
This section is empty.
Types ¶
type SessionInfo ¶
type SessionInfo struct {
ID string
Model string
Status string
Steps int32
Tokens agentloop.TokenUsage
CreatedAt time.Time
UpdatedAt time.Time
// Opening is the session's first user message, which is how a person
// actually recognises a session — an id tells them nothing.
Opening string
}
SessionInfo is one row of a session listing: the metadata a person needs to recognise a session, without loading its trace.
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store is a SQLite-backed SessionStore and StepStore over one database.
func Open ¶
Open opens (creating if needed) the database at path and applies the schema. Pass ":memory:" for an ephemeral database — useful in tests, though every Store then starts empty.
clock is a seam for tests; nil uses time.Now.
func (*Store) Append ¶
Append implements agentloop.StepStore. The session row is touched in the same transaction so a session is never listed without the steps that belong to it, or vice versa.
func (*Store) DB ¶
DB exposes the underlying handle for migrations or reporting an application wants to run itself.
func (*Store) Delete ¶
Delete removes a session and its whole trace. Deleting a session that is not there returns ErrNoSession rather than succeeding quietly — a mistyped id should say so.
func (*Store) Finalize ¶
Finalize implements agentloop.SessionStore, recording the summary of the run that just ended. A session finalizes once per Run, so later calls overwrite: the most recent run is what the session's status describes.
It upserts rather than requiring the row to exist, so a run that answered without ever carrying data still leaves a session behind for List to find.
func (*Store) Get ¶
Get implements agentloop.SessionStore. An unknown id is not an error and does not create a row: the loop calls Get before every run and treats "no session yet" as normal, so it returns a zero Session and leaves Exists as the answer to whether one is really there.
func (*Store) Grant ¶
Grant records that the user approved prompt for this session, so resuming the session does not ask again.
Only approvals are recorded. A refusal is deliberately not persisted: remembering "no" forever would silently block a capability the user might well allow on a later run, and being asked twice is the lesser harm.
func (*Store) LastN ¶
LastN implements agentloop.StepStore, returning the most recent n steps in CHRONOLOGICAL order. The ordering is load-bearing — the loop replays these straight into the LLM context — so the rows are taken newest-first to apply the limit and then reversed.
func (*Store) List ¶
List returns sessions most recently updated first, capped at limit (non-positive means no cap).
func (*Store) MostRecent ¶
MostRecent returns the id of the most recently updated session — what "continue where I left off" resolves to. It returns ErrNoSession when the database is empty, so a caller can say so rather than starting a session the user did not ask for.
func (*Store) UpdateData ¶
UpdateData implements agentloop.SessionStore, replacing the session's data snapshot and creating the session if this is the first write.