Skip to content

Feature Request: Make Memory a pluggable module #27

Open

Description

@iNicholasBE

Context

Currently, chat memory in JavaClaw is a core feature backed by a single implementation (FileSystemChatMemoryRepository) that persists conversations as YAML files on disk. This works well for simple setups, but limits what's possible with memory — especially for users who want richer retrieval, graph-based relationships between memories, or semantic search.

Projects like OpenClaw have already made memory a selectable plugin slot, allowing users to swap memory backends without touching core code.

Proposal

Make memory a pluggable module in JavaClaw, following the same plugin pattern we use for channels (like Telegram).

This means:

  • Defining a Memory Plugin SPI — a clear interface/contract that memory plugins must implement
  • Extracting the current file-based memory into a default plugin (e.g. memory-filesystem)
  • Auto-configuration — plugins register via Spring Boot auto-configuration, with property-based selection (agent.memory.provider=filesystem|neo4j|...)
  • Graceful fallback — if no plugin is configured, fall back to the filesystem default

First plugin: Neo4j

As a first community-contributed memory plugin, we'd like to explore a Neo4j-backed memory implementation. Graph databases are a natural fit for conversational memory because they can model relationships between topics, entities, and conversations — enabling richer retrieval than flat file storage.

Open questions to discuss

  1. Plugin SPI design — What should the memory plugin interface look like? Should we extend Spring AI's ChatMemoryRepository, or define our own abstraction that's broader (e.g. supporting semantic search, entity extraction)?

  2. Scope of "memory" — Today we store raw message history. Should the plugin contract also cover:

    • Summarization / compaction?
    • Entity/relationship extraction?
    • Semantic similarity search?
    • Or should those be separate concerns?
  3. Configuration model — How should plugins expose their own config (e.g. Neo4j connection settings)? Should we follow Spring Boot's @ConditionalOnProperty pattern like we do for Telegram?

  4. Neo4j graph model — What would the graph schema look like? Conversations → Messages → Entities/Topics? How do we leverage Neo4j's strengths beyond just being a message store?

  5. Migration path — Should there be a way to migrate existing filesystem conversations into a new memory backend?

Would love to hear thoughts from anyone interested in contributing. This issue is intentionally broad to start the conversation before we commit to an implementation.


Sparked by community interest — thanks to @TobEnd for volunteering Neo4j expertise!

Activity

  1. changed the title [-]Make Memory a pluggable module[/-] [+]Feature Request: Make Memory a pluggable module[/+] on Mar 24, 2026
  2. soufianebouaddis commented on Mar 25, 2026

    @soufianebouaddis

    Hello @iNicholasBE, I’m very interested in contributing to this project. Could you please let me know if contributions are currently welcome and how I can get started?

  3. iNicholasBE commented on Mar 25, 2026

    @iNicholasBE
    ContributorAuthor

    Hi @soufianebouaddis , first of all, thank you so much for your interest in contributing!

    We are 100% looking for contributors, so you are more than welcome.

    To get started, pick an open issue you're interested in working on and leave a comment sharing that you'd like to take it on along with a brief outline of how you'd tackle it.

    We'll then assign the issue to you so others know you're working on it. Once you have something ready, submit a PR.

    Hope that's clear!

  4. soufianebouaddis commented on Mar 25, 2026

    @soufianebouaddis

    Hi @iNicholasBE, I’d like to take this issue

    Before I start, I just want to make sure I understand the direction correctly:

    -For the memory plugin interface, do you prefer keeping it close to ChatMemoryRepository, or something a bit more flexible for future features?
    -Should I focus first on basic message storage/retrieval and leave things like summarization or semantic search for later?
    -I’m thinking of following the same pattern as channels for plugin registration (Spring Boot auto-config + @ConditionalOnProperty). Does that sound right?
    -Also, I assume the current filesystem implementation should be extracted as-is into a default plugin, without changing behavior?

    My idea is to start simple with a minimal SPI, plug the existing implementation into it, and then iterate.

  5. TobEnd commented on Mar 25, 2026

    @TobEnd

    Hi, yeah sure you can assign me the issue.

  6. iNicholasBE commented on Mar 25, 2026

    @iNicholasBE
    ContributorAuthor

    @soufianebouaddis , is there another issue you are interested in or do you want to collaborate with @TobEnd on this one?

    @TobEnd was the one who requested this feature on Reddit and has Neo4J experience.

  7. soufianebouaddis commented on Mar 25, 2026

    @soufianebouaddis

    Hi @iNicholasBE, thanks for the suggestion!

    I’d be happy to collaborate with @TobEnd on this one, especially since his has Neo4j experience.

    I can focus on setting up the initial plugin SPI and refactoring the current filesystem implementation into a default plugin, and we can iterate from there.

    @TobEnd let me know what you think

  8. added 2 commits that reference this issue on Apr 10, 2026
  9. lvca commented on Apr 13, 2026

    @lvca

    Hi @TobEnd and @brunomerkle - great proposal! I'm one of the creators of ArcadeDB and wanted to drop a note before Neo4j becomes the default choice.

    ArcadeDB is worth considering as the first (and possibly only) memory plugin you need:

    Wire-protocol compatible with Neo4j. ArcadeDB implements the Bolt protocol, so any code written with the Neo4j Java driver (neo4j-java-driver) works against ArcadeDB unchanged. Your neo4jService class wouldn't need modification - just swap the URI to bolt://localhost:2480 and remove the neo4j dependency from your POM.

    Multi-model in one engine. Beyond graph, ArcadeDB also supports documents and key-value natively, so a single memory-arcadedb plugin could cover conversation history (document), entity relationships (graph), and embedding indices (vector) - no separate vector store needed.

    Apache 2.0, embedded, no Docker required. For agent memory that "just works" locally (which the OpenClaw lineage values), ArcadeDB can run embedded inside the JVM with no external process:

    try (Database db = new DatabaseFactory("./memory-store").create()) {
      db.transaction(() -> {
        db.query("cypher", "CREATE (:Memory {content: $content, ts: $ts})", params);
      });
    }

    Spring Boot auto-configuration. An ArcadeDBChatMemoryRepository backed by Spring Boot auto-configuration would look almost identical to what you'd write for Neo4j, and I'd be happy to help design or review the plugin SPI to make sure ArcadeDB fits cleanly.

    Happy to answer questions about the Bolt compatibility layer, graph schema design for conversational memory, or embedded setup. Full docs: https://docs.arcadedb.com/

    Bolt compatibility note: ArcadeDB implements Bolt 4.x. The standard neo4j-java-driver 4.x or 5.x will connect to bolt://host:2480 without code changes. This is the lowest-friction integration path possible for a Java project already planning a Neo4j plugin.

    Graph schema suggestion for JavaClaw memory:

    CREATE (:Session {id: $sessionId, created: $ts})
    CREATE (:Message {role: $role, content: $content, ts: $ts})
    CREATE (:Entity {name: $name, type: $type})
    
    MATCH (s:Session {id: $sid}), (m:Message {ts: $ts})
    CREATE (s)-[:HAS_MESSAGE]->(m)
    
    MATCH (m:Message), (e:Entity)
    CREATE (m)-[:MENTIONS]->(e)

    This gives you conversation history, entity linking, and multi-hop reasoning (which conversations mention entity X?) for zero extra infrastructure.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions