Skip to content
Closed
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
12 changes: 12 additions & 0 deletions examples/python/daoxe-openai-compatible/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Zep Cloud — https://app.getzep.com
ZEP_API_KEY=your_zep_api_key_here

# DaoXE OpenAI-compatible gateway — https://daoxe.com
# Not available in mainland China.
DAOXE_API_KEY=your_daoxe_api_key_here

# Exact model ID from your DaoXE account (GET https://daoxe.com/v1/models)
DAOXE_MODEL=your_account_model_id_here

# Optional override (default: https://daoxe.com/v1)
# DAOXE_BASE_URL=https://daoxe.com/v1
69 changes: 69 additions & 0 deletions examples/python/daoxe-openai-compatible/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Zep + DaoXE (OpenAI-compatible LLM gateway)

Minimal example: use [Zep](https://www.getzep.com) agent memory with an
[OpenAI Python client](https://github.com/openai/openai-python) pointed at an
OpenAI-compatible chat Completions endpoint.

[DaoXE](https://daoxe.com) is used here as the gateway (`base_url=https://daoxe.com/v1`).
Any OpenAI-compatible provider works the same way — only the base URL, API key,
and model ID change.

## What this shows

1. Create a Zep user + thread and store turns with `thread.add_messages`.
2. Pull a context block with `thread.get_user_context`.
3. Call chat completions via the OpenAI SDK with a custom `base_url`.
4. Persist the assistant reply back into Zep.

## Requirements

- Python 3.10+
- Zep Cloud API key ([app.getzep.com](https://app.getzep.com))
- DaoXE API key ([daoxe.com](https://daoxe.com)) — **not available in mainland China**
- A model ID from your DaoXE account (`GET https://daoxe.com/v1/models`)

DaoXE is multi-protocol (OpenAI-compatible `/v1/chat/completions` and Anthropic-style
`/v1/messages`). This example uses only the OpenAI-compatible path so it drops into
existing OpenAI SDK code.

## Setup

```bash
cd examples/python/daoxe-openai-compatible
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .env
# edit .env with ZEP_API_KEY, DAOXE_API_KEY, and DAOXE_MODEL
```

## Run

```bash
python chat_with_memory.py
```

Expected flow: two turns against the same Zep thread. The second user message
asks about something said in the first turn so you can see Zep context influence
the reply.

## Environment

| Variable | Required | Description |
|----------|----------|-------------|
| `ZEP_API_KEY` | yes | Zep Cloud API key |
| `DAOXE_API_KEY` | yes | DaoXE API key (Bearer token for `/v1`) |
| `DAOXE_MODEL` | yes | Exact model ID from your DaoXE account |
| `DAOXE_BASE_URL` | no | Defaults to `https://daoxe.com/v1` |

Prefer live model IDs from the account / `GET /v1/models` rather than hard-coding
a catalog.

## Notes

- Same pattern as other examples in this repo that construct `OpenAI(...)` /
`AsyncOpenAI(...)` — the only difference is `base_url`.
- Do not use this path from mainland China; DaoXE is not available there.
- For Claude-protocol clients, DaoXE also exposes `POST /v1/messages` with the
same key and account-scoped model IDs; that path is out of scope for this
OpenAI SDK sample.
109 changes: 109 additions & 0 deletions examples/python/daoxe-openai-compatible/chat_with_memory.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
#!/usr/bin/env python3
"""
Zep memory + DaoXE (OpenAI-compatible chat Completions).

Uses the official OpenAI Python client with base_url pointed at DaoXE.
Model IDs must match your DaoXE account (GET /v1/models). DaoXE is not
available in mainland China.

DaoXE is multi-protocol; this sample only uses the OpenAI-compatible path.
"""

from __future__ import annotations

import os
import uuid

from dotenv import load_dotenv
from openai import OpenAI
from zep_cloud.client import Zep
from zep_cloud.types import Message

load_dotenv()

DAOXE_BASE_URL = os.getenv("DAOXE_BASE_URL", "https://daoxe.com/v1")


def require_env(name: str) -> str:
value = os.getenv(name)
if not value:
raise SystemExit(
f"Missing {name}. Copy .env.example to .env and set required values."
)
return value


def main() -> None:
zep_api_key = require_env("ZEP_API_KEY")
daoxe_api_key = require_env("DAOXE_API_KEY")
model = require_env("DAOXE_MODEL")

zep = Zep(api_key=zep_api_key)
llm = OpenAI(api_key=daoxe_api_key, base_url=DAOXE_BASE_URL)

suffix = uuid.uuid4().hex[:8]
user_id = f"daoxe-example-user-{suffix}"
thread_id = f"daoxe-example-thread-{suffix}"
user_name = "Alex"

print(f"Creating Zep user={user_id} thread={thread_id}")
zep.user.add(user_id=user_id, first_name="Alex", last_name="Example")
zep.thread.create(thread_id=thread_id, user_id=user_id)

turns = [
"I prefer concise answers and my favorite color is blue.",
"What color do I like, and how should you answer me?",
]

for i, user_text in enumerate(turns, start=1):
print(f"\n=== Turn {i} ===")
print(f"User: {user_text}")

zep.thread.add_messages(
thread_id=thread_id,
messages=[
Message(name=user_name, role="user", content=user_text),
],
)

context_block = ""
try:
memory = zep.thread.get_user_context(thread_id=thread_id)
context_block = memory.context or ""
except Exception as exc: # noqa: BLE001 — demo should keep running
print(f"(Zep context unavailable: {exc})")

system = (
"You are a helpful assistant. Use any provided memory context. "
"Keep replies under 80 words."
)
if context_block:
system = f"{system}\n\n# Memory context\n{context_block}"

completion = llm.chat.completions.create(
model=model,
messages=[
{"role": "system", "content": system},
{"role": "user", "content": user_text},
],
temperature=0.3,
)
assistant_text = (completion.choices[0].message.content or "").strip()
print(f"Assistant: {assistant_text}")

zep.thread.add_messages(
thread_id=thread_id,
messages=[
Message(
name="Assistant",
role="assistant",
content=assistant_text,
),
],
)

print("\nDone. Inspect the thread in the Zep dashboard if needed.")


if __name__ == "__main__":
main()
3 changes: 3 additions & 0 deletions examples/python/daoxe-openai-compatible/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
zep-cloud>=2.0.0
openai>=1.0.0
python-dotenv>=1.0.0