Tzurot v3
July 2, 2026 ยท View on GitHub
๐ Status: Public beta โ BYOK (Bring Your Own Key) enabled
A modern, scalable Discord bot with customizable AI characters, powered by a microservices architecture with long-term memory, voice in/out, and BYOK-first provider routing.
Highlights
- Multi-provider, vendor-flexible: Default routing through OpenRouter (400+ models, free tier included). Voice via Mistral (BYOK), ElevenLabs (BYOK), or self-hosted (no key needed). All provider boundaries are clean abstractions โ no lock-in.
- BYOK by default: Users supply their own LLM + voice provider keys via
/settings apikeyand pay their own usage. Free-model + self-hosted-voice guest mode available for users without keys. - Privacy-respecting LTM: pgvector with locally-computed embeddings โ no third-party API call for memory operations.
- Voice in + out with attribution: STT for incoming voice messages, TTS for outgoing replies, with bot-owner-visible attribution telling you which provider actually ran (catches silent fallbacks).
- Per-character config cascade: User-default โ per-character โ per-user-per-character override. Surfaces resolved state via
/voice view <character>,/inspect, and dedicated dashboards. - Clean microservice boundaries: 4 services (3 TypeScript + 1 Python) with explicit, pragmatic responsibilities.
Quick Start
Prerequisites
- Node.js 25+
- pnpm 10+
- PostgreSQL 16+ with pgvector extension
- Redis 7+ (for BullMQ)
- Discord Bot Token
- OpenRouter API Key
Setup
-
Install dependencies:
pnpm install -
Configure environment:
cp .env.example .env # Edit .env with your tokens and keys # Required: DISCORD_TOKEN, DATABASE_URL (PostgreSQL with pgvector) # Required: OPENROUTER_API_KEY (for AI responses) # Optional: REDIS_URL (Railway provides this automatically) # Note: Embeddings run locally (Xenova/bge-small-en-v1.5), no API key needed -
Start services:
# Development mode (all services) pnpm dev # Or start individually: pnpm --filter @tzurot/bot-client dev pnpm --filter @tzurot/api-gateway dev pnpm --filter @tzurot/ai-worker dev
Architecture
+-------------+ +--------------+ +------------+
| Discord |---->| Bot Client |---->| API |
| Users |<----| Service |<----| Gateway |
+-------------+ +--------------+ +-----+------+
|
v
+------------+
| Queue |
| (Redis |
| +BullMQ) |
+-----+------+
|
v
+--------------------------+--------------------------+
| |
v v
+------------+ +------------+
| AI Worker |-------------------------------------->| PostgreSQL |
| Service | | (pgvector) |
+-----+------+ +------------+
|
+-----------+-----------+----------+----------+
| | | | |
v v v v v
+----------+ +----------+ +----------+ +--------+ +----------+
| Open | | Mistral | | Eleven | | Voice | | Local |
| Router | | (BYOK | | Labs | | Engine | |Embeddings|
| (400+ | | TTS+STT)| | (BYOK | |(Python | | (BGE, |
| models) | | | | TTS) | | STT/TTS| | no API) |
+----------+ +----------+ +----------+ +--------+ +----------+
Services:
- bot-client: Discord.js interface, slash commands, webhooks, voice attachment handling
- api-gateway: HTTP API, request validation, BullMQ job dispatch, cascade resolvers
- ai-worker: LLM calls, memory retrieval, prompt building, voice synthesis dispatch, diagnostic flight recorder
- voice-engine: Python FastAPI service for self-hosted STT (NVIDIA Parakeet TDT) and TTS (Pocket TTS)
Data Stores:
- PostgreSQL + pgvector: Users, characters, conversation history, vector embeddings for long-term memory
- Redis: BullMQ queues + caching layer (TTL caches with pub/sub invalidation)
Integrations:
- OpenRouter (LLM): 400+ AI models, free tier included. Primary LLM provider.
- Mistral (BYOK voice): Voxtral for STT, voice-cloning TTS. Primary BYOK voice provider.
- ElevenLabs (BYOK voice): TTS + STT. Alternate BYOK provider.
- Voice Engine (self-hosted): Python service running NVIDIA Parakeet TDT for STT and Pocket TTS for TTS. No external API needed; fallback for guest users and BYOK users when their provider fails.
- Local Embeddings (no API): Xenova/bge-small-en-v1.5 (384-dim vectors).
Project Structure
services/โ Microservicesbot-client/โ Discord bot interface (TypeScript)api-gateway/โ HTTP API and request routing (TypeScript)ai-worker/โ Background AI processing (TypeScript)voice-engine/โ Self-hosted STT/TTS service (Python FastAPI)
packages/โ Shared codecommon-types/โ TypeScript types, schemas, shared utilitiescache-invalidation/โ Redis pub/sub cache invalidation servicesclients/โ Typed gateway API clients (generated from the route manifest)config-resolver/โ LLM/TTS/vision config cascade resolversconversation-history/โ Conversation persistence + retentionidentity/โ User/personality loading and provisioningembeddings/โ Local embedding model (BGE-small-en-v1.5)test-factories/โ Shared mock-data factoriestest-utils/โ Shared test helpers and PGLite integrationtooling/โ Ops CLI (pnpm ops) and codebase analysis
prisma/โ Database schema and migrationsscripts/โ One-off utilities: analysis, debug, data migrations, deployment helperstzurot-legacy/โ Archived v2 codebase (kept for migration reference)
Features
โ Working in Production
- Multiple Characters:
@mentiondifferent characters (e.g.@lilith,@default) for per-character routing - Reply Detection: Reply to bot messages to continue conversations seamlessly
- Message References: Reference other messages via Discord links or replies
- Long-term Memory: Characters remember context across sessions and conversations
- Conversation History: Contextual responses using recent message history with cross-channel bridging when configured
- Webhook Avatars: Each character has unique name and avatar
- Image Support: Send images to characters for vision processing
- Voice In: Send Discord voice messages โ STT via Mistral (BYOK), ElevenLabs (BYOK), or self-hosted Parakeet (free fallback). Transcripts include attribution showing which provider produced them.
- Voice Out: TTS replies with voice cloning (Mistral or ElevenLabs BYOK) or self-hosted Pocket TTS (free fallback). Bot-owner-only diagnostic notices surface silent fallbacks (e.g., voice reference exceeded provider limit).
- Message Chunking: Automatic handling of Discord's 2000-character limit
- Model Indicators: Footer shows which AI model produced each response (toggleable per-user/per-character)
- BYOK (Bring Your Own Key): Users provide their own LLM + voice provider keys via
/settings apikey - Guest Mode: Free model + self-hosted voice access for users without keys
- Channel Activation: Characters can auto-respond to all messages in a channel
- NSFW Verification: Age verification via Discord's native age-gated channels
- DM Chat: Chat with characters in DMs by replying to bot messages
- Diagnostic Surface:
/inspectshows the full LLM request flight recorder (memory retrieval, token budget, prompt assembly, response, post-processing) for debugging and transparency
Slash Commands
Tzurot is fully managed via Discord slash commands. For the complete reference (every subcommand, every argument), see the Command Reference.
/characterโ Create, edit, browse, import/export AI characters; chat with them; manage per-character config + voice cloning enrollment/personaโ User personas, defaults, per-character overrides/voiceโ TTS/STT provider config, cloned-voice library, per-character resolved-state dashboard (/voice view)/preset+/channelโ Custom LLM presets, channel auto-response activation/modelsโ Browse and inspect available AI models (capabilities, context window, pricing)/memory+/historyโ Long-term memory browse/search/prune, conversation history management, privacy modes (focus, incognito)/settingsโ Timezone, BYOK API keys, per-character preset overrides, global default settings dashboard/inspect+/helpโ Diagnostic log browser (full LLM request flight recorder); list all available commands/shapesโ Legacy Shapes.inc character migration/admin+/denyโ Owner-only monitoring, maintenance, denial management
๐ Planned
- TTS Phase 2 โ NeuTTS Air: Self-hosted next-gen voice cloning engine alongside Pocket TTS, for free-tier voice-clone users
- Multi-character per channel: Multiple characters responding naturally to the same conversation
- Lorebooks / sticky context: Keyword-triggered lore injection
- Memory enhancements: LTM summarization, OpenMemory integration
Development
pnpm build # Build all services
pnpm test # Run unit tests
pnpm test:component # Run component tests
pnpm quality # Lint + CPD + depcruise + typecheck
pnpm format # Format code
pnpm ops --help # CLI tooling reference
Deployment
The reference deployment runs on Railway with auto-deploy from develop. Each microservice + the voice engine runs as its own Railway service; PostgreSQL (with pgvector) and Redis are Railway-provided.
BYOK enabled: users bring their own LLM + voice provider keys via /settings apikey. Guest users get free models + self-hosted voice.
See Railway Operations Guide for the full deployment runbook.
# Auto-deploys on push to develop
git push origin develop
# Logs
railway logs --service api-gateway
railway logs --service ai-worker
railway logs --service bot-client
# Status
railway status
Local Development
Local development requires PostgreSQL (with pgvector) and Redis:
# Using Podman (SteamOS/Distrobox) or Docker
podman start tzurot-redis tzurot-postgres
pnpm dev
Running tests: unit tests (pnpm test) need no services. Component tests
(pnpm test:component) and the integration + contract tiers (pnpm test:integration)
require Redis โ start it first (podman start tzurot-redis) or you'll get a clear
"Test Redis is unreachable" error. Tests use in-process PGLite for the database, so no
Postgres is needed.
Documentation
Project Status & Planning
- CURRENT.md โ Current session status and active work
- BACKLOG.md โ Project backlog and priorities
- GitHub Releases โ Version history and changelogs
Architecture & Design
- Architecture Decisions โ Why v3 is designed this way
- Caching Audit โ Cache implementations and patterns
- CLAUDE.md โ Project configuration for AI assistants
Development Guides
- Testing Guide โ Testing philosophy and patterns
- Operations Guide โ Railway deployment and operations
- OPS CLI Reference โ CLI tooling reference
Local dev setup: see Quick Start and Development above. Steam Deck specifics:
docs/steam-deck/.
Project History
v2 (archived in tzurot-legacy/): JavaScript, DDD-style architecture, single AI provider. Vendor lock-in caused the rewrite to v3 in 2025.
v3 (current): TypeScript microservices, vendor-flexible provider routing, BYOK-first. Production deployment 2025-10. Focus: simple, maintainable, scalable.
License
MIT License โ See LICENSE file for details
Maintainer
Single-developer project by Vladlena Costescu