Skip to content
Open
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 @@ -36,6 +36,8 @@ jobs:
- 'integrations/livekit/python/**'
ag2:
- 'integrations/ag2/python/**'
agent-framework:
- 'integrations/agent-framework/python/**'

- uses: dorny/paths-filter@d1c1ffe0248fe513906c8e24db8ea791d46f8590 # v3
id: typescript
Expand Down
15 changes: 15 additions & 0 deletions integrations/ms-agent-framework/python/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Changelog

## 0.1.0 (2026-06-16)

### Added

- `ZepContextProvider` -- a Microsoft Agent Framework `ContextProvider` that gives an agent long-term memory backed by Zep.
- `before_run` persists the latest user message via `thread.add_messages(return_context=True)` and injects Zep's Context Block into the agent's instructions.
- `after_run` persists the assistant response to the same Zep thread.
- Lazy Zep user and thread creation on first run, cached per provider instance.
- Optional `on_user_created` hook for per-user ontology, custom instructions, or user summary instructions.
- Configurable user/assistant message display names, `ignore_roles`, and `source_id`.
- Graceful error handling that logs failures without crashing the host agent.
- Mock-based test suite plus a live integration test gated on `ZEP_API_KEY` and `OPENAI_API_KEY`.
- Working example demonstrating cross-thread memory recall.
72 changes: 72 additions & 0 deletions integrations/ms-agent-framework/python/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Makefile for zep-ms-agent-framework 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_ms_agent_framework --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!"
155 changes: 155 additions & 0 deletions integrations/ms-agent-framework/python/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
# Zep Microsoft Agent Framework Integration

