Skip to main content

Crate agent_store

Crate agent_store 

Source
Expand description

§agent-store

A causal-ordered, backend-pluggable store substrate for the agent fleet. It is not a database and not an agent — it is the thin layer that gives every consumer (newt-agent’s conversation store, modulex-mcp’s routine board) the same three things:

  • a pluggable BackendSqliteBackend today (bundled rusqlite, zero system deps, the laptop default); a synchronous Postgres backend behind the pg feature in Phase 2, for where an operator already runs a server (your own box, or airship’s “Meat Locker”).
  • two causal primitives — a monotonic Generation counter (modulex’s report clock) and a per-writer, BLAKE3-chained WriterLog with tamper-evident WriterLog::verify (newt’s §6 ordering contract).
  • a commit Doorbell — the seam co-located agents use to wake each other over agent-mesh instead of polling a file.

Everything here is synchronous, so consumers drop it into their existing call sites without an async refactor. The substrate never touches the mesh and never reads the wall clock: ordering is (writer, seq) and generation counters, never timestamps.

§Usage

use agent_store::{Doorbell, CommitEvent, Generation, SqliteBackend, WriterLog};

// Open an ephemeral store and lay down the substrate tables.
let db = SqliteBackend::in_memory().unwrap();
Generation::ensure_schema(&db).unwrap();
WriterLog::ensure_schema(&db).unwrap();

// A monotonic generation counter (modulex's report clock).
let report = Generation::new("report");
assert_eq!(report.bump(&db).unwrap(), 1);
assert_eq!(report.bump(&db).unwrap(), 2);

// A per-writer chained log (newt's conversation turns), with a doorbell
// that a session loop would bridge onto the mesh.
let bell = Doorbell::new();
bell.subscribe(|e: &CommitEvent| {
    // a real consumer publishes (writer, seq) on a mesh topic here
    let _ = e.seq;
});

let turn = WriterLog::append(&db, "conv:demo", "alice", b"hello world").unwrap();
bell.ring(&CommitEvent {
    stream: turn.stream.clone(),
    writer: turn.writer.clone(),
    seq: turn.seq,
    content_hash: turn.content_hash,
});

// The chain is tamper-evident.
WriterLog::verify(&db, "conv:demo", "alice").unwrap();

Structs§

CommitEvent
What a commit announces: where it landed and its content hash. Just enough for a peer to fetch the entry — never the payload itself.
Doorbell
A fan-out of commit subscribers. Cloneable and shareable; clones observe the same subscriber set.
Entry
One entry in a writer’s chained log.
Fingerprint
A 32-byte writer identity (BLAKE3 of an ed25519 public key).
Generation
A named monotonic counter.
SqliteBackend
A SQLite-backed Backend using bundled rusqlite (no system libsqlite3).
StorePolicy
A declarative storage policy.
WriterLog
Stateless operations over the chained log table.

Enums§

BackendKind
Which storage backend a StorePolicy selects.
Dialect
Which SQL dialect a backend speaks — primitives use this only for the few places the portable subset is not enough.
StoreError
Errors raised by the store substrate.
Value
A database-neutral value, used for both bind parameters and returned cells.

Traits§

Backend
A pluggable, synchronous storage backend.

Type Aliases§

Result
Convenience alias for results in this crate.
Row
One returned row: a column-ordered vector of Values.