After the large radio integration and the previous mb76 cleanup pass, Mediabot v3 went through another round of refinement: mb80 / mb81.
This was not a database-schema migration.
This was not a risky rewrite.
This was another careful Hogwarts-style polish pass:
keep the bot stable, make commands nicer to use, reduce noise, and improve the small daily details that matter on IRC.
A lot of this work is not spectacular at first glance. But it is exactly the kind of work that makes an old IRC bot feel sharper, cleaner, and more comfortable to operate.
Mischief was reviewed. Regressions were hunted. And a few little cursed edge cases were sent back to Azkaban.
The mb80/mb81 work focused on existing features:
The guiding principle stayed the same:
Improve what exists.
Do not break old behavior.
Do not change the DB schema.
Keep the bot pleasant to use.
!karmareset: show the previous scoreBefore:
teuk reset karma for Gwen to 0.
After:
teuk reset karma for Gwen to 0 (was +42).
This is a small but useful improvement. Resetting karma is an admin action, and showing the old value gives immediate context.
No magic smoke, no guessing, no “wait, what was it before?” moment.
Claude API calls now support a configurable temperature:
anthropic.TEMPERATURE = 0.7
The value is clamped between 0.0 and 1.0.
Default behavior remains unchanged when the key is absent.
This lets each Mediabot instance decide whether Claude should behave more like Hermione with a checklist, or Luna after three cups of tea.
!alias list: count in the headerBefore, the alias list started directly with entries.
Now it announces the total:
3 alias(es) defined:
kk => karma++ teuk
lol => 8ball is this funny?
stats => top 5
Small improvement, but much clearer.
!showcmd: command ageCommand metadata now includes a readable age:
Command : kk Author : teuk Created : 2024-03-15 14:22:07 (442d ago)
That makes old custom commands easier to understand. Some commands are fresh spells. Some are ancient scrolls from another era.
Several commands now display time in a more readable form.
!radiodlstatusBefore:
Radio download: pid=12345 alive=1 age=165s timeout=180s
After:
Radio download: pid=12345 alive=1 age=2m 45s timeout=180s
.dccstatBefore:
Age: 165s
After:
Age: 2m 45s
.quotaBefore:
teuk #boulets 3/5 req (93s left)
After:
teuk #boulets 3/5 req (1m 33s left)
Readable time matters. Humans should not need to mentally parse raw seconds every time the bot speaks.
!searchcmd: show hit countsSearch results now include command usage counts.
Before:
Commands containing 'karma': 5 result(s) — karmatop | karmainfo | karma
After:
karmatop(142) | karmainfo(89) | karma(1204)
This helps identify which matching commands are actually used.
!topcmd: percentagesTop command output now includes cleaner percentage formatting:
karma(1204, 18.3%)
instead of a rougher format without punctuation.
!lastcmd: better age displayRecent commands no longer need to show ugly output like:
0h ago
They can now report minutes or just now, which feels much better in practice.
Claude debug logs now show the approximate history size:
claudeAI() → claude-sonnet-4-5 for #boulets / teuk [hist: 3 msg(s), ~840 chars]
This is useful when debugging why Claude behaves a certain way, or when checking whether history is growing too much.
.ai pin listA new Partyline command lets admins see active Claude pins:
.ai pin list
Example output:
Active Claude pins:
teuk #boulets You are a helpful culinary assistant...
Gwen #phat Reply only with emoji...
This makes active in-memory prompt overrides visible instead of mysterious.
.ai history clear [nick]Claude history can now be cleared from Partyline:
.ai history clear teuk
.ai history clear
This clears _claude_history and _ai_last_active for the target nick.
Useful when a conversation context becomes stale, weird, or cursed.
.logs: full date for older entriesSame-day entries still use a compact time:
[14:23] <Gwen> hello
Older entries show the full date:
[2026-05-29 14:23] <teuk> hello
That makes Partyline logs much easier to read across days.
.nickinfo: last login ageNick info now includes a readable age for the last login:
Last login: 2024-03-15 14:22:07 (442d ago)
.who #channel: sorted by privilege levelPartyline .who now sorts users by DB privilege level first, then alphabetically.
That means important users appear first:
@teuk [500] @Gwen [200] WindropBot Boolozorus2 bot42
Much more useful than a flat alphabetical list.
.history: command timestampsPartyline command history now includes the time at which commands were run:
Recent commands:
1 14:23 .stat
2 14:25 .schedule list
The timestamp is stored when the command is pushed into history, so it reflects the real execution time.
.netsplit: last event ageNetsplit diagnostics now include the age of the last event when available:
Netsplit QUITs since last reconnect: 23 (last: 4h12m ago)
Good operational detail. Small spell, useful spell.
!radiomounts: compact outputThe old mount output could be too verbose for IRC:
/stream | 128k | listeners=3 | title=Teuk Hits | desc=... | url=http://...
The new format is compact:
/stream | 128k | 3 listeners | Teuk Hits
Long URLs and redundant descriptions are removed from the normal display.
!radiodlstatus: readable ageAs mentioned earlier, active radio downloads now show readable duration:
age=2m 45s
instead of raw seconds.
YouTube output now uses compact view counts:
views 1.2M
instead of:
views 1234567
This applies consistently to YouTube details and search output.
Generic URL titles now include the source domain:
URL example.com teuk: My article title
This is more informative than a generic “URL Title” badge.
It helps users understand where the preview came from before clicking.
!hailo statusHailo brain stats are now more readable:
Hailo stats: 23847 tokens, 47692 entries | ~23k tokens, 3.8 links/token
The old raw output was accurate, but less pleasant.
Trivia output now includes percentages and total score context, making the result easier to understand at a glance.
A final review found a few tiny consistency issues, and they were polished too:
.quota now respects configured anthropic.RATE_MAX / anthropic.RATE_WINDOW;!ai quota was aligned with the same configurable limits;!searchcmd summary now shows the actual requested limit;!topcmd percentage formatting was cleaned up;!lastcmd avoids ugly 0h ago output.These are small details, but they prevent the bot from feeling inconsistent.
A good bot should not say “5/5” in one place and use custom configured quota values somewhere else.
That is how cursed objects are born.
This pass deliberately avoided DB schema changes.
No schema migration required.
No table changes.
No column changes.
Everything here is application-level polish:
That makes the commit much safer to review and deploy.
Before pushing, the following commands are good smoke tests.
IRC:
m check
m searchcmd karma
m searchcmd karma 12
m topcmd
m lastcmd
m showcmd karma
m alias list
m radiomounts
m radiodlstatus
m ai quota
m yt test
m hailo status
Partyline:
.stat
.logs
.quota
.quota teuk
.nickinfo teuk
.who #teuk
.history
.dccstat
.netsplit
.ai pin list
.ai history
.ai history clear teuk
And, as always:
perl -I. -c mediabot.pl
perl -I. -c Mediabot/AdminCommands.pm
perl -I. -c Mediabot/ChannelCommands.pm
perl -I. -c Mediabot/DBCommands.pm
perl -I. -c Mediabot/External.pm
perl -I. -c Mediabot/Helpers.pm
perl -I. -c Mediabot/Partyline.pm
perl -I. -c Mediabot/UserCommands.pm
mb80/mb81 is a polish pass, but a meaningful one.
Mediabot now feels more consistent:
This is the kind of commit that does not shout, but makes everything nicer.
Suggested commit spell:
🪄 Lumos mb81: polish commands, Partyline diagnostics, and AI output
Alternative:
🧹 Protego mb81: refine command output and quieter bot diagnostics
You must be logged in to reply.