Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/test-integrations.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ jobs:
- 'integrations/langgraph/python/**'
pydantic-ai:
- 'integrations/pydantic-ai/python/**'
strands:
- 'integrations/strands/python/**'

- uses: dorny/paths-filter@d1c1ffe0248fe513906c8e24db8ea791d46f8590 # v3
id: typescript
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ Framework integration packages live under [`integrations/`](integrations/), orga
framework-first then language: `integrations/<framework>/<language>/`. Each package is built,
tested, and released independently.

- **Python**: Google ADK, Microsoft Agent Framework, Microsoft AutoGen, AG2, CrewAI, LangGraph, LiveKit, Pydantic AI
- **Python**: Google ADK, Microsoft Agent Framework, Microsoft AutoGen, AG2, CrewAI, LangGraph, LiveKit, Pydantic AI, Strands Agents
- **TypeScript**: Google ADK, Mastra, Vercel AI SDK
- **Go**: Google ADK

Expand Down
1 change: 1 addition & 0 deletions integrations/CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ Current packages:
| `mastra/typescript` | `@getzep/zep-mastra` (npm) | `@getzep/zep-mastra` |
| `ms-agent-framework/python` | `zep-ms-agent-framework` (PyPI) | `zep_ms_agent_framework` |
| `pydantic-ai/python` | `zep-pydantic-ai` (PyPI) | `zep_pydantic_ai` |
| `strands/python` | `zep-strands` (PyPI) | `zep_strands` |
| `vercel-ai/typescript` | `@getzep/zep-vercel-ai` (npm) | `@getzep/zep-vercel-ai` |

