Skip to main content

saihm-crewai

SAIHM external memory for CrewAI — a StorageBackend your crew owns: one encrypted source of truth every agent in the crew shares, portable across every model, and provably erasable.

SaihmStorageBackend is a drop-in crewai.memory.storage.backend.StorageBackend — the protocol CrewAI's unified memory resolves through. Register it once and that crew's long-term memory becomes memory the user actually owns: portable across models and frameworks, non-custodial (sealed client-side; Python never holds a key), and provably erasable (GDPR Art. 17 — reset crypto-shreds the cells, it does not merely hide them).

pip install saihm-crewai      # needs crewai >= 1.15 and Node.js >= 20 on PATH (see "How it works")
from crewai.memory.storage.factory import set_memory_storage_factory
from saihm_memory import SaihmStorageBackend

# Register once at startup; return None for other specs to defer to CrewAI's own selection.
set_memory_storage_factory(
    lambda spec: SaihmStorageBackend() if spec == "saihm" else None   # sandbox by default — no account, offline
)

Any CrewAI memory built afterwards for the "saihm" storage spec is then backed by SAIHM.

Or drive the store directly (any Python app):

from crewai.memory.types import MemoryRecord
from saihm_memory import SaihmStorageBackend

store = SaihmStorageBackend()                    # local blind sandbox, no signup
store.save([MemoryRecord(content="the user is vegetarian", categories=["diet"])])
hits = store.search(query_embedding, limit=5)    # -> [(MemoryRecord, score), ...] best-first
store.reset()                                    # crypto-shred everything this store wrote

SaihmStorageBackend implements the full StorageBackend protocol — save / search / delete / update / get_record / list_records / get_scope_info / list_scopes / list_categories / count / reset, plus async asave / asearch / adelete. Each record is one encrypted SAIHM cell.

CrewAI version. CrewAI replaced its memory storage API between 1.9 and 1.15 (storage.interface.Storage and ExternalMemory gave way to storage.backend.StorageBackend, types.MemoryRecord, and the storage.factory hook). This package targets the current API and therefore requires crewai >= 1.15; it is verified against 1.15.14.

Why not just the built-in storage?

CrewAI's default storage is only as portable as the process it runs in, and only as private as whoever holds the store behind it. SAIHM changes the ownership model — same StorageBackend protocol, a fundamentally different guarantee about who owns the memory:

  • Yours across every model. The same memory opens under Claude, GPT, DeepSeek, Qwen, Kimi, or GLM — and under the LangGraph, LangChain, and AutoGen adapters. Switch models or frameworks and the crew's memory follows it. No migration, no re-embedding, no vendor lock-in.
  • The store is blind. Every entry is sealed client-side with post-quantum cryptography (ML-DSA-65 / ML-KEM-768 / AES-256-GCM) before it ever leaves your process. The endpoint holds ciphertext it cannot read; Python never holds a key.
  • Erasure you can prove. reset and delete destroy each cell's key, so its ciphertext becomes unrecoverable noise — a cryptographic shred, not a soft-delete. That is GDPR Art. 17 built into the backend. On the hosted tier each shred is recorded in SAIHM's audit chain; in the offline sandbox the identical code path runs locally, with no external record.
  • Free to start, offline in seconds. Runs against a local blind sandbox with no account and no network; point it at the hosted free tier when you're ready to persist.

Give your crew long-term memory your users actually own — portable, private, and provably forgettable — without leaving the StorageBackend protocol CrewAI already uses.

How it works

All cryptography runs in a small Node sidecar (built on @saihm/mcp-server-pro, ML-DSA-65 / ML-KEM-768 / AES-256-GCM); Python drives it over MCP stdio and holds no keys — one audited crypto implementation, not a second one ported to Python. That is why Node.js ≥ 20 is required. The sidecar ships inside the wheel as source only; its Node dependencies are installed once into a per-user cache (~/.cache/saihm-crewai) on first use, then reused offline.

  • Sandbox (default): no configuration → a local, in-process blind endpoint (ciphertext only). Great for trying it with zero signup; memory lasts for the client's life.
  • Live: set SAIHM_ENDPOINT_URL + SAIHM_MASTER_SECRET_HEX and either SAIHM_TIER=FREE (free tier — run npx -y @saihm/mcp-server-pro free-join once) or SAIHM_AUTH_HEADER (Pro; join at https://saihm.coti.global/join) → durable, hosted, blind memory.

Always close() the backend (or close a shared client); a dropped client is reaped on GC, but explicit close is cleaner.

Ranking (blind store)

SAIHM is a blind store — the endpoint holds ciphertext only and cannot run a server-side vector index — so search ranks client-side:

  • Semantic, using CrewAI's own embeddings. search takes a query_embedding and CrewAI puts an embedding on each MemoryRecord, so ranking is cosine similarity computed in your process. The embedding is sealed into the cell alongside the content; the endpoint sees neither. This adapter never embeds anything itself — whatever embedding model CrewAI is configured with is the one that applies.
  • Recency fallback. When no embeddings are present (for example the offline sandbox, where nothing has been embedded), search degrades to newest-first rather than returning nothing.
  • min_score, limit, scope_prefix, categories, and metadata_filter are all honored — filtering happens before ranking.

Each result is a (MemoryRecord, score) tuple, best-first. Exact recall (get_record, list_records) and erasure (delete, reset) are always exact, never approximate.

scope_prefix matches on path boundaries: /demo covers /demo and /demo/inner but never /demo2 or /demonstrate. That distinction matters because delete and reset crypto-shred irreversibly.

A cell written outside this adapter (e.g. by the LangGraph, LangChain, or AutoGen SAIHM adapters, or a raw remember) is left untouched — one owned store can hold facts from several adapters without collision, and reset only ever shreds the entries this backend wrote.

Related

License

Apache-2.0.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

saihm_crewai-0.1.0.tar.gz (39.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

saihm_crewai-0.1.0-py3-none-any.whl (36.3 kB view details)

Uploaded Python 3

File details

Details for the file saihm_crewai-0.1.0.tar.gz.

File metadata

  • Download URL: saihm_crewai-0.1.0.tar.gz
  • Upload date:
  • Size: 39.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.12.3

File hashes

Hashes for saihm_crewai-0.1.0.tar.gz
Algorithm Hash digest
SHA256 ed7b6b086ac5976d56c64e84d0fbe6bef281249d752a13adcff872c223d70ad8
MD5 934408552e114ae6241d4951d0560301
BLAKE2b-256 d288b19f253769d548df5837922cd1ef482a2b4bcfb117852f38352201232b90

See more details on using hashes here.

File details

Details for the file saihm_crewai-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: saihm_crewai-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 36.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.12.3

File hashes

Hashes for saihm_crewai-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 1b103dc2930ced0d4cd7397e1e60969af77dd7e25c61e72f1adadd00d61c8a28
MD5 24137d0018286528bac64f1b97b0b7e1
BLAKE2b-256 275fed59fc18d5a659cc179202ba4827d97c27cc18cb3fe5f86dad95d87df8d5

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page