Skip to content

feat(memory): add SAME memory provider plugin - #4887

Closed
sgx-labs wants to merge 3 commits into
NousResearch:mainfrom
sgx-labs:feat/same-memory-provider
Closed

feat(memory): add SAME memory provider plugin#4887
sgx-labs wants to merge 3 commits into
NousResearch:mainfrom
sgx-labs:feat/same-memory-provider

Conversation

@sgx-labs

@sgx-labs sgx-labs commented Apr 3, 2026

Copy link
Copy Markdown

Summary

SAME (Stateless Agent Memory Engine) is a self-hosted, offline-first knowledge
store for AI agents — a Go binary that indexes markdown notes into a local semantic
vault with provenance and trust tracking.
Source: sgx-labs/statelessagent

This PR adds SAME as a native Hermes memory provider: a local-first alternative to
Hindsight and Honcho for users who want persistent memory without cloud dependencies.

No new pip dependencies. The plugin talks to the same binary (external install)
via a MCPStdioClient — a thin JSON-RPC 2.0 wrapper over stdio. All calls go through
a threading lock; tested at 50 concurrent calls with 0% failure rate.

Why it belongs

SAME fills the "local memory with trust metadata" gap in the current plugin lineup:

Plugin Architecture Differentiator
Hindsight Cloud/local API Knowledge graph, entity resolution
Honcho Cloud API Dialectic Q&A, user modeling
Holographic Local SQLite Trust scoring, HRR retrieval
SAME Local Go binary Provenance tracking, trust state, cross-agent memory

What it does

Lifecycle hooks:

  • prefetch() — semantic vault search before every turn; injects ranked context with trust tags
  • on_session_end() — generates structured handoff notes (what was requested, done, pending)
  • on_pre_compress() — persists context to vault before compression discards it
  • on_memory_write() — mirrors MEMORY.md/USER.md writes to the vault automatically
  • on_turn_start() — auto-restarts the MCP subprocess if it dies between turns

Agent tools (5 of 19 available):

  • same_search — semantic search with trust state metadata
  • same_save_note — save markdown notes with provenance tracking
  • same_save_decision — structured decision logging with attribution
  • same_get_note — read full note content by path
  • same_health — vault health and index status

Security

  • Secret redaction in prefetch output — API keys, tokens, JWTs; uses agent.redact when available
  • Prompt injection filtering — notes matching instruction patterns are excluded from auto-recall
  • Minimal subprocess env — only PATH, HOME, TMPDIR, LANG, and OLLAMA_URL passed to same mcp; no API keys leaked
  • Handles both Anthropic content block formats (list and string) in session messages
  • Path traversal blocked at the SAME binary level (8/8 payloads blocked in test)

Install (for reviewers testing locally)

brew install sgx-labs/tap/same
# or: curl -fsSL https://statelessagent.com/install.sh | bash
# or: npm install -g @sgx-labs/same

same init                               # initialize a vault
hermes config set memory.provider same
export SAME_VAULT_PATH=/path/to/vault

Test results

Category Result
MCP tool calls 17/17 pass
Concurrent calls (50) 50/50, 0.15s avg
Path traversal payloads 8/8 blocked
Secret redaction Anthropic, Firecrawl, GitHub, OpenAI patterns confirmed
Prompt injection filtering Poison notes excluded from prefetch
Session handoffs Tool-use turns captured via content block extraction
Subprocess restart Auto-recovers after kill
Env isolation No API keys leaked to subprocess

Test plan

  • hermes config set memory.provider same activates plugin
  • hermes memory status shows SAME as active provider
  • Prefetch injects vault context before each turn
  • same_search tool returns ranked results with trust metadata
  • same_save_decision logs decisions with attribution
  • Session end creates handoff note in vault
  • Plugin restarts cleanly after kill $(pgrep same)

🤖 Generated with Claude Code

Adds SAME (Stateless Agent Memory Engine) as a native memory provider.
Local-first cross-agent memory with provenance tracking and trust state.

- Auto-recall via prefetch on every turn
- 5 agent tools: search, save_note, save_decision, get_note, health
- Session handoff creation on exit
- Built-in memory mirroring to vault
- Secret redaction and injection filtering in prefetch
- Minimal subprocess env (no API key leakage)
- Auto-restart if MCP subprocess dies

