Skip to content

feat: add local semantic memory with embedding + vector search#2421

Open
0xbyt4 wants to merge 10 commits intoOpenMind:mainfrom
0xbyt4:feat/semantic-memory
Open

feat: add local semantic memory with embedding + vector search#2421
0xbyt4 wants to merge 10 commits intoOpenMind:mainfrom
0xbyt4:feat/semantic-memory

Conversation

@0xbyt4
Copy link
Collaborator

@0xbyt4 0xbyt4 commented Feb 25, 2026

Summary

OM1 currently has short-term memory (LLMHistoryManager: last N messages + summarization) but no long-term memory - the robot cannot learn from previous interactions. This PR adds local semantic memory using embedding-based vector search, allowing the robot to store experiences and automatically retrieve relevant memories during conversations.

How It Works

Tick Start
    |
    v
Fuser.fuse()
    |-- Collect sensor inputs (inputs_fused)
    |-- SemanticMemoryProvider.retrieve(inputs_fused, mode)    <-- NEW
    |-- Inject RELEVANT MEMORIES section into prompt            <-- NEW
    |-- Return fused_prompt
    |
    v
LLM.ask(prompt)
    |-- @update_history() decorator
    |   |-- LLM generates response
    |   |-- SemanticMemoryProvider.store(input, response, mode) <-- NEW
    |
    v
Actions executed

Each tick, the Fuser queries semantic memory with the current sensor input. ChromaDB returns the top-k most similar past experiences (filtered by cosine similarity threshold). These are injected into the prompt as a RELEVANT MEMORIES section between inputs and actions. After the LLM responds, the input-response pair is stored as a new memory.

Technical Details

  • Embedding Model: all-MiniLM-L6-v2 - 384-dim embeddings, ~22M params, runs on CPU
  • Vector Store: ChromaDB PersistentClient - SQLite-backed, persists to config/memory/embeddings/
  • Similarity: Cosine distance with configurable threshold (default: 0.3)
  • Mode Isolation: Each robot mode gets its own ChromaDB collection (om1_{mode_name})
  • Lazy Loading: Model and ChromaDB only initialize when semantic_memory_enabled: true
  • Singleton Pattern: Consistent with existing providers (IOProvider, etc.)

Resource Budget (Apple M3, 8GB RAM)

Component RAM Latency
all-MiniLM-L6-v2 ~90 MB ~10ms/encode
ChromaDB ~20-50 MB <5ms/query
Total ~140 MB ~20ms/tick

Configuration

Disabled by default. Enable per config:

cortex_llm: {
    type: "OpenAILLM",
    config: {
        agent_name: "Spot",
        history_length: 10,
        semantic_memory_enabled: true,   // default: false
        semantic_memory_top_k: 3,        // default: 3
        semantic_memory_threshold: 0.3,  // default: 0.3
    },
},

Changes

File Change
src/providers/semantic_memory_provider.py New singleton provider: store/retrieve/clear_mode
src/llm/__init__.py 3 new LLMConfig fields
src/runtime/cortex.py Provider init in _initialize_mode()
src/providers/llm_history_manager.py Store hook in update_history() decorator
src/fuser/__init__.py Retrieve + RELEVANT MEMORIES prompt injection
tests/providers/test_semantic_memory_provider.py 20 unit tests
pyproject.toml sentence-transformers, chromadb, onnxruntime deps

Verified Manually

Tested with MockInput (WebSocket) + conversation config. Robot successfully:

  1. Stored facts ("My name is Oxbye", "I work as a blockchain developer", "I love cats")
  2. Retrieved correct memories when asked ("Where am I from?" -> Jupiter, "What do I do?" -> blockchain developer)
  3. Persisted memories across restarts (ChromaDB PersistentClient)

Add SemanticMemoryProvider using sentence-transformers (all-MiniLM-L6-v2)
and ChromaDB for persistent semantic memory. Robot stores sensory-action
pairs and retrieves relevant memories via cosine similarity, injecting
them into the LLM prompt as RELEVANT MEMORIES section.
@0xbyt4 0xbyt4 requested review from a team as code owners February 25, 2026 11:24
@github-actions github-actions bot added dependencies Pull requests that update a dependency file robotics Robotics code changes python Python code tests Test files config Configuration files labels Feb 25, 2026
- Move sentence-transformers, chromadb, onnxruntime to [project.optional-dependencies] memory group
  to avoid ~500MB+ ML dependency bloat for users who don't use semantic memory.
  Install with: uv sync --extra memory
- Fix test_retrieve_filters_by_threshold to assert empty list instead of just isinstance check
…t config

- Use pytest.importorskip("chromadb") at top-level so tests are skipped
  when memory extras are not installed (CI runs uv sync without --extra memory)
- Remove all function-level imports in favor of top-level imports
- Remove semantic_memory fields from conversation.json5 since memory is
  an optional feature that users opt into
Base already includes torch, ultralytics, deepface, tf-keras.
sentence-transformers and chromadb are small in comparison. Keeping
them in base ensures CI runs tests without workflow changes.
…manager

- test_fuser_injects_memories_when_enabled: verify RELEVANT MEMORIES in prompt
- test_fuser_skips_memories_when_disabled: verify no injection when disabled
- test_update_history_stores_to_semantic_memory: verify store() called with correct mode
- test_update_history_skips_store_when_memory_disabled: verify store() not called
Keep both semantic memory and knowledge base features in fuser.
Adapt semantic memory tests to async fuse() signature.
@codecov
Copy link

codecov bot commented Feb 26, 2026

Codecov Report

❌ Patch coverage is 85.15625% with 19 lines in your changes missing coverage. Please review.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
src/providers/semantic_memory_provider.py 81.90% 19 Missing ⚠️

📢 Thoughts on this report? Let us know!

faiss-cpu and sentence-transformers native libraries conflict on macOS
ARM64, causing SIGSEGV (exit code 139) when both are loaded in the
same process. Move KnowledgeBase import from top-level to lazy import
inside __init__, so faiss is only loaded when KB config is present.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

config Configuration files dependencies Pull requests that update a dependency file python Python code robotics Robotics code changes tests Test files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant