feat(integrations): add Zep MemoryStore for Strands Agents - #590
Conversation
Implement zep-strands — a Strands Agents MemoryStore backed by Zep's temporal Context Graph. Supports user-graph and standalone-graph modes, server-side extraction via thread.add_messages, graph.search recall, optional pin-or-expose zep_search tool, and ensure_user/ensure_thread provisioning. Co-authored-by: Daniel Chalef <danielchalef@users.noreply.github.com>
Co-authored-by: Daniel Chalef <danielchalef@users.noreply.github.com>
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
Co-authored-by: Daniel Chalef <danielchalef@users.noreply.github.com>
Co-authored-by: Daniel Chalef <danielchalef@users.noreply.github.com>
There was a problem hiding this comment.
-
Critical —
integrations/strands/python/src/zep_strands/memory_store.py:403,453,504: SDK failures fromgraph.search,graph.add, andthread.add_messagespropagate into the host agent. A transient Zep/network failure can therefore abort recall, extraction, or an agent turn, contrary to the integration convention that Zep errors must not crash agents. Catch operational SDK exceptions, log them without payloads, and return safe fallbacks ([]/Noneor the framework’s error result). Add failure-path tests. -
Critical —
integrations/strands/python/src/zep_strands/memory_store.py:439-442: oversized JSON is truncated as arbitrary text. This removes closing syntax and sends invalid JSON tograph.add, so the advertised size guard still produces a rejected write. Reject oversized JSON explicitly or perform structure-aware chunking; add a test with valid JSON exceeding 9,900 characters.
Fail fast when extraction is enabled without writable user/thread mode, and document that Strands' default extraction cadence (every 5 turns) delays when conversation batches reach Zep — on top of async ingestion. Co-authored-by: Daniel Chalef <danielchalef@users.noreply.github.com>
Co-authored-by: Daniel Chalef <danielchalef@users.noreply.github.com>
Truncating a JSON payload strips its closing syntax, so the size guard sent Zep a document it would reject. Oversized json now raises with chunking guidance; text/message still truncate. Also document why Zep SDK errors propagate out of the store methods: MemoryManager skips failing stores on search, raises AggregateMemoryError on add, and ExtractionCoordinator rolls back its high-water mark so a failed batch retries. Swallowing add_messages errors would be read as success and drop those messages permanently. Co-authored-by: Daniel Chalef <danielchalef@users.noreply.github.com>
Bring zep-strands to peer parity: full Agent+MemoryManager integration test (gated on ZEP+OPENAI), root README listing, and example/docs cleanup. Co-authored-by: Cursor <cursoragent@cursor.com>
Use production-default extraction=True with a session-boundary flush instead of an every-turn InvocationTrigger in the example and live tests. Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
Warning
- [
integrations/strands/python/src/zep_strands/search.pyline 360,zep_searchexception handler] The tool returns the raw exception text to the model (f"Graph search failed: {exc}") and logs the full traceback. SDK exceptions may contain request URLs, identifiers, response bodies, or other sensitive operational details, which would then be forwarded to the configured model provider. Return a generic tool error and log only a sanitized error type/status; keep detailed diagnostics behind an explicit debug-only mechanism. Add a test using an exception containing sensitive text to ensure it is not returned.
Avoid returning raw SDK exception text to the model; log type/status only. Co-authored-by: Cursor <cursoragent@cursor.com>
Summary
Adds
zep-strands, a Strands Agents integration that implements the nativeMemoryStoreinterface on top of Zep’s temporal Context Graph. This is the extension point the AWS Strands team uses for long-term memory (same surface as Bedrock KB / AgentCore Memory Store / community stores like Dakera).What’s included
Package:
integrations/strands/python/→ PyPI namezep-strands, importzep_strandsZepMemoryStore.searchgraph.search(defaultscope="auto"→ Context Block)ZepMemoryStore.add_messagesthread.add_messagesfor server-side extractionZepMemoryStore.addgraph.addfor text/JSON/message factsZepMemoryStore.initializeensure_user/ensure_threadcreate_zep_search_toolAlso supports standalone-graph mode via
graph_id(search + add only).Extraction notes
extraction=True(default in writable user/thread mode) uses Strands’ server-side path viaadd_messages.user_id+thread_id.flush()) — graph building is delayed vs turn-by-turn persistence, and Zep ingestion remains async after that.Usage sketch
Validation
ruff check+ruff format --check— passmypy src/— passpytest— 55 passed, 1 integration test skipped withoutZEP_API_KEYpaths-filterentry forstrandsintest-integrations.ymlintegrations/CLAUDE.mdupdatedFollow-ups (not in this PR)
/strands-memory) once the package is published