Skip to content

feat(memory): create MempalaceAdapter implementing MemoryManager interface [phase-5] #355

@quangdang46

Description

@quangdang46

Problem

jcode's MemoryManager is a concrete struct (~1800 lines) used at ~12 call sites across 7 crates. To integrate mempalace as a backend, we need an adapter that maps MemoryManager API → mempalace MemoryProvider trait, without changing all call sites at once.

There is currently no trait separating storage from logic — MemoryManager directly loads/saves MemoryGraph JSON files.

Scope

Files: New crate crates/jcode-mempalace-adapter/ (or new module in crates/jcode-base/src/memory/)

  1. Create MempalaceAdapter:

    pub struct MempalaceAdapter {
        palace: mempalace_core::palace::Palace,
        sidecar: Option<jcode_base::sidecar::Sidecar>,
    }
  2. Implement all MemoryManager public methods by delegating to Palace:

    MemoryManager method MempalaceAdapter → Palace call
    remember_project(entry) add_drawer(entry.into_drawer()) with scope=Local
    remember_global(entry) add_drawer(entry.into_drawer()) with scope=Global
    find_similar(query, threshold, max) search_with_embedding(query_vec, scope)
    find_similar_with_cascade(...) cascade_search (mempalace [#15b] Extension compatibility lane: global + per-extension forced-compat with reason codes #31)
    search_scoped(query, scope) search(query, scope.into())
    tag_memory(id, tag) tag(id, tag)
    link_memories(from, to, w) link(from, to, w)
    forget(id) forget(id)
    get_prompt_memories_scoped(limit, scope) recent(limit, scope.into())
    get_related(id, depth) related(id, depth)
    graph_stats() graph_stats_legacy() → (memories, tags, edges, clusters)
    list_all_scoped(scope) get_drawers(Some(scope.into()), None)
    backfill_embeddings() iterate get_drawers(), embed, upsert
  3. Type conversions:

    • MemoryEntry → Drawer (and back): map category→kind, scope, confidence, strength, timestamps, embeddings
    • MemoryCategory → DrawerKind: Fact→Fact, Preference→Preference, Entity→Entity, Correction→Correction, Custom(s)→Custom(s)
    • MemoryScope → mempalace::MemoryScope: Project→Local, Global→Global, All→All
  4. Constructor:

    impl MempalaceAdapter {
        pub async fn new(palace_path: &Path, project_dir: Option<&Path>) -> anyhow::Result<Self>
    }

    Uses PalaceBuilder to construct a Palace pointing at the given path.

  5. Feature flag: #[cfg(feature = "mempalace-backend")] gates the adapter crate.

Acceptance Criteria

  • All MemoryManager methods delegate correctly to Palace
  • Type conversions (MemoryEntry↔Drawer, MemoryCategory↔DrawerKind) are lossless
  • Existing jcode unit tests pass when adapter is used behind feature flag
  • Adapter compiles without requiring changes to MemoryManager callers
  • cargo test -p jcode-mempalace-adapter passes

Dependencies

mempalace issues (must be resolved first):

Reference

jcode MemoryManager: crates/jcode-base/src/memory.rs lines 148-1846
jcode MemoryEntry: crates/jcode-memory-types/src/lib.rs lines 233-266
mempalace MemoryProvider trait: crates/core/src/palace.rs lines 702+
mempalace Palace struct: crates/core/src/palace.rs line 1225+

Metadata

Metadata

Assignees

No one assigned

    Labels

    mp-migrationjcode → mempalace memory migrationphase-5Migration Phase 5 (jcode adapter)

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions