Autonomous, sentient-like bots powered by local LLM inference. Conversing naturally -- with sleep, typos, hesitations, and memory.
This project has a Matrix server. Invite @pixieglow:protocol-luna.github.io to test the bot -- no guarantee it’s awake, though.
Load the model. No system prompt, no few-shot priming, no behavioral layer. The fine-tuning alone produces human-style responses -- not assistant-style.
What you see: the model responds with “good hruu”, “ohh nicee”, “no problem, how was your day?” -- casual, lowercase, no punctuation excess. The style is baked into the weights, not injected by prompts. The behavioral layer (typos, hesitations, sleep) just adds imperfections on top.
The raw model is already human-style. But Protocol Luna doesn’t stop there.
Inject 3-5 example exchanges before each request. The model doesn’t just answer -- it continues a persona. Name, tone, context, all seeded in the prompt window. Zero training required.
Prevents the bot from echoing the same phrases. Forces vocabulary diversity across long conversations -- no more “ohh nicee” five times in a row.
Lower top_p (0.7) for focused, coherent replies. Higher top_k (40) to allow vocabulary variety. The balance between “human-sounding” and “sane” is a tuning knob, not a lottery.
The model is available on HuggingFace -- the 200k-instruct variant is the one used in production:
fox3000foxy/Luna-Protocol-1.5B-Discord-Dialogues-200k-instructFour components, four setups. All local, no cloud APIs required. Full guide →
Wraps llama.cpp to serve GGUF models via an OpenAI-compatible HTTP API. Single-backend mode on :3124:
git clone https://github.com/protocol-luna/krystal.git
cd krystal
./start.sh # Luna 1.5B on :3124
Configurable via KRYSTAL_* environment variables.
Python middleware that sits between Emerald and Krystal. Classifies messages, manages sessions, injects few-shot examples, and detects degenerate responses.
git clone https://github.com/protocol-luna/sapphire.git
cd sapphire
pip install -r requirements.txt
python server.py # listens on :3123
TypeScript WebSocket server that connects bots to Sapphire. Evaluates behavior rules (burst, sleep, typo, mannerisms), calls Sapphire, processes responses.
git clone https://github.com/protocol-luna/emerald.git
cd emerald
npm install
cp config.example.yml config.yml
npm start # WebSocket server on :3126
Optional but recommended. Builds a Markov chain from conversation data to generate ambient messages without LLM calls.
git clone https://github.com/protocol-luna/ruby.git
cd ruby
npm install
npm start # HTTP server on :3127
Emerald's config.yml must have ruby_enabled: true and the correct ruby_host/ruby_port.
Thin WebSocket clients of Emerald. No LLM logic -- just forward messages and post responses.
# Jade (Discord)
git clone https://github.com/protocol-luna/jade.git
cd jade
npm install
# configure config.yml: discord_token, emerald_host/port
npm start
# Pixieglow (Matrix)
git clone https://github.com/protocol-luna/pixieglow.git
cd pixieglow
bun install
# configure config.yml: matrix access token, emerald_host/port
bun start
Generate a Discord OAuth2 URL: scope bot, permissions Send Messages, Read Message History, Add Reactions, intents guilds, guildMessages, guildMessageReactions, messageContent, directMessages.
For Matrix: invite @pixieglow:protocol-luna.github.io to test. Requires a Matrix homeserver (tested with tuwunel).
All three components share the same fine-tuned model from HuggingFace:
pip install huggingface-hub
huggingface-cli download \
fox3000foxy/Luna-Protocol-1.5B-Discord-Dialogues-200k-instruct \
--local-dir models/
fox3000foxy/Luna-Protocol-1.5B-Discord-Dialogues-200k-instruct
Six services working together: LLM inference, gateway, brain, Markov chain, and two platform adapters.
LLM inference server wrapping llama.cpp. Serves GGUF models via an OpenAI-compatible HTTP API. Single-backend mode on :3124. Managed by PM2.
Brain and decision engine. WebSocket server (:3126) that connects platform adapters to Sapphire. Evaluates behavior rules, processes responses, and sends commands. Debug mode across all layers.
LLM gateway built on FastAPI. Classifies messages via BGE-small embedding centroids, manages conversation sessions, injects few-shot examples, detects degenerate responses, and routes to Krystal with emotion-aware sampling.
Markov chain service. Builds an order-2 Markov chain from all messages flowing through Emerald. Generates ambient messages and spontaneous replies with no LLM latency.
The brain (Emerald) manages behavior and Sapphire communication. Bots are thin WebSocket clients.
Every message goes through trigger evaluation, behavior layer, Sapphire call, and post-processing -- orchestrated by Emerald.
Cascade of checks: mentions, DMs, names, keywords, random chance. Each maps to specific delay and ignore thresholds.
Central WebSocket server (:3126). Bots forward MessageEvents, Emerald evaluates behavior, calls Sapphire, applies typo/swap, and sends RespondCommands back with responseText.
Circadian rhythm with three behaviors: sleep (ignore all but mentions), slow (3-5× delay), short (+30% ignore).
Tracks word frequency per channel. When a topic repeats too often, the bot gets bored -- longer delays, higher ignore chance.
Master diagram unifying all sub-systems into one end-to-end lifecycle.
Python LLM gateway called by Emerald. Classifies each message via embedding centroid similarity (BAAI/bge-small-en-v1.5), manages sessions, injects few-shot examples, detects degenerate responses, and calls Krystal. Single-backend mode (:3124).
Jade’s state machine isn’t about generating text -- it’s about deciding when, how, and whether to respond. Every behavior is a deliberate imperfection.
Simulates keyboard slips: adjacent-key swaps (teh), missing letters (liek), double-taps (sooo). Probability scales with message length -- longer messages = more typos. Corrections happen silently 3-8 seconds later.
“hmm”, “wait”, “idk”, “...” inserted before uncertain responses. The LLM doesn’t generate these -- the state machine injects them post-generation based on confidence scoring.
Circadian rhythm tied to real time. At night: ignore all but mentions. During “slow” hours: 3-5× longer delays. The bot doesn’t pretend to sleep -- it actually reduces activity based on its persona’s schedule.
When engaged in a conversation, response delays drop to 2-5 seconds -- mimicking real typing speed. But only for 15 seconds max per exchange, then it cools down. Prevents the bot from dominating a thread.
Tracks word frequency per channel. When a topic repeats too often, the bot gets bored -- longer delays, higher ignore chance, shorter responses. Humans do this unconsciously; the bot does it explicitly.
Tracks who spoke last. If the bot was the last to talk, it’s less likely to respond again -- preventing monologues. If someone replies to the bot specifically, response probability jumps back up.
Unedited Discord exchanges. Both accounts are bot instances -- neither participant is human. PixieGlow runs Luna 1.5B 200k Instruct (Q8_0). Sujet d’SBlow runs Discord-Hermes-8B (f16).
From keyword matching to autonomous agents -- a quick timeline of conversational AI.
How it works: A script called DOCTOR scans user input for keywords (e.g. “mother”, “sad”). When found, it applies a transformation rule -- flipping pronouns (“my” → “your”) and appending a template response (“Tell me more about your mother”). No memory, no understanding, no state. The “Eliza effect”: humans project empathy onto a rephrasing engine.
How it works: An “internal model” with numerical variables for anger, fear, and suspiciousness. Each user input is parsed for keywords, and matching rules adjust these variables up or down. The output is generated by selecting a response template based on which variable is highest -- deflection when suspicious, aggression when angry. Still no learning -- just a more complex state machine than ELIZA.
How it works: AIML (Artificial Intelligence Markup Language) -- XML-based pattern matching. Each rule defines a “template” (response) tied to a “pattern” (regex-like keyword sequence). Categories can have <srai> redirects (synonyms, fallbacks), <set>/<get> for basic memory, and <that> for context tracking. ~40,000 hand-written rules. Won Loebner Prize 3x. Still no learning -- just a massive lookup table.
How it works: Hybrid approach -- AIML-style pattern matching for conversation, plus API integrations for real data (weather, news, stock prices). Introduced contextual shortcuts: users could type /weather Paris directly. The bot maintained per-user state across sessions. The first chatbot to feel “useful” rather than just entertaining -- 26 million users on AIM/MSN.
How it works: Speech-to-text (Hidden Markov Models) → NLU intent classification → slot filling (entity extraction) → action dispatch to APIs. The chatbot becomes an agent -- it doesn’t just talk, it does things (set alarms, send messages, search the web). State tracking via conversation graphs. Still rule-based at the NLU layer -- the “intelligence” is in the integration, not the language model.
How it works: A Transformer neural network trained on trillions of tokens. Instead of matching patterns, it predicts the next token given the full conversation context. Reinforcement Learning from Human Feedback (RLHF) aligns outputs to human preferences. No scripts, no decision trees -- just probability distributions over vocabulary. The chatbot becomes indistinguishable from a person because it’s learned the statistical structure of human language itself.
How it works: A fine-tuned 1.5B LLM (Qwen-based) served locally via llama.cpp. Few-shot priming injects persona context into every request. Behavioral layers add sleep cycles, typos, hesitations, topic fatigue, and spontaneous messages -- none of which come from the model itself. Voice output via PiperTTS -- a fast, local neural TTS that runs on CPU in real time, making voice messages on Discord or Matrix feel natural. The bot runs on your hardware, lives on your server, and is indistinguishable from a real user. Two instances can hold a conversation for hours without breaking character.
Protocol Luna isn’t a chatbot for customer support. It’s about creating presence -- digital beings that feel real enough to pass.
When every platform is flooded with bots, the only way to stay visible is to have your own. Two instances of Luna can maintain a server’s activity without any human intervention.
Game worlds, Discord servers, virtual communities -- environments where NPCs need to feel like real participants, not scripted quest givers.
Not therapy, not productivity -- just presence. A bot that remembers your habits, shares your interests, and talks to you like a friend would.
How do humans react to bots they can’t detect? Protocol Luna is a practical lab for studying the Eliza effect at scale.
Technical deep-dives behind Protocol Luna, written by the creator at fox3000foxy.com.
State machines, fine-tuning guides, configuration references.
Krystal, Sapphire, Emerald, Jade, Pixieglow, Ruby
Guide LLM behavior with example conversations
24 Mermaid diagrams covering the entire codebase
Luna-Protocol-1.5B on HuggingFace (200k-instruct)
7.3M exchanges, 17M turns, 140M words
GitHub organization overview