OpenAI-compatible API server for integrating Vector Graph Memory with Open WebUI and other LLM frontends.
This document describes the current implemented API behavior. The repository is currently pre-1.0, and package version 0.1.0 is the authoritative version.
Run the default stack with Docker Compose:
# 1. Configure environment
cp .env.example .env
# Edit .env - at minimum set OPENAI_API_KEY
# 2. Start all services (databases + API)
docker compose up -d
# 3. Check logs
docker compose logs -f apiThe API will be available at http://localhost:8000
Included services:
- Qdrant (vector database)
- JanusGraph (graph database)
- API server (FastAPI with memory agent)
- Open WebUI
How it works:
- All containers run on an internal Docker network (
vector-graph-network) - The API container connects to databases using container names (
qdrant,janusgraph) - The API port (8000) and Open WebUI port (3000 by default) are exposed to your host machine
- Database connections are handled automatically - no localhost configuration needed!
Current limitation:
- MongoDB is defined in
docker-compose.yml, but MongoDB-backed audit logging is not fully wired through API startup configuration yet. JSONL is the currently working audit path.
Run the API locally while databases run in Docker:
# 1. Install dependencies
pip install -e ".[api]"
# 2. Configure environment
cp .env.example .env
# Edit .env with your settings
# 3. Start only databases
docker compose up -d qdrant janusgraph
# 4. Initialize JanusGraph schema once
python scripts/init_janusgraph_schema.py
# 5. Export OPENAI_API_KEY in your shell
export OPENAI_API_KEY=sk-...
# 6. Start API locally
./start_api.shThe API will be available at http://localhost:8000
Note: start_api.sh currently checks OPENAI_API_KEY from the shell environment before starting the API. It does not source .env automatically.
- Open your Open WebUI instance
- Go to Settings → Connections
- Add a new OpenAI API connection:
- Name: Vector Graph Memory
- Base URL:
http://localhost:8000/v1 - API Key: (any value, not validated)
- Save and select the "vector-graph-memory" model
Simply chat with the agent through Open WebUI. The agent will:
- Automatically search memory for relevant context
- Propose storing important information
- Track conversations in audit logs
Memory Trigger Modes:
ai_determined(default): The server currently injects memory-review guidance on every turn, and the model decides whether to propose anythingphrase: Trigger on specific phrase (e.g., "save this to memory")interval: Check every N messages
Configure via TRIGGER_MODE in .env
Standard OpenAI chat completions endpoint.
Request:
{
"model": "vector-graph-memory",
"messages": [
{"role": "user", "content": "What do you remember about my job search?"}
],
"user": "optional-session-id"
}Response:
{
"id": "chatcmpl-...",
"object": "chat.completion",
"created": 1234567890,
"model": "vector-graph-memory",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "Based on my memory, you applied to..."
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 10,
"completion_tokens": 20,
"total_tokens": 30
}
}List available models.
Response:
{
"object": "list",
"data": [
{
"id": "vector-graph-memory",
"object": "model",
"created": 1234567890,
"owned_by": "vector-graph-memory"
}
]
}Get pending memory proposals for a session.
Response:
{
"session_id": "user-123",
"proposals": {
"proposal-uuid-1": {
"content": "Applied to Google for Senior SWE role",
"entity_type": "job",
"relationships": [],
"similar_nodes": []
}
}
}Confirm or reject a memory proposal.
Query Parameters:
action:add_new,update_existing, orcancelupdate_node_id: Required if action isupdate_existing
Response:
{
"status": "ok",
"message": "Successfully added job to memory with ID: abc-123"
}Get audit log for a session.
Query Parameters:
limit: Maximum number of entries (default: 50) for non-session-scoped recent-history calls; session-scoped history does not currently enforce this limit
Response:
{
"session_id": "user-123",
"entries": [
{
"timestamp": "2026-03-22T01:55:04",
"operation": "add_node",
"summary": "Added job: Applied to Google...",
"entities": ["node-uuid-1"]
}
]
}API health check.
Response:
{
"status": "ok",
"service": "vector-graph-memory-api",
"version": "1.0.0"
}See .env.example for full configuration options.
Key Settings:
| Variable | Description | Default |
|---|---|---|
LLM_MODEL |
PydanticAI model string | openai:gpt-4o-mini |
PROJECT_ID |
Memory namespace | default |
MEMORY_USE_CASE |
Use case description | General purpose memory |
TRIGGER_MODE |
When to check memory | ai_determined |
SIMILARITY_THRESHOLD |
Duplicate detection threshold | 0.85 |
MongoDB audit environment variables are listed in .env.example, but they are not yet fully consumed by API startup code. JSONL is the currently functional audit backend.
-
AI Determined (
ai_determined)- The server currently prompts memory review on every turn
- The model still decides whether to propose additions
- Set:
TRIGGER_MODE=ai_determined
-
Phrase-based (
phrase)- Trigger on specific phrase
- User must explicitly request memory storage
- Set:
TRIGGER_MODE=phraseandTRIGGER_PHRASE=save this to memory
-
Interval-based (
interval)- Check every N messages
- Predictable behavior
- Set:
TRIGGER_MODE=intervalandTRIGGER_INTERVAL=5
The API server:
-
Initializes on startup:
- Connects to Qdrant and JanusGraph
- Creates MemoryAgent instance
- Loads configuration from environment
-
Handles requests:
- Receives chat messages via OpenAI API
- Runs agent with memory tools
- Returns responses
-
Manages sessions:
- Uses
userfield as session ID - Tracks pending proposals per session
- Maintains conversation context
- Uses
-
Provides memory control:
- Endpoints to view/confirm proposals
- Audit log access
- Session management
- MongoDB audit logging is intended but not fully wired into API startup configuration.
- The API reports
1.0.0in FastAPI metadata and the health endpoint, while package metadata remains0.1.0. start_api.shrequiresOPENAI_API_KEYto be exported in the current shell and does not source.env.- JanusGraph schema initialization is manual for local library and local API development.
- Session-scoped audit history does not currently apply the documented
limitparameter.
python -m uvicorn src.vgm.api.server:app --reload --host 0.0.0.0 --port 8000# Health check
curl http://localhost:8000/
# Chat completion
curl -X POST http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "vector-graph-memory",
"messages": [{"role": "user", "content": "Hello!"}],
"user": "test-session"
}'
# Check proposals
curl http://localhost:8000/memory/proposals/test-sessionInteractive API docs available at:
- Swagger UI: http://localhost:8000/docs
- ReDoc: http://localhost:8000/redoc
docker compose up -d# All services
docker compose logs -f
# Just API
docker compose logs -f api
# Just databases
docker compose logs -f qdrant janusgraphdocker compose up -d --build apidocker compose downdocker compose down -vdocker compose restart apiError: Cannot connect to Qdrant/JanusGraph
Solution:
docker compose up -d
# Wait 10-15 seconds for JanusGraph to initialize
# Check if services are healthy
docker compose psError: OPENAI_API_KEY not set
Solution:
Add to .env:
OPENAI_API_KEY=sk-...Then restart:
docker compose restart apiError: Address already in use
Solution:
Change port in .env:
API_PORT=8001Then rebuild:
docker compose up -dCheck logs:
docker compose logs apiCommon issues:
- Missing
OPENAI_API_KEYin.env - Missing exported
OPENAI_API_KEYin the current shell when using./start_api.sh - Database services not ready (wait 15-20 seconds)
- Port conflict (change
API_PORT)
Force rebuild:
docker compose up -d --build --force-recreate api- See
playground.ipynbfor usage examples - Check
README.mdfor overall project documentation - Review
.env.examplefor all configuration options