Releases: computator1200/hermes-ircx-plugin
Release list
IRCX v1.10.2: cleaner .agent errors + temporary model swaps
Patch fix for the .agent command bridge.
- No more leaked slash forms. An unknown
.agent <x>used to reply "Unknown command /x"; it now answers "unknown command: .agent x. Try '.agent help'", validated against the gateway registry before dispatch. - Model swaps are temporary by default.
.agent model <name>now applies for the current session only (no config write). Persist explicitly:.agent model <name> --persistsaves to this profile'sconfig.yaml.agent model <name> --globalsaves to the shared config (all profiles).agent model <name> --sessionis explicit session-only (the default)- a bare
.agent modelstill shows the current model
Note: Hermes' /model has no --persist flag of its own (it persists by default, with --session/--global modifiers); --persist here is provided by the bridge and maps to a profile-scoped save.
IRCX v1.10.1: fix connect() is_reconnect kwarg
Patch fix.
IRCXAdapter.connect() now accepts the is_reconnect keyword (and tolerates future kwargs) to match BasePlatformAdapter.connect(*, is_reconnect=False). The gateway passes is_reconnect on its (re)connect path, so enabling the ircx platforms via config/dashboard (rather than relying only on plugin registration) previously raised connect() got an unexpected keyword argument 'is_reconnect' and left both networks stuck in retry. Fixed.
IRCX v1.10.0: .agent + .ircx command split, live ircx.env config
Two command namespaces
Control the bot from a PM or in-channel (authorized users only). The previous .ircx <command> bridge was misleadingly named, so it is now split in two:
.agent <command> - the agent/gateway brain
Bridges to the central gateway slash commands: .agent model <name>, .agent reset, .agent reasoning high, .agent whoami, .agent status, and so on. .agent help lists them. (This is the renamed former .ircx bridge; set the prefix with IRCX_COMMAND_PREFIX.)
.ircx <command> - live adapter configuration
Configures this IRC plugin itself, on the fly:
.ircx list- every non-secret setting and its current value.ircx get <key>.ircx set <key> <value>- covers all non-secret options.ircx restart- restart the gateway to apply connection-level changes
Hot keys (observe mode, mention policy, blocked channels, raw guardrails, spontaneous %, allowed users, ...) apply instantly. Connection keys (server, port, nickname, channel, networks, sasl_*, log_dir, context_buffer) save and prompt for .ircx restart. It is multi-network aware: it acts on the network the message arrived on. Set the prefix with IRCX_ADMIN_PREFIX.
Dedicated config file: ircx.env
The plugin's many IRCX_* options can now live in a dedicated dotenv file pointed to by IRCX_CONFIG_FILE (e.g. <profile>/ircx.env), loaded on top of the environment at startup. This declutters the main profile .env, and .ircx set persists changes there.
Secrets stay safe: connection passwords (SASL / NickServ / server) remain in the main .env, are shown as *** by .ircx get, and cannot be set from chat (the agent reads untrusted channel input, so credentials are kept out of its reach).
Upgrade notes
- If you used
.ircx model ...before, that is now.agent model .... - To adopt the separate config file, set
IRCX_CONFIG_FILE=<profile>/ircx.envand move your non-secretIRCX_*lines into it (passwords stay in.env).
IRCX v1.9.0: .ircx command console, raw IRC, reliability fix
Highlights
.ircx command console (PM or in-channel)
Message the bot .ircx <command> to drive the same controls as the gateway slash commands: .ircx model <name>, .ircx reset, .ircx reasoning high, .ircx whoami, .ircx status, and more. .ircx help lists them. Authorized users only.
IRCX_COMMANDS_ENABLED(default true) andIRCX_COMMAND_PREFIX(default.ircx).- Gateway
/cmdreferences in help and error output are rewritten to the.ircx cmdform, so what you read matches how you type (URLs and file paths are left alone).
irc_raw tool (opt-in)
A new irc_raw tool sends raw IRC protocol lines (MODE, INVITE, WHO, LIST, KNOCK, services) for the long tail the dedicated tools do not cover.
- Off by default; enable with
IRCX_ALLOW_RAW=true. IRCX_RAW_GUARDRAILSsets policy strictness:high: refuse operator/server-destructive verbs (OPER, KILL, DIE, LINE, SA) and JOINs toIRCX_BLOCKED_CHANNELS.medium: refuse JOINs toIRCX_BLOCKED_CHANNELSonly.none: no policy guards.- CR/LF stripping and a length cap always apply at every level (protocol integrity, not policy).
Reliability
- Fixed a "Task cannot await on itself" error that could fire when the connection dropped while the receive loop was triggering disconnect.
Housekeeping
- Documentation, manifest, and comments cleaned up.
Note: this release folds in the .ircx command bridge that was developed internally as 1.8.0, so the public release goes 1.7.0 to 1.9.0.
IRCX v1.7.0 - multiple IRC networks in one gateway (shared memory)
One gateway can now host several IRC networks at once, all sharing the agent's memory, sessions, and persona - no second gateway, no split-brain.
✨ IRCX_NETWORKS
List extra networks; each <N> registers a platform ircx-<n> configured from an isolated IRCX_<N>_* env namespace. The primary network stays on the unprefixed IRCX_* vars (byte-identical, including legacy IRC_* fallbacks).
IRCX_SERVER=irc.rizon.net
IRCX_NICKNAME=pascal
IRCX_CHANNEL=#home
IRCX_NETWORKS=libera
IRCX_LIBERA_SERVER=irc.libera.chat
IRCX_LIBERA_NICKNAME=PascalAI
IRCX_LIBERA_CHANNEL=#mychan
IRCX_LIBERA_SASL_USERNAME=PascalAI
IRCX_LIBERA_SASL_PASSWORD=...Every IRCX_* setting has an IRCX_<N>_* counterpart (server/port/TLS/SASL/nick/channels/observe-mode/allowlists/BLOCKED_CHANNELS/logging/…).
How it works
load_config(env_prefix=…)and the module hooks (check_requirements/validate_config/is_connected/ env-enablement / cron sender) plus adapter-level auth reads are all prefix-aware; the legacyIRC_*fallback applies only to the primary.register()registers the primary plus one platform perIRCX_NETWORKSentry (runtime-registered Hermes platforms).- Shared memory: all instances run in one process under one profile → byterover/native memory, sessions, and persona are shared. Conversation sessions stay distinct per (network, channel).
- Network-aware tools: the
irc_*tools act on whichever network the agent was addressed in (resolved via the current-turn platform), falling back to the primary.
Pairs naturally with a soju bouncer: point each
IRCX_<N>_SERVERat soju withIRCX_<N>_SASL_USERNAME=<user>/<network>; soju multiplexes the upstreams while each instance stays a clean single-network connection.
Tests
6 new tests; full IRCX suite 156 passing, primary path unchanged. CI green.
IRCX v1.6.0 - irc_query: drive IRC services & bots (see their NOTICE replies)
The agent can now talk to IRC services and bots and actually see their replies.
The problem
Services (NickServ, ChanServ, MemoServ, HostServ, BotServ…) reply by NOTICE, and the adapter drops all NOTICEs for loop-safety. So an agent messaging ChanServ was "talking blind" - sending commands but never seeing the response.
irc_query
irc_query(target, text, timeout=8) sends a private message to a service/bot/nick and captures its reply - both NOTICE and PRIVMSG, multi-line, using an adaptive quiet-period - then returns the lines in-band.
irc_query ChanServ "INFO #ops" → ["#ops is registered", "Founder: …", …]
irc_query MemoServ "SEND alice hi!" → ["Memo sent to alice."]
irc_query NickServ "INFO pascal" → [...]
This unlocks the whole message-driven surface that needs no dedicated tools: registering/managing channels, sending memos to offline users, reading service INFO, and commanding any channel bot by its trigger syntax.
Design
- Reuses the async request/reply pattern from
irc_whois_server. - Capture is passive - it only collects replies for an in-flight query and never auto-responds, so it can't create NOTICE loops.
- Only private replies from the queried target are captured (channel chatter is ignored).
Tests
5 new tests; full IRCX suite 150 passing, no regressions. CI green.
IRCX v1.5.0 - IRCX_BLOCKED_CHANNELS denylist
A single blacklist variable to permanently ban a channel - handy for cutting off a costly public channel for good.
✨ IRCX_BLOCKED_CHANNELS
Comma-separated denylist of channels the bot must never be in. It always wins:
- Never auto-joined - even if the channel is also listed in
IRCX_CHANNEL. - Never joined on request -
irc_joinrefuses it even if a user PMs the bot to join, and even if it's in theIRCX_JOINABLE_CHANNELSallowlist. - Never answered in - if the bot somehow ends up in a blocked channel (e.g. a forced join), messages there are dropped before context/dispatch, so it can't run up cost.
IRCX_BLOCKED_CHANNELS=#World-Chat,#another-public-channelEnforced in three places: load_config (filtered out of auto-join), _join_allowed (checked before the allowlist), and the inbound message path (dropped).
Allowlist vs denylist:
IRCX_JOINABLE_CHANNELSis default-deny (list what's allowed);IRCX_BLOCKED_CHANNELSis default-allow (list what's banned) and overrides it. Use whichever fits.
✅ Tests
4 new tests; full IRCX suite 145 passing, no regressions. CI green.
IRCX v1.4.0 - agent can see channel events (joins/parts/quits)
The agent can now see who comes and goes in its channels - joins, parts, quits, kicks, and nick changes - not just messages.
✨ What's new
Set IRCX_SHOW_EVENTS=true (default off) and the bot records membership events into each channel's rolling context buffer (and the on-disk log), so they show up in channel_context on the next turn. Now the agent can greet a returning friend, notice someone left, or follow a nick change.
| Event | Recorded as |
|---|---|
| join | *** alice has joined #chan |
| part | *** alice has left #chan (reason) |
| quit | *** alice has quit IRC (reason) - to every channel shared with the bot |
| kick | *** bob was kicked from #chan by alice (reason) |
| nick | *** alice is now known as alice2 - to every shared channel |
🔒 Design / safety
- Pure visibility: events are context only - never dispatched as a prompt, so no reply storms.
- The bot's own joins/parts are skipped.
- Quits/nick-changes are attributed correctly across channels: shared membership is snapshotted before
parse_tokensremoves/renames the user. - Respects
group_policy: allowlistand the on-disk logging setting. - Off by default - it's noisy on large channels; enable per deployment.
✅ Tests
9 new tests; full IRCX suite 141 passing, no regressions. CI green.
IRCX v1.3.0 - 6 self-management tools (everyday IRC agency)
Six more agent-facing IRC tools, again drawn from the live bot's own wishlist - this round about self-management and ordinary participation: signalling availability, checking on people, recovering channel state, and setting boundaries. Like the v1.2.0 set, the state-changing tools enforce operator status server-side; nothing new is required on the wire in the common case.
✨ New tools
| Tool | What it does |
|---|---|
irc_away |
Set or clear the bot's away status - signal "stepping back" or a degraded state (shown on WHOIS / auto-reply). |
irc_whois_server |
Network-wide WHOIS that works even for users the bot shares no channel with. "Is X online right now?" → account, host, realname, server, idle, channels. (async request/reply on numerics 311/312/313/317/319/330/671/318, with timeout). |
irc_cycle |
Part + rejoin a channel to reset desynced state after a netsplit or lost op. The channel key is preserved across the cycle. |
irc_set_key |
First-class channel-key (+k) management; the key is remembered so reconnects rejoin with it. Requires the bot to be a channel op. |
irc_ignore / irc_unignore |
Temporarily mute a user - their messages are dropped (not answered, not buffered for context) until the timeout lapses, so it can't become permanent avoidance. Default 300 s, max 86400 s. |
🔒 Safety / design
- Ignored senders are dropped early in the inbound path (no reply, no context buffering); replayed history is exempt.
irc_set_key/irc_cyclerequire the bot to hold operator status - consistent withirc_mode/irc_topic/irc_kick. No new env flags.- All tools live in the
ircxtoolset (enable viaplatform_toolsets.ircx).
✅ Tests
12 new tests; full IRCX suite 132 passing, no regressions. CI green.
Note: a CTCP-response tool was also on the wishlist, but CTCP
VERSION/PING/TIME/SOURCE/CLIENTINFOresponses have shipped since v1.0.0 - verified, not rebuilt.
IRCX v1.2.0 - 7 new agent tools (from Pascal's wishlist)
Seven new agent-facing IRC tools, chosen from a live bot's own feature requests. All read channel state (membership, modes, topic, accounts) from the ircstates state machine; nothing new on the wire in the common case.
✨ New tools
| Tool | What it does |
|---|---|
irc_topic |
Read or set a channel's topic (setting may require op). |
irc_notice |
Send an IRC NOTICE - the convention for automated/non-conversational bot output. |
irc_search_history |
Search logged channel history by keyword / sender / channel (requires IRCX_LOG_DIR). "What did X say about Y earlier?" |
irc_nick |
Change the bot's own nick at runtime. |
irc_mode |
Read channel modes, or set them (set requires the bot to be a channel op). |
irc_kick |
Remove a user - gated: needs IRCX_ALLOW_AGENT_KICK=true and the bot must hold operator status. Refuses to kick itself. |
irc_accounts_online |
Which of your allowed users (by verified account or nick) are currently visible. |
🔒 Safety
irc_kickis double-gated (opt-in flag + bot-must-be-op) and off by default.irc_mode/irc_topicwrites require the bot to actually hold the needed channel rights; otherwise they return a clear error rather than failing silently.- All targets/args are CRLF/NUL-stripped (injection-safe); history search and log writes run off the event loop.
✅ Quality
120 network-free tests (was 106), +14 covering the new tools incl. the op-gating and history-search paths. CI green; live-verified on Rizon.
🤖 Generated with Claude Code