A Python CLI that runs in-character NPC conversations with persistent memory, FAISS vector search, and multi-engine orchestration. Built as the runtime layer for interactive character agents — the same memory/retrieval patterns used in larger game-world and personal-assistant projects.
Run a conversation with a named NPC:
python main.py clara_moonEach session:
- Loads character sheet, relationship metrics, and conversation history from disk
- Embeds new dialogue and retrieves relevant past memories via FAISS
- Builds a structured prompt (Jinja2 templates) with retrieved context
- Calls the configured LLM (Ollama local or OpenAI-compatible API)
- Persists updated memory, relationship state, and conversation log back to JSONL files
Type quit to exit.
| Engine | Role |
|---|---|
MemoryEngine |
Persistent JSONL memory, lore ingestion, history windowing, summarization |
EmbedEngine |
Ollama embeddings → FAISS index for semantic retrieval |
PromptEngine |
Jinja2 template assembly (chat, summary, image prompts) |
LLMEngine |
Routes to Ollama or OpenAI based on LLM_config.yaml |
StateEngine |
Tracks location, activity, and game-state surfaces |
ImageEngine |
Optional image generation hooks |
Memory uses a three-layer chunking model (document → section → atomic fact) via the bundled EMBEDDER/ pipeline. See EMBEDDER/README.md for embedding details.
- Python 3.10+
- Ollama (local LLM + embeddings)
- FAISS (
faiss-cpu) - Jinja2, PyYAML, OpenAI Python SDK
pip install -r requirements.txtCopy and edit an LLM config:
copy "LLM_config - gemma3-12b.yaml" LLM_config.yamlEnsure Ollama is running with your chosen chat and embedding models pulled.
main.py # CLI entry point
town_core/ # Engine modules
npc_data/<npc_name>/ # Per-character persistent state
character_sheet.txt
conversation_history.txt
embeddings.jsonl
npc_metrics.yaml
EMBEDDER/ # Three-layer embedding pipeline
LLM_config.yaml # Active model routing config
- Hybrid retrieval: static lore domain + per-NPC dynamic memory, searched by embedding similarity
- Durable state: every turn writes back to JSONL — no in-memory-only sessions
- Configurable model routing: swap between local Ollama and cloud APIs via YAML, no code changes
- Relationship system: numeric trust/affinity stats drive prompt modifiers via lookup tables
- EMBEDDER — standalone embedding pipeline (also vendored here)
- DOGSLED — dual-agent coding workspace used to build this stack
- DragonWarp — game-world agent with lore RAG (private repo)