Requires `same` binary: https://statelessagent.com

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@britrik

britrik commented Apr 3, 2026

Copy link
Copy Markdown

Code Review: SAME Memory Provider Plugin

Thank you for this well-architected memory provider plugin! The design is solid with good security practices.

Issues Found

1. Critical Bug - Truncated Code (Line ~450)
The diff shows a corrupted/truncated line:

tokens=cli_ou...it()

This should be:

tokens = cli_output.split()

This would cause a NameError when the version check runs. Please verify the full line is present in the source.

2. Schema Inconsistency (Line 399)
The top_k parameter is marked as required in the schema but has a default value:

"required": ["query", "top_k"],
...
"top_k": {
    "default": 10,
}

This is inconsistent - either remove top_k from required, or handle the default in handle_tool_call (which you already do at line 786).

3. Minor: Tool Schema Defaults
The JSON Schema default keyword inside property definitions works but is non-standard. Consider either:

  • Moving defaults to the handler code only
  • Using proper JSON Schema draft-07 format

Strengths

Security: Good security practices throughout:

  • B-06: Minimal environment passed to subprocess
  • B-03/B-04: Injection pattern detection in prefetch results
  • B-05: Secret redaction before context injection
  • MCP stdio client properly isolates the subprocess

Thread Safety: Proper use of locks for prefetch and MCP communication

Architecture: Clean MCP JSON-RPC 2.0 implementation with auto-reconnect

Features: Comprehensive feature set (prefetch, session handoffs, memory mirroring, compression safety)

Suggestion

Consider adding input validation for the query parameter in queue_prefetch to prevent potential abuse (e.g., extremely long queries).


Overall: Great contribution! The security considerations are well-thought-out. Please fix the truncated line and the schema inconsistency before merging.

- Remove top_k and append from schema required arrays; defaults
  handled in handle_tool_call (schema inconsistency fix)
- Remove JSON Schema default keywords from property definitions
- Add query length validation in queue_prefetch (max 10K chars)
- Clean up internal reference comments

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@sgx-labs

sgx-labs commented Apr 3, 2026

Copy link
Copy Markdown
Author

Thanks for the thorough review @britrik!

#1 — Truncated line: This is a GitHub diff rendering artifact — the full line is tokens = cli_output.split() (line 532 in source). Verified intact.

#2 — Schema inconsistency: Fixed. Removed top_k and append from required arrays. Defaults are now handled exclusively in handle_tool_call() via setdefault(), which is where the SAME MCP server expects them.

#3 — Tool schema defaults: Fixed. Removed default keywords from schema property definitions. Default values are documented in the description string instead (e.g. "Number of results to return (default 10)").

Suggestion — query validation: Added. queue_prefetch now rejects empty or >10K char queries before making the MCP call.

All changes in the latest commit.

- Add SAME one-liner intro with repo link
- Move "vs MCP integration" near top (first question users have)
- Dual install path: post-merge (just configure) vs standalone (symlink)
- brew/curl/npm as primary install, symlink as secondary
- Hook/tool table replaces bullet list
- "5 of 19 MCP tools" gives scope context
- Add Support section with GitHub Issues and Discord

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@alt-glitch alt-glitch added type/feature New feature or request P3 Low — cosmetic, nice to have comp/plugins Plugin system and bundled plugins tool/memory Memory tool and memory providers labels May 1, 2026
@kshitijk4poor

Copy link
Copy Markdown
Collaborator

Thanks for the contribution!

Per the updated CONTRIBUTING.md, new memory providers are no longer accepted as in-tree additions to plugins/memory/:

Memory Providers: CLOSED to new in-tree additions
PRs adding to plugins/memory/ will be closed. Publish as standalone plugin into ~/.hermes/plugins/ or via pip entry point. Must implement MemoryProvider ABC (sync_turn, prefetch, shutdown, optional post_setup).

Closing this in line with that policy. The path forward is to publish it as a standalone plugin so users can install it directly without touching the Hermes source tree. Once it's published, a small docs PR adding it to the Community plugins section of the README is welcome.

Sorry for the bump — appreciate the time you put into this.

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

Labels

comp/plugins Plugin system and bundled plugins P3 Low — cosmetic, nice to have tool/memory Memory tool and memory providers type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants