Forum teuk.org

πŸ§ͺ🧹 Mediabot v3: The Cauldron Ledger Pass β€” Trivia, Karma, Prometheus, and Living IRC Memory

in Mediabot Β· started by TeuK Β· 3w ago

TeuK Β· 3w ago

This update was not a phoenix flight, not a Time‑Turner experiment, and not another great refactoring of the castle walls.

This was more like walking into the Potions classroom after midnight, finding every vial, label, ledger, and cauldron slightly out of place, and deciding that tonight was the night everything would become orderly.

The result is a very practical Mediabot v3 pass:

  • better trivia commands;
  • richer active-user and last-message tools;
  • persistent karma history;
  • safer nicklist handling;
  • stronger Partyline user introspection;
  • more Prometheus metrics;
  • cleaner AI summary feedback;
  • schema alignment for fresh installs.

No grand speech from Dumbledore.

Just a lot of useful magic that makes the bot easier to use, easier to observe, and harder to break.


🧾 The big structural point: KARMA_LOG is now part of the schema

The important database-side change is the new KARMA_LOG table.

Until now, karma history could fall back to an in-memory ring buffer when the persistent table was missing. That was safe, but not ideal: after a restart, history could disappear.

The new migration:

install/migrations/20260603_karma_log.sql

creates the persistent karma history table used by !karmahist.

The fresh-install schema was also aligned:

install/mediabot.sql

now contains KARMA_LOG too.

That matters because a fresh install should not be weaker than a migrated install.

A new wizard should receive the same spellbook as an old one.


πŸͺ™ Karma history becomes more serious

With KARMA_LOG, karma history is no longer just a memory charm floating around inside the bot.

It can now be persisted properly.

That gives commands like:

!karmahist teuk

a much better long-term foundation.

The bot can still behave gracefully if the table is absent, but the intended modern setup now has a real table behind it.

The cauldron keeps the receipts.


πŸ“ˆ !karmadiff learned bigger moves

!karmadiff was improved in two directions.

First, it accepts flexible windows:

!karmadiff teuk 3d
!karmadiff teuk 30d
!karmadiff teuk 2h

with sensible limits.

Then it gained an overview mode:

!karmadiff all
!karmadiff all 7d

This shows the top karma movers over the selected period:

Karma top movers (last 7d): menz: +12 | teuk: +8 | fantom: -4

That turns karma from a single-person lookup into a channel mood detector.

A little emotional seismograph for IRC.


🧠 !ai models now asks the source

The !ai models command can now query the Anthropic API dynamically when an API key is configured.

If the API responds, the bot shows live model data with a [live] badge.

If the API is unavailable, missing, or slow, it falls back to the static list with [static].

That is the right behavior:

Try the owl post.
If the owl is lost, use the noticeboard.

The command becomes more useful without making the bot fragile.


πŸ•― !ai summary now gives immediate feedback

AI summaries can take a few seconds.

That is normal, but on IRC silence feels like a broken command.

Now, before calling Claude, Mediabot tells the user how many messages are about to be summarized:

Summarising 42 message(s) on #boulets...

That small line changes the feeling of the command completely.

The user knows the spell has started.

No more staring at the wand wondering if it fizzled.


🧩 !ai summary today <nick> was checked

The parsing for nick-filtered AI summaries was audited and confirmed functional.

That means forms like:

!ai summary today teuk

are already correctly handled.

No extra code was needed there.

Sometimes the best fix is noticing that the spell is already correct.


πŸ† Trivia became a real mini-game

Trivia received a lot of love in this pass.

Leaderboard

New command:

!trivia leaderboard
!trivia leaderboard 10

It shows the best players on the channel using the existing TRIVIA_SCORES table.

Personal score

New command:

!trivia myscore
!trivia myscore menz

It displays score, rank, and last correct answer timestamp.

Reset support

Trivia reset became easier to access:

!trivia reset menz
!trivia reset

The nick-specific reset remains compatible with the older !triviareset command.

Difficulty selection

Trivia now accepts difficulty:

!trivia easy
!trivia medium
!trivia hard
!trivia computers hard

The difficulty is passed to OpenTrivia DB.

Difficulty display everywhere

Difficulty tags are now visible in all important trivia moments:

  • question;
  • correct answer;
  • timeout.

Example:

Trivia [HARD] (Science: Computers): ...
Correct, teuk! [HARD] The answer was: Radon
Time's up! [HARD] The answer was: Radon

This makes the game feel much more polished.

Not just a question scroll β€” a proper little Hogwarts quiz duel.


🧍 !active now can show the quiet people too

!active now now does more than show who spoke recently.

It can also show people present in the channel nicklist who have not talked in the last hour:

Present but silent in last 60min: gwen, Bot3 (2 nick(s))

That is a lovely IRC-specific detail.

Because presence is not the same as speaking.

Sometimes the ghosts are in the room, just quiet.


πŸ“† !active month was added

!active now supports:

!active month

This gives activity since the beginning of the current month.

Together with earlier modes like today, yesterday, week, and now, the command is becoming much more human-friendly.

You no longer need to think in raw hour windows for common questions.


πŸ•° !last <nick> [n]

The !last command can now show more than one message:

!last teuk 3

The output is limited to avoid flood and displayed chronologically.

This is a very useful operator/community command: you can quickly see the last few things someone said without digging through logs manually.

A small Pensieve sip, not the whole lake.


πŸ§™ Partyline .nickinfo and .who now use the real schema

Two Partyline commands had old or incorrect SQL assumptions about the USER schema.

They referenced names such as:

u.nick
u.email
USER_HOST
USER_LOG
LEVEL

But the real schema uses:

USER.nickname
USER_LEVEL
USER_HOSTMASK
ACTIONS_LOG

The commands were rewritten against the real schema.

So .nickinfo <nick> and .who <#chan> should now stop pretending users do not exist.

The castle records were there.
The command was just looking in the wrong filing cabinet.


🧭 .seen remains improved

The recent .seen improvements remain part of the overall direction:

.seen Te[u]K
.seen teu*

Exact match normalizes case, and wildcard lookup works.

That gives Partyline the same spirit as the IRC-side seen command.


🎲 Safer nicklist handling

Several race-condition style crashes were addressed around channel nicklists.

getRandomNick

getRandomNick($channel) now guards against unknown or uninitialized channels before dereferencing the nicklist.

This matters for dynamic commands using %r.

channelNicksRemove

channelNicksRemove now checks that the nicklist exists and is an array before trying to remove a nick.

on_message_NICK

Nick changes during startup or partial nicklist initialization no longer assume the channel nicklist is always ready.

These are not flashy changes, but they are exactly the kind of defensive code that keeps a long-running IRC bot alive.

No exploding cauldron just because a JOIN, QUIT, KICK or NICK arrives at an awkward moment.


πŸ“œ Quotes got more consistent

The recent quote improvements are now part of the stable direction:

  • !q random avoids immediate repeat;
  • !q <nick> also avoids immediate repeat;
  • !q view truncates huge quotes;
  • !q search ranks by relevance;
  • !q stats includes the top contributor.

These changes make the quote system feel much more mature.

Less random parchment avalanche.
More curated spell archive.


πŸ“Š Prometheus gained more IRC life signals

Several new Prometheus counters were added:

mediabot_urltitle_requests_total{type=...}
mediabot_nick_changes_total
mediabot_joins_total{channel=...}
mediabot_parts_total{channel=...}

That gives better observability over:

  • URL title activity by type;
  • nick-change bursts;
  • channel joins;
  • channel parts.

This is useful not only for dashboards, but also for understanding IRC network behavior.

If the castle suddenly fills with owls, the metrics should show it.


πŸ”— URL title metrics by type

URL title handling now increments counters by URL family:

youtube
instagram
spotify
applemusic
facebook
x_twitter
generic

This will make Grafana much more interesting later.

Instead of just knowing that URL titles are happening, we can see what kind of links people actually share.

That is good dashboard material.


🧹 Reminder cancel was fixed

!remind cancel <id> now normalizes the caller nick with lc($nick) before matching against from_nick.

That fixes cases where IRC nick casing differs from the lowercase value stored in the database.

A reminder should not become impossible to cancel just because the nick has fancy casing.


πŸ“š POD documentation for Mediabot::User

Mediabot::User received better POD documentation.

The accessors and level helpers are documented more clearly, including the user level hierarchy:

User < Administrator < Master < Owner

This is not glamorous, but it matters.

Future refactoring is safer when the objects explain themselves.


πŸ§ͺ Suggested regression tests

Shell checks

perl -I. -c Mediabot/UserCommands.pm
perl -I. -c Mediabot/Partyline.pm
perl -I. -c Mediabot/Quotes.pm
perl -I. -c Mediabot/Helpers.pm
perl -I. -c Mediabot/External/Claude.pm
perl -I. -c Mediabot/External/URL.pm
perl -I. -c mediabot.pl

LC_ALL=C grep -P '\x00' -n Mediabot/*.pm Mediabot/*/*.pm || true
grep -rn "cl\.text\b\|ORDER BY cl\.id\b" Mediabot/ || true
git diff --check

Schema checks

grep -n "CREATE TABLE .*KARMA_LOG" install/mediabot.sql
grep -n "fk_karma_log_channel" install/mediabot.sql
grep -n "20260603_karma_log.sql" install/migrations/README.md

perl tools/check_schema_drift.pl --conf=mediabot.conf --strict

IRC tests

m q random
m q view 1
m q search teuk trivia
m q stats

m trivia leaderboard
m trivia myscore
m trivia hard
m trivia reset teuk

m active now
m active month
m last teuk 3

m karmadiff all 7d
m karmahist teuk

m ai models
m ai summary today teuk

Partyline tests

.nickinfo teuk
.who #teuk
.seen Te[u]K
.seen teu*
.top
.top #teuk 5

🏁 Final status

This was the Cauldron Ledger pass.

Mediabot now has:

  • persistent karma history schema;
  • migration docs aligned with fresh installs;
  • better trivia gameplay;
  • better active-user visibility;
  • better last-message lookup;
  • stronger Partyline user inspection;
  • safer nicklist handling;
  • richer Prometheus metrics;
  • cleaner AI summary feedback;
  • better quote behavior;
  • no hidden schema mismatch between migrations and fresh installs.

The shelves are labeled.
The potion bottles are capped.
The ledger finally balances.

The ink is dry; send the owl.

You must be logged in to reply.