This one was not about adding a giant new subsystem.
It was not about changing the database schema.
It was not about summoning a dragon and hoping it would behave.
This was the quiet but important kind of work: making existing commands sharper, outputs clearer, diagnostics more useful, and the whole bot nicer to operate on real IRC channels.
In Hogwarts terms, this was not a flashy tournament spell.
It was more like walking through the castle at night with a lantern, checking every corridor, tightening every enchanted hinge, silencing noisy portraits, and making sure Peeves did not hide a regression in the plumbing.
And honestly, that kind of work matters.
The rule was simple:
Improve existing behavior.
Fix small bugs.
Polish command output.
Do not touch the database schema.
Prepare a clean commit.
Mediabot v3 already has a lot of history behind it. It is not a toy bot freshly written last weekend. It has old features, new modules, IRC-specific behavior, AI integration, Partyline tooling, radio commands, statistics, karma, quotes, reminders, and a lot of small features that people actually use.
So this pass focused on making the bot feel more coherent.
Not more complicated.
Just better.
Several command paths now produce more useful debug information.
The old debug message was generic:
Check SQL command : kk
It worked, but it lacked context.
Now the dispatch log is more useful:
mbDbCommand: !kk on #boulets by teuk
That gives the command, the channel, and the caller in one line.
Much better when reading logs after something strange happened on IRC.
Private commands also got cleaner DEBUG3 logging:
mbCommandPrivate: !ai from teuk
The special q command remains quiet, because logging someone leaving a session is not exactly the most thrilling prophecy in the tower.
When a command is blocked by cooldown, the logs now say so clearly:
checkCmdCooldown() blocking !ai on #boulets — 8s remaining
That is the kind of detail you want when diagnosing “why did the bot not answer?”
The Claude integration keeps getting more mature.
Both IRC-side !ai quota and Partyline .quota now respect the configured values:
anthropic.RATE_MAX
anthropic.RATE_WINDOW
No more hardcoded “5 requests / 60 seconds” in one place while another part of the bot reads the configuration.
That sort of inconsistency is how cursed objects are born.
Partyline quota output now includes both the relative wait time and the reset clock time:
teuk #boulets 3/5 req (1m 33s left, resets 11:42)
That is much more useful than raw seconds. Humans should not need to perform arithmetic just to know when the cauldron is ready again.
.ai statusA new Partyline AI status command gives a compact overview:
Claude: 3 session(s) (~2.4k chars), 2 pinned, 1 persona(s).
This is excellent operational visibility. It tells you how much AI context is alive in memory without digging through internal structures.
.ai historyAI history output now includes exchanges and approximate character count:
6 message(s) in context (3 exchange(s), ~840 chars):
This makes it easier to understand how much context the bot is carrying.
A lot of this polish pass improved existing statistics commands.
!stats: channel rankThe !stats output now includes the user’s rank on the channel:
teuk: 342 msg(s) (8.7%) on #boulets | rank: #12 | first seen: ...
That small rank: #12 makes the output immediately more meaningful.
!active: activity countsBefore:
Active in last 24h on #boulets: teuk, Gwen, bot42 (3 nick(s))
After:
Active in last 24h on #boulets: teuk(142), Gwen(89), bot42(12) (3 nick(s))
This is far better. It shows both who was active and how active they were.
!when: total message countThe !when command now includes the total number of messages:
teuk first seen on #boulets: 2024-03-15 14:22:07 (1y 2m ago), 1204 msg(s)
That turns a historical lookup into a useful summary.
!last: exact timeBefore:
teuk last said (3h 15m ago on #boulets): "bonjour tout le monde"
After:
teuk last said (3h 15m ago, 14:23 on #boulets): "bonjour tout le monde"
That exact time is a small detail, but it makes the command much more pleasant.
!compare: absolute leadBefore:
teuk: 142 msg(s) (61%) | Gwen: 89 msg(s) (39%) | teuk leads
After:
teuk: 142 msg(s) (61%) | Gwen: 89 msg(s) (39%) | teuk leads by 53 msg(s)
No ambiguity. No mental subtraction. Just the answer.
The karma system also received several small but useful improvements.
!karmadiff: current score includedBefore:
teuk: karma changed by +3 in the last 24h (7 vote(s)).
After:
teuk: karma changed by +3 in the last 24h (7 vote(s), score: +42).
This gives both the movement and the current state.
!karmahist: summary in the headerBefore:
teuk: recent karma changes on #boulets:
After:
teuk: recent karma changes on #boulets (+5/-2):
The header now immediately tells whether the recent karma movement was mostly positive or negative.
!karmainfo: log periodThe command now shows the memory window covered by the in-memory karma log:
karmainfo teuk [score: +42] (last 7d in log): ...
That is honest and useful. It tells the user the scope of the displayed data instead of pretending the in-memory buffer is eternal.
Several smaller commands were cleaned up too.
!pollresult: winner in the headerPoll results now show the winner immediately:
open poll: "Best language?" (8 vote(s)) Winner: Perl (62%):
The full detail is still shown below, but the answer is visible right away.
!triviatop: percentagesTrivia top results now include percentages:
Trivia hall of fame: #1. teuk: 7 (58%) #2. Gwen: 4 (33%)
That makes the hall of fame easier to read at a glance.
!note search: result ratioBefore:
2 note(s) matching 'doctor':
After:
2/5 note(s) matching 'doctor':
It now shows how many results matched out of the user’s total notes.
!abbrev: source word countBefore:
teuk: RATM
After:
teuk: RATM (4 word(s))
Tiny improvement. Nice output.
Custom commands are one of Mediabot’s oldest and most useful features, so they got some attention too.
!modcmd: show previous valueBefore:
Modifying command kk [message] karma++ %N
After:
Modifying command kk [message] (was: PRIVMSG %c karma++ %N)
That is much safer. When changing a command, seeing the old action helps avoid accidental edits.
!countcmd: page countBefore:
countcmd[01]: addcmd remcmd ...
After:
countcmd[01/04]: addcmd remcmd ...
Much better when the result spans multiple pages.
!owncmd: percentage by authorBefore:
teuk(42) Gwen(15) bot(8)
After:
teuk(42,64%) Gwen(15,23%) bot(8,12%)
This gives a clearer view of who owns how much command content.
!calclast: result count in headerBefore:
Last calc(s):
After:
Last 3 calc(s):
Small, clear, useful.
Time formatting was made more consistent.
!timersBefore:
myTimer - every 3600s - !karma
After:
myTimer - every 1h00m - !karma
!addtimerBefore:
Timer mytimer added
After:
Timer mytimer added (every 1h00m): PRIVMSG #boulets !karma
The bot now confirms not only that the timer was created, but also the interval and command. That is much safer.
.schedule listPartyline schedule output also uses human-readable intervals:
claude_history_purge 1h00m running 4
instead of raw seconds.
.cmdcooldownCooldown list and set confirmation are now clearer:
Cooldown for !ai on #boulets set to 1m20s.
Cooldown for !ai on #boulets removed.
Good admin tooling should not feel like deciphering runes.
The radio commands were not the main subject this time, but a couple of nice improvements landed.
!radiostatus: compact outputBefore, the command could produce four NOTICE lines.
Now it is reduced to two lines:
Icecast teuk.org | /stream | 128k | 1 listener(s) | Electro Mix Vol.3
Listen: http://teuk.org:8000/stream
Less spam. More signal.
!radiomountsAlready polished previously, the compact direction continues: IRC output should be readable, not a parchment scroll rolling across the channel.
!q statsQuote stats now use a cleaner format:
Quotes on #boulets: 42 total — oldest 3y 2m ago, latest 2d ago
!userstatsUser stats are now summarized on a single line:
Users: 42 total — Master:3, Friend:12, Registered:27
This is much better than multiple notices for a simple summary.
!cstatAuthenticated user stats now include a level summary in the header:
Authenticated users: 12 (Administrator:2, Friend:5, Registered:5)
!resolveResolution output is now cleaner:
1.2.3.4 => host.example.com
host.example.com => 1.2.3.4, 1.2.3.5
The old arrow format worked, but the new one is easier to scan.
One important thing was caught before commit: the Partyline quota function had some dirty source formatting from earlier patching.
It contained literal line breaks inside strings and a weird control character around the internal \x00 split.
That was cleaned up properly.
The final version keeps:
.quota;.quota nick;but uses clean source code:
$stream->write("No active rate limit windows.\r\n");
my ($nick_k, $chan_k) = split /\x00/, $key, 2;
This is exactly why double-checking matters.
Claude did good work.
The second review caught the cursed splinter in the wand.
This pass deliberately avoids schema changes.
No schema migration.
No new table.
No new column.
Everything here is application-level polish:
That makes the commit safer to review and easier to deploy.
IRC:
m check
m stats teuk
m active
m last teuk
m compare teuk Gwen
m karmadiff teuk
m karmahist teuk
m karmainfo teuk
m pollresult
m timers
m addtimer test 3600 PRIVMSG #test hello
m countcmd
m owncmd
m whotalk
m uptime
m q stats
m userstats
m note search test
m resolve teuk.org
m radiostatus
m ai quota
Partyline:
.quota
.quota teuk
.ai status
.ai history
.schedule list
.cmdcooldown list
.history
.logs
Code checks:
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/Mediabot.pm
perl -I. -c Mediabot/Partyline.pm
perl -I. -c Mediabot/UserCommands.pm
perl -I. -c Mediabot/Quotes.pm
perl -I. -c Mediabot/Hailo.pm
And one last anti-cursed-source check:
LC_ALL=C grep -P '\x00' -n Mediabot/Partyline.pm || true
git diff --check
This was a large polish pass, but a sane one.
Mediabot now feels sharper across many small commands:
This is not the kind of commit that screams.
It is the kind of commit that makes the bot feel well-maintained.
Suggested commit spell:
✨ Lumos Maxima: refine command output, Partyline diagnostics, and IRC stats
Alternative:
🧭 Marauder's Polish: improve command clarity and Partyline diagnostics
You must be logged in to reply.