Long-term memory for [Microsoft Agent Framework](https://github.com/microsoft/agent-framework) agents, backed by [Zep](https://www.getzep.com)'s temporal Context Graph. Persists conversation turns and injects relevant context into the model on every run.

## Installation

```bash
pip install zep-ms-agent-framework
```

The package depends only on `agent-framework-core`. The runnable example also uses a model provider:

```bash
pip install zep-ms-agent-framework agent-framework-openai
```

## Quick Start

Attach a `ZepContextProvider` to an agent through the `context_providers` keyword argument:

```python
import asyncio
from agent_framework import Agent
from agent_framework.openai import OpenAIChatClient
from zep_cloud.client import AsyncZep
from zep_ms_agent_framework import ZepContextProvider

zep = AsyncZep(api_key="your-zep-api-key")

agent = Agent(
OpenAIChatClient(model="gpt-4o-mini"),
instructions="You are a helpful assistant with long-term memory.",
context_providers=[
ZepContextProvider(
zep_client=zep,
user_id="user-123",
thread_id="thread-abc",
first_name="Jane",
last_name="Smith",
email="jane@example.com", # optional
)
],
)

async def main() -> None:
result = await agent.run("Hi, I'm a data scientist in Portland.")
print(result.text)

asyncio.run(main())
```

## How It Works

The integration ships one class — `ZepContextProvider` — that subclasses Agent Framework's [`ContextProvider`](https://github.com/microsoft/agent-framework) and overrides the two lifecycle hooks the framework calls around every `agent.run(...)`. See [`src/zep_ms_agent_framework/context_provider.py`](src/zep_ms_agent_framework/context_provider.py).

### before_run

Runs before the model is invoked. On each turn it:

1. **Extracts** the latest user message from `context.input_messages`.
2. **Creates** the Zep user and thread lazily on first use (cached thereafter).
3. **Persists** the message via `thread.add_messages(return_context=True)` — storing the message and retrieving Zep's Context Block in a single round-trip.
4. **Injects** the returned Context Block (facts, relationships, prior knowledge from the whole user graph) into the model's instructions via `context.extend_instructions(...)`.

### after_run

Runs after the model responds. It reads the assistant reply from `context.response.messages` and persists it to the same Zep thread, so both sides of the conversation are captured.

Because `thread.get_user_context` (and `add_messages(return_context=True)`) assemble context from the **entire user graph**, the thread only scopes relevance — an agent on a new thread still recalls facts the same user shared earlier.

## Identity and Threads

Memory is scoped per `ZepContextProvider` instance to one `user_id` + `thread_id`. For a multi-user application, construct one provider (and one agent, or one agent per request) per user/conversation, passing real names so Zep can resolve the user's identity node in the graph.

| Field | Required | Default | Description |
|-------|----------|---------|-------------|
| `zep_client` | Yes | — | Initialised `AsyncZep` client (caller owns its lifecycle) |
| `user_id` | Yes | — | Zep user ID this provider's memory is scoped to |
| `thread_id` | Yes | — | Zep thread ID the conversation is recorded in |
| `first_name` | Recommended | `None` | User first name — helps Zep anchor identity |
| `last_name` | Optional | `None` | User last name |
| `email` | Optional | `None` | User email |
| `user_message_name` | Optional | full name | Display name on persisted user messages |
| `assistant_message_name` | Optional | `"Assistant"` | Display name on persisted assistant messages |
| `source_id` | Optional | `"zep"` | Agent Framework attribution ID for injected instructions |
| `ignore_roles` | Optional | `None` | Roles to exclude from graph ingestion (still stored in thread history) |
| `on_user_created` | Optional | `None` | Async hook run once after a new user is created (ontology / instructions setup) |

## Features

- **Native context-provider hook** — uses Agent Framework's own `before_run` / `after_run` pipeline, the same surface as the framework's built-in memory providers.
- **Single round-trip** — persists the user turn and retrieves the Context Block in one call.
- **Lazy resource creation** — the Zep user and thread are created on first run and cached.
- **Whole-user-graph recall** — context is fused across all of the user's threads and data.
- **Per-user setup hook** — `on_user_created` for configuring ontology, custom instructions, or user summary instructions.
- **Graceful error handling** — a Zep failure is logged but never crashes the host agent; the agent degrades to memoryless for that turn.
- **Async-only, client-agnostic** — requires `AsyncZep`; works with any Agent Framework chat client.

## Configuration

```bash
# Required
export ZEP_API_KEY="your-zep-api-key"
export OPENAI_API_KEY="your-openai-api-key" # for the example / live tests
```

See [SETUP.md](SETUP.md) for signing up, creating an API key, and running the example end to end.

## Examples

- **[examples/basic_agent.py](examples/basic_agent.py)** — a single agent seeding facts in one thread and recalling them in a new thread (cross-thread recall).

## Development

```bash
git clone https://github.com/getzep/zep.git
cd zep/integrations/ms-agent-framework/python
make install # uv sync --extra dev
make all # format + lint + type-check + test
```

| Command | Description |
|---------|-------------|
| `make format` | Format code with ruff |
| `make lint` | Run linting checks |
| `make type-check` | Run mypy type checking |
| `make test` | Run the test suite (integration tests skip without API keys) |
| `make all` | Run all checks |
| `make build` | Build the package |

Live integration tests run only when `ZEP_API_KEY` and `OPENAI_API_KEY` are set:

```bash
uv run pytest tests/test_integration.py -v -s -m integration
```

## Requirements

- Python 3.11+
- `zep-cloud>=3.23.0`
- `agent-framework-core>=1.8.1`

## Support

- [Zep Documentation](https://help.getzep.com)
- [Microsoft Agent Framework](https://github.com/microsoft/agent-framework)
- [GitHub Issues](https://github.com/getzep/zep/issues)

## License

Apache 2.0 — see [LICENSE](../../../LICENSE) for details.

## Contributing

Contributions are welcome! Please see our [Contributing Guide](../../../CONTRIBUTING.md) for details.
95 changes: 95 additions & 0 deletions integrations/ms-agent-framework/python/SETUP.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
# Setup Guide

This guide walks you from a fresh machine to running the example agent with Zep memory.

## 1. Sign up for Zep and create an API key

1. Go to [https://www.getzep.com](https://www.getzep.com) and create an account.
2. Open the [Zep dashboard](https://app.getzep.com) and select (or create) a project.
3. In the project settings, go to **API Keys** and create a new key.
4. Copy the key — you will set it as `ZEP_API_KEY` below.

Zep is a paid product; see [getzep.com](https://www.getzep.com) for plan details.

## 2. Get an OpenAI API key (for the example)

The integration itself is model-agnostic, but the bundled example and live tests
drive the agent with OpenAI. Create a key at
[platform.openai.com/api-keys](https://platform.openai.com/api-keys) and copy it
for `OPENAI_API_KEY`.

## 3. Install

Using `pip`:

```bash
pip install zep-ms-agent-framework agent-framework-openai
```

Or, to work from the repository with `uv`:

```bash
git clone https://github.com/getzep/zep.git
cd zep/integrations/ms-agent-framework/python
make install # uv sync --extra dev (includes agent-framework-openai)
```

Requirements: Python 3.11+, `agent-framework-core>=1.8.1`, `zep-cloud>=3.23.0`.

## 4. Configure environment variables

```bash
export ZEP_API_KEY="your-zep-api-key"
export OPENAI_API_KEY="your-openai-api-key"

# Optional: override the OpenAI model used by the example (default: gpt-4o-mini)
export OPENAI_MODEL="gpt-4o-mini"
```

## 5. Run the example

From the repository:

```bash
uv run python examples/basic_agent.py
```

Or, if you installed with `pip`:

```bash
python examples/basic_agent.py
```

The example:

1. Seeds facts about a user across two turns in one thread.
2. Waits for Zep to process the knowledge graph (ingestion is asynchronous).
3. Starts a **new** thread for the same user and asks recall questions — the
agent answers using facts fused into the user's graph from the first thread.

## 6. Run the tests

Mock-based tests (no API keys needed):

```bash
make test
```

Live integration test (requires `ZEP_API_KEY` and `OPENAI_API_KEY`):

```bash
uv run pytest tests/test_integration.py -v -s -m integration
```

## Troubleshooting

- **`ZepDependencyError` on import** — Microsoft Agent Framework is not
installed. Run `pip install zep-ms-agent-framework` (which pulls
`agent-framework-core`).
- **`ModuleNotFoundError: agent_framework.openai`** — install the model
provider used by the example: `pip install agent-framework-openai`.
- **Recall returns nothing** — Zep ingestion is asynchronous; a just-added fact
is not instantly retrievable. The example waits ~20s; increase the wait if
your graph is large or under load.
- **Authentication errors** — confirm `ZEP_API_KEY` is set in the same shell and
belongs to the intended project.
Loading
Loading