**Naming convention (keep CI derivation simple):** the framework directory is the package
Expand Down
1 change: 1 addition & 0 deletions integrations/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ New to Zep? Sign up at [getzep.com](https://www.getzep.com) and create an API ke
| Microsoft Agent Framework | Python | `zep-ms-agent-framework` | [`ms-agent-framework/python/`](ms-agent-framework/python/) |
| Microsoft AutoGen | Python | [`zep-autogen`](https://pypi.org/p/zep-autogen) | [`autogen/python/`](autogen/python/) |
| Pydantic AI | Python | `zep-pydantic-ai` | [`pydantic-ai/python/`](pydantic-ai/python/) |
| Strands Agents | Python | `zep-strands` | [`strands/python/`](strands/python/) |
| Vercel AI SDK | TypeScript | `@getzep/zep-vercel-ai` | [`vercel-ai/typescript/`](vercel-ai/typescript/) |

Looking for bulk data ingestion (Slack exports, documents, email, CSV/JSON records,
Expand Down
58 changes: 58 additions & 0 deletions integrations/strands/python/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Changelog

## Unreleased

### Added

- Live agent integration test (`test_integration_full_lifecycle`) exercising
`Agent` + `MemoryManager` + `ZepMemoryStore` against Zep Cloud and OpenAI,
including cross-thread recall and `on_user_created` (gated on
`ZEP_API_KEY` + `OPENAI_API_KEY`). Store-only round-trip remains available
with just `ZEP_API_KEY`.

### Fixed

- `ZepMemoryStore.initialize()` no longer calls Zep. `Agent.__init__` is
synchronous, so Strands runs that hook on a throwaway event loop in a worker
thread; provisioning there drove the caller's `AsyncZep` client from a second
event loop and raised `RuntimeError: ... is bound to a different event loop`
whenever the caller had already awaited that client (the pattern the README
and example recommend: `ensure_user`, then hand the client to the store).
Provisioning now happens on the store's first search or write, which always
runs on the agent's own loop.
- `ZepMemoryStore` now rejects `extraction=True` (or an `ExtractionConfig`) at construction unless the store is writable user-graph mode with both `user_id` and `thread_id`, so `MemoryManager` never schedules extraction that would raise on every cycle.
- `add()` no longer truncates oversized `json` payloads. Slicing JSON strips its closing syntax, so the size guard produced a document Zep would reject; oversized `json` now raises a `ValueError` pointing at chunking. `text`/`message` payloads are still truncated with a warning.
- Corrected the `provisioning` module docstring (it incorrectly referred to
`ZepContextProvider`).
- `zep_search` no longer returns raw exception text to the model. SDK errors
can include URLs, identifiers, or response bodies; the tool now returns a
fixed `"Graph search failed."` string and logs only the exception type
(and `status_code` when present), with the full traceback at DEBUG.
- The example and live agent test now pass an explicit `OpenAIModel`. Both
require `OPENAI_API_KEY` and document `strands-agents[openai]`, but neither
passed `model=` to `Agent`, so Strands silently fell back to its
`BedrockModel()` default and the run failed on missing AWS credentials. The
model ID is overridable via `OPENAI_MODEL` (default `gpt-5-mini`).

### Changed

- Documented that Strands' default extraction cadence is every **5 turns**, so conversation batches only reach Zep when the trigger fires (or on `flush()`), delaying graph building relative to turn-by-turn persistence — in addition to Zep's asynchronous ingestion after messages arrive.
- Documented the failure-handling contract: Zep SDK errors propagate out of `search`/`add`/`add_messages` by design, because `MemoryManager` and `ExtractionCoordinator` own failure isolation (skip-and-log, `AggregateMemoryError`, and high-water-mark rollback for retry). Added tests pinning that behavior.
- Example and live tests flush at the session boundary after `invoke_async`,
which `MemoryManager` requires to persist buffered turns on that path.

## 0.1.0 (2026-08-01)

### Added

- `ZepMemoryStore` — a Strands Agents `MemoryStore` backed by Zep's temporal Context Graph.
- `search` via `graph.search` (default `scope="auto"` returns Zep's assembled Context Block).
- `add_messages` via `thread.add_messages` for server-side extraction in user-graph mode.
- `add` via `graph.add` for text/JSON/message facts (`metadata["type"]` selects the data type).
- `initialize` provisions the Zep user and thread (no-op for standalone graphs).
- Standalone-graph mode via `graph_id` (search + add only).
- `ensure_user` / `ensure_thread` idempotent provisioning helpers with optional `on_created` hook.
- `create_zep_search_tool` with pin-or-expose control over `graph.search` parameters.
- `expose_search_tool` on `ZepMemoryStore` to register the search tool through `get_tools()`.
- Message and graph payload truncation helpers with length-only warnings.
- Mock-based unit tests, a gated live integration test, and a runnable example.
72 changes: 72 additions & 0 deletions integrations/strands/python/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Makefile for zep-strands development

.PHONY: help install format lint lint-fix type-check test test-cov clean build all pre-commit ci

# Default target
help:
@echo "Available commands:"
@echo " install - Install package and dependencies in development mode"
@echo " format - Format code with ruff"
@echo " lint - Run linting checks"
@echo " type-check - Run type checking with mypy"
@echo " test - Run tests"
@echo " test-cov - Run tests with coverage report"
@echo " all - Run format, lint, type-check, and test"
@echo " build - Build the package"
@echo " clean - Clean build artifacts"

# Install package in development mode
install:
uv sync --extra dev

# Format code
format:
uv run ruff format .

# Run linting checks
lint:
uv run ruff check .

# Fix linting issues automatically
lint-fix:
uv run ruff check --fix .

# Run type checking
type-check:
uv run mypy src/

# Run tests (mock-based; integration tests skip without API keys)
test:
uv run pytest tests/ -v

# Run tests with coverage
test-cov:
uv run pytest tests/ -v --cov=zep_strands --cov-report=term-missing --cov-report=xml

# Run all checks (format first, then lint, then type-check, then test)
all: format lint type-check test

# Build the package
build:
uv build

# Clean build artifacts
clean:
rm -rf dist/
rm -rf build/
rm -rf *.egg-info/
rm -rf .pytest_cache/
rm -rf .mypy_cache/
rm -rf .ruff_cache/
find . -type d -name __pycache__ -exec rm -rf {} +
find . -type f -name "*.pyc" -delete
rm -f coverage.xml
rm -f .coverage

# Development workflow - run this before committing
pre-commit: lint-fix format lint type-check test
@echo "All checks passed! Ready to commit."

# CI workflow - strict checks without auto-fixing
ci: lint type-check test
@echo "CI checks passed!"
Loading
Loading