Skip to content

Add zep-langgraph integration#524

Open
danielchalef wants to merge 3 commits into
mainfrom
feat/zep-langgraph
Open

Add zep-langgraph integration#524
danielchalef wants to merge 3 commits into
mainfrom
feat/zep-langgraph

Conversation

@danielchalef

Copy link
Copy Markdown
Member

Adds the zep-langgraph package (integrations/langgraph/python) — Zep memory for LangGraph.

Shape (per the spike's verified findings)

Primary — node/tool helpers (the pattern Zep's own langgraph-memory guide and mem0 use): a context helper around thread.get_user_context (inject a Context Block into the system prompt), a persistence helper around thread.add_messages, and prebuilt graph.search tools — usable in StateGraph / create_react_agent.

Secondary — ZepStore(BaseStore): implements only the two abstract methods (batch/abatch); hybrid-delegate wraps a backing KV BaseStore (InMemoryStore by default) for exact-key get/put/delete/list_namespaces, and routes search to Zep graph.search. Zep ingestion is async (no graph read-after-write within a turn) — documented; this avoids silently flattening Zep's graph retrieval into KV semantics.

Deps

langgraph>=1.2.5, zep-cloud>=3.23.0. Python ≥3.11.

Ships

README, SETUP.md (Zep signup), example (create_react_agent/StateGraph), 95 mock tests, Makefile, CHANGELOG.

Validation

ruff + ruff format + mypy + pytest (95 passed). Approach in integrations/SPIKE_FINDINGS.md.

🤖 Generated with Claude Code

danielchalef and others added 2 commits June 18, 2026 11:01
Zep memory for LangGraph (Python). Leads with node/tool helpers (the pattern
Zep's own LangGraph guide and mem0 use), plus a hybrid-delegate BaseStore.

- Node/tool helpers (PRIMARY): a context helper around thread.get_user_context
  to inject a Context Block into the system prompt, a persistence helper around
  thread.add_messages, and prebuilt graph.search tools — usable in StateGraph /
  create_react_agent.
- ZepStore(BaseStore) (SECONDARY): implements only batch/abatch; hybrid-delegate
  wraps a backing KV store (InMemoryStore by default) for exact-key get/put/
  delete/list, and routes search to Zep graph.search (semantic). Ingestion is
  async (no graph read-after-write within a turn) — documented.
- Depends on langgraph>=1.2.5 and zep-cloud>=3.23.0. Python >=3.11.
- README, SETUP, example, 95 mock tests, Makefile, CHANGELOG. CI filter added.

Verified: ruff + ruff format + mypy + pytest (95 passed). See
integrations/SPIKE_FINDINGS.md.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… example

- examples/react_agent.py: drop temperature=0 (gpt-5 reasoning models reject
  it, 400ing SETUP.md's first documented command); match the README's
  ChatOpenAI(model="gpt-5").
- store.py ZepStore.search: honor SearchOp.offset (slice), clamp limit to
  [1, 50] (Zep's graph.search ceiling) with a warning, log a clear warning when
  a BaseStore filter is passed (Zep uses typed search_filters instead of
  ignoring it silently), and fix search_scope="auto" returning zero items by
  reading the materialized context block. Fetch offset+limit rows since Zep has
  no server-side offset.
- persistence.py: apply the 4096-char truncation guard to native Zep Message
  objects (the README/example path previously bypassed it and would 400), via a
  shared _truncate_message_content helper; chunk persist_messages /
  persist_messages_sync to <=30 messages per add_messages call (Zep's cap),
  requesting return_context only on the final chunk. Warnings log lengths/counts
  only -- no message content/PII.

Tests: limit clamp, offset honored, auto-scope context item, filter warning,
oversize native Message truncated (+ no mutation / passthrough), >30 messages
chunked (async + sync), context-on-last-chunk only.

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

claude Bot commented Jun 18, 2026

Copy link
Copy Markdown

test

@claude

claude Bot commented Jun 18, 2026

Copy link
Copy Markdown

Code review

Two issues found.


1. Bug: partial message loss on multi-chunk persistence

File: integrations/langgraph/python/src/zep_langgraph/persistence.py, lines 250-257 (async) and 312-319 (sync)

When a turn exceeds 30 messages, persist_messages splits it into chunks. If any chunk raises an exception, the loop exits immediately via return last_context - silently abandoning all remaining chunks. The earlier chunks are already written to Zep, leaving the thread in a partial state. The caller cannot detect this: both "failed mid-batch" and "succeeded with no context" return None.

)
except Exception:
logger.warning(
"Failed to persist %d message(s) to Zep thread %s",
len(chunk),
thread_id,
exc_info=True,
)
return last_context
if want_context and response is not None:

The same defect is in persist_messages_sync at line 319.

Consider continue instead of return (keep attempting subsequent chunks even if one fails), and emit a log line indicating how many messages were not persisted.


2. Missing explicit dependency: langchain-core

File: integrations/langgraph/python/pyproject.toml, lines 7-10

langchain-core is imported unconditionally at runtime in tools.py, persistence.py, context.py, and store.py, but is absent from dependencies. The package relies on it being transitively pulled in by langgraph>=1.2.5. If langgraph ever ships without langchain-core as a hard dependency, users will get an ImportError with no hint from this package's own metadata.

requires-python = ">=3.11"
dependencies = [
"langgraph>=1.2.5",
"zep-cloud>=3.23.0",
]

Suggested fix - add langchain-core as an explicit dependency:

dependencies = [
    "langgraph>=1.2.5",
    "langchain-core>=0.3",
    "zep-cloud>=3.23.0",
]

…re dep

persist_messages / persist_messages_sync: on a chunk-level add_messages
failure, continue to the remaining chunks (best-effort) instead of
returning early and silently dropping them. The warning now reports the
failing chunk index and total chunk count (counts only, no PII). Adds
regression tests asserting all chunks are attempted after a mid-batch
failure.

pyproject.toml: add explicit langchain-core>=1.0 dependency. langchain_core
is imported directly (tools, persistence, context, store) but was only
pulled in transitively via langgraph; uv resolves it to 1.x.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant