When Wynter asks a romantic question about Jared ("is he in love
with me", "does he miss me", etc.) the LLM fallback now explicitly
denies the premise instead of giving a generic Jared-wins response.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add explicit Jared/Wynter no-romance lore to all four branch
bio_contexts and prompts — prevents model from implying romantic
feelings between them
- Add _implies_jared_wynter_romance() validator; responses that
suggest romantic connection fall back to the static fallback
- Replace random-list responses for non-Jared/Wynter senders with
AI-generated magic 8-ball predictions via BALL_MODEL
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
lotusllm, lotusllmben, and llama3.3 70B have been removed from
Ollama on LXC 130 to free ~44 GB disk space.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- BALL_MODEL: huihui_ai/llama3.2-abliterate:3b (abliterated 3B,
follows complex persona instructions without censorship)
- ASK_MODEL + OLLAMA_MODEL: phi4-mini:latest (Phi-4 Mini 3.8B,
best instruction-following model available within GPU VRAM)
- Update _MODEL_DISPLAY for new model names
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Fix about_jared/about_wynter using substring match — "they" matched
"he", "theme" matched "he", etc., routing Wynter's questions to the
wrong branch. Now uses \b word boundaries via re.search.
- Switch BALL_MODEL default from sadiq-bd 1B uncensored to
llama3.2:latest (3B) — the 1B model hallucinates, ignores persona
instructions, and mentions Jared randomly. GPU is now working on
Arc A380 at ~25 tok/s so the larger model is practical.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
gemma3:latest produces garbage output on the Vulkan backend (Intel Arc A380).
llama3.2:latest runs correctly at 100% GPU. Timeout bumped to 120s to handle
cold model loads (~22s) without timing out.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
8ball is only AI-powered for specific users (Wynter/Jared); for everyone
else it's a random static response. Games is the correct category.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Model attribution is now only shown when the LLM actually generated the
response. If the model refused or gave an invalid answer and we fell back
to the static response, no 'via ...' line is shown.
Fallback responses for all three Wynter branches are now randomised pools
so the bot doesn't always give the same flat yes/no phrase regardless of
what Wynter actually typed.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
help: grouped into AI / Games / Random / Server categories with Option B
purple header; descriptions auto-pulled from the command registry.
Model attribution: added _MODEL_DISPLAY map so 'via lotusllm' becomes
'via Llama 3.2 1B', 'via gemma3:latest' becomes 'via Gemma 3 4B', etc.
Config: OLLAMA_MODEL switched from lotusllm to llama3.2:latest; added
BALL_MODEL (sadiq-bd/llama3.2-1b-uncensored) as a dedicated config var
for the 8ball so it stays on the uncensored model without affecting fortune.
Descriptions: fortune -> AI-generated fortune cookie; ask -> Ask LotusBot;
health -> Bot health & stats (admin only).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Responding 'Wynter is too busy...' in third person to someone who just
asked 'will I...' feels disconnected. Changed the prompt to speak
directly to Wynter using you/your, with her name used only for emphasis.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The LLM was responding with 'She's far too busy...' instead of using
'Wynter' by name. Added explicit instruction to both Wynter branches
to always refer to her by name and never use she/her pronouns.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
8ball: color-coded answer text (green=positive, red=negative, amber=neutral)
for both the random and Jared/Wynter AI branches; question shown as small
italic below the answer; AI responses include model attribution.
fortune: teal header, answer in blockquote italics, model attribution shown
only when response came from the LLM (not the static fallback list).
ask: purple header, question in italic, response in blockquote, model
attribution at bottom.
trivia: blue header with category, green reveal answer, model attribution
shown only for LLM-generated questions (not static fallbacks).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Each !ask call is stateless — no context is retained between commands,
so ending a response with a question is misleading. Added explicit
instruction to the system prompt to prevent this.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
fortune: generates a fresh witty one-liner via Ollama on every call,
falls back to static list if LLM is unavailable.
ask: switched to /api/chat endpoint with a system prompt for better
conversational quality; now uses ASK_MODEL (default: gemma3:latest)
separately from the 8ball OLLAMA_MODEL so each can be tuned independently.
trivia: LLM generates a fresh question each time (no more repeating the
same 25 questions); supports !trivia <category> with six categories
(gaming, tech, general, movies, music, science); falls back to static
questions if JSON generation fails.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Remove unused imports: logging from bot.py and config.py, RoomMessageText/
UnknownEvent from callbacks.py, functools.partial and MAX_INPUT_LENGTH from
commands.py. Rename unused local variables to _ (resp in cmd_ping, symbols in
render_keyboard_plain, guesses_left in two wordle functions). Move wordle import
to top of commands.py to fix E402.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- When Jared asks a question containing Wynter's name, it now uses a
dedicated mock-Wynter prompt instead of the generic positive-Jared
one. The _is_positive_about_jared guard is also skipped for this
branch so negative words aimed at Wynter don't trigger the fallback.
Fallback changed from "Jared is absolutely right!" (nonsensical for
Wynter questions) to "Sounds about right — Wynter had it coming."
- Added ruff Python lint job to .gitea/workflows/lint.yml covering
matrixbot/ on every push and PR.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
All bot source files from LXC 151 (/opt/matrixbot) are now tracked here.
Secrets (.env, credentials.json), venv dirs, and runtime state files
(nio_store, welcome_state.json, wordle_stats.json) are excluded via .gitignore.
Includes deploy.sh to sync files to /opt/matrixbot and restart the service.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>