fmemory 0.9.91

Memory library for the fiddlesticks agent harness framework
Documentation

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 MemoryBackend contract 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 trait
  • SqliteMemoryBackend: default durable backend implementation
  • PostgresMemoryBackend: durable backend using PostgreSQL
  • FilesystemMemoryBackend: JSON-file durable backend implementation
  • InMemoryMemoryBackend: ephemeral test-oriented backend implementation
  • MemoryBackendConfig: backend selection configuration
  • MemoryConversationStore: adapter implementing fchat::ConversationStore
  • SessionManifest: harness session metadata (+ schema/harness versions)
  • FeatureRecord: feature checklist item
  • ProgressEntry: per-run progress log entry
  • RunCheckpoint: run lifecycle status record
  • BootstrapState: 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 true when it creates state for the first time
  • returns false when 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:

  • Storage
  • NotFound
  • InvalidRequest
  • Other