5 releases (2 stable)
Uses new Rust 2024
| 3.0.0 | Mar 3, 2026 |
|---|---|
| 1.0.0 | Feb 9, 2026 |
| 0.9.91 | Feb 9, 2026 |
| 0.9.9 | Feb 9, 2026 |
| 0.1.0 | Feb 7, 2026 |
#2474 in Database interfaces
Used in 3 crates
(2 directly)
355KB
8K
SLoC
Context Layer API
fmemory provides durable state and transcript persistence for Fiddlesticks.
It is the persistence layer used by fharness for initializer/coding-run artifacts and by fchat (through an adapter) for conversation history.
Responsibilities
- Persist session bootstrap artifacts (manifest, feature list, progress, run checkpoints)
- Persist transcript messages
- Expose a
MemoryBackendcontract for harness logic - Adapt memory transcript storage to
fchat::ConversationStore
fmemory does not:
- Execute model calls (
fprovider) - Orchestrate turns (
fchat) - Execute tools (
ftooling) - Decide multi-run harness strategy (
fharness)
Add dependency
[dependencies]
fmemory = { path = "../fmemory" }
Core types
MemoryBackend: async persistence traitSqliteMemoryBackend: default durable backend implementationPostgresMemoryBackend: durable backend using PostgreSQLFilesystemMemoryBackend: JSON-file durable backend implementationInMemoryMemoryBackend: ephemeral test-oriented backend implementationMemoryBackendConfig: backend selection configurationMemoryConversationStore: adapter implementingfchat::ConversationStoreSessionManifest: harness session metadata (+ schema/harness versions)FeatureRecord: feature checklist itemProgressEntry: per-run progress log entryRunCheckpoint: run lifecycle status recordBootstrapState: manifest + feature/progress/checkpoint aggregate
Session initialization guards
MemoryBackend includes explicit initializer-safe methods:
is_initialized(session_id)initialize_session_if_missing(...)
initialize_session_if_missing(...) is idempotent:
- returns
truewhen it creates state for the first time - returns
falsewhen state already exists (no overwrite)
Basic backend usage
use fcommon::SessionId;
use fmemory::prelude::*;
async fn seed_backend(backend: &dyn MemoryBackend) -> Result<(), MemoryError> {
let session = SessionId::from("session-1");
let created = backend
.initialize_session_if_missing(
&session,
SessionManifest::new(session.clone(), "feature/init", "Initialize harness"),
vec![FeatureRecord {
id: "feature-1".to_string(),
category: "functional".to_string(),
description: "Initializer artifacts exist".to_string(),
steps: vec!["write init state".to_string()],
passes: false,
}],
Some(ProgressEntry::new("run-1", "Initializer scaffold created")),
Some(RunCheckpoint::started("run-1")),
)
.await?;
let _ = created;
Ok(())
}
Backend selection
fmemory supports configurable backend construction:
use fmemory::{MemoryBackendConfig, create_default_memory_backend, create_memory_backend};
let sqlite_default = create_default_memory_backend()?;
let in_memory = create_memory_backend(MemoryBackendConfig::InMemory)?;
let sqlite_custom = create_memory_backend(MemoryBackendConfig::Sqlite {
path: "./state/fmemory.sqlite3".into(),
})?;
let postgres = create_memory_backend(MemoryBackendConfig::Postgres {
host: "127.0.0.1".into(),
port: 5432,
database: "fmemory".into(),
username: "postgres".into(),
password: "postgres".into(),
})?;
let filesystem = create_memory_backend(MemoryBackendConfig::Filesystem {
root: "./state/fmemory".into(),
})?;
let _ = (sqlite_default, in_memory, sqlite_custom, postgres, filesystem);
# Ok::<(), fmemory::MemoryError>(())
Default backend path is ~/.fiddlesticks/fmemory.sqlite3 (or %USERPROFILE%/.fiddlesticks/fmemory.sqlite3 on Windows). Override it with FMEMORY_SQLITE_PATH.
fchat integration adapter
MemoryConversationStore lets fchat use fmemory without direct store duplication:
use std::sync::Arc;
use fmemory::prelude::*;
let backend: Arc<dyn MemoryBackend> = Arc::new(InMemoryMemoryBackend::new());
let store = MemoryConversationStore::new(backend);
let _ = store;
Versioning fields
SessionManifest includes:
schema_version(default:1)harness_version(default:"v0")
These support forward migration for future harness behaviors.
Error model
MemoryErrorKind variants:
StorageNotFoundInvalidRequestOther
Dependencies
~34MB
~639K SLoC