From 392dbd29db0b528c3827bfad085091059fe8f6ed Mon Sep 17 00:00:00 2001 From: seven7763 Date: Wed, 15 Jul 2026 01:07:57 +0800 Subject: [PATCH] docs(examples): add Zep + DaoXE OpenAI-compatible Python sample Show using the OpenAI Python client with base_url https://daoxe.com/v1 alongside Zep thread memory. Model IDs come from the DaoXE account; notes multi-protocol and that the service is not available in mainland China. Co-Authored-By: Claude Fable 5 --- .../daoxe-openai-compatible/.env.example | 12 ++ .../python/daoxe-openai-compatible/README.md | 69 +++++++++++ .../chat_with_memory.py | 109 ++++++++++++++++++ .../daoxe-openai-compatible/requirements.txt | 3 + 4 files changed, 193 insertions(+) create mode 100644 examples/python/daoxe-openai-compatible/.env.example create mode 100644 examples/python/daoxe-openai-compatible/README.md create mode 100644 examples/python/daoxe-openai-compatible/chat_with_memory.py create mode 100644 examples/python/daoxe-openai-compatible/requirements.txt diff --git a/examples/python/daoxe-openai-compatible/.env.example b/examples/python/daoxe-openai-compatible/.env.example new file mode 100644 index 00000000..c7b94382 --- /dev/null +++ b/examples/python/daoxe-openai-compatible/.env.example @@ -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 diff --git a/examples/python/daoxe-openai-compatible/README.md b/examples/python/daoxe-openai-compatible/README.md new file mode 100644 index 00000000..73213f7b --- /dev/null +++ b/examples/python/daoxe-openai-compatible/README.md @@ -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. diff --git a/examples/python/daoxe-openai-compatible/chat_with_memory.py b/examples/python/daoxe-openai-compatible/chat_with_memory.py new file mode 100644 index 00000000..affcf326 --- /dev/null +++ b/examples/python/daoxe-openai-compatible/chat_with_memory.py @@ -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() diff --git a/examples/python/daoxe-openai-compatible/requirements.txt b/examples/python/daoxe-openai-compatible/requirements.txt new file mode 100644 index 00000000..daa75cd3 --- /dev/null +++ b/examples/python/daoxe-openai-compatible/requirements.txt @@ -0,0 +1,3 @@ +zep-cloud>=2.0.0 +openai>=1.0.0 +python-dotenv>=1.0.0