====== chat_llm_irc: IRC bot adapter ======

''chat_llm_irc'' is a standalone IRC client that lets the [[module:chat_llm|LLM
Guru]] participate in IRC channels.  It connects to a server, joins one or more
channels, and speaks in just two situations — otherwise it lurks silently:

  - **Direct address** — someone says the bot's nick (or a configured alias) in the channel.  The bot replies, prefixing the questioner's nick.
  - **High-confidence intervention** — someone asks a question (a line ending in ''?''), nobody answers within ''irc_intervention_wait'' seconds, and the bot's retrieval score for that question clears a confidence floor.  The bot then volunteers an answer.  A per-channel cooldown keeps it from dominating.

The adapter lives in ''exec/chat_llm_irc.js'' and shares the engine, memory,
tools, and RAG described under [[module:chat_llm]].

===== Running it =====

Normally run as a Synchronet **service**.  Add a block to ''ctrl/services.ini'':

<code ini>
[GuruIRC]
Cmd        = ?chat_llm_irc.js
Port       = 0
MaxClients = 1
Options    = STATIC | NO_HOST_LOOKUP
</code>

For a one-shot test from the command line:

<code>
jsexec chat_llm_irc.js [persona]
</code>

The optional persona argument selects the [[config:chat_llm.ini]] section to
read (default ''guru:irc'', layered over ''[default]'').

===== Configuration =====

IRC-specific keys go in the persona's [[config:chat_llm.ini]] section (backend,
model, prompts, memory, and RAG settings are shared with the engine and
documented there):

^ Key ^ Default ^ Purpose ^
| ''irc_network'' | ''irc.synchro.net'' | IRC server to connect to. |
| ''irc_port'' | ''6667'' | Server port. |
| ''irc_channels'' | ''#synchronet'' | Comma-separated list of channels to join. |
| ''irc_nick'' | derived | Bot nick.  Defaults to a name derived from the system QWK ID and persona; a ''_'' is appended on collision. |
| ''irc_aliases'' | //(none)// | Comma-separated extra names the bot answers to, e.g. ''%%guru, Guru, The Guru%%''.  The actual nick is always matched in addition. |
| ''irc_nickserv_password'' | //(none)// | Optional NickServ ''IDENTIFY'' password. |
| ''irc_intervention_wait'' | ''120'' | Seconds an unanswered question must sit before the bot may chime in. |
| ''irc_intervention_cooldown'' | ''900'' | Minimum seconds between unprompted interventions per channel. |
| ''irc_intervention_min_score_per_token'' | ''8.0'' | Retrieval score-per-token floor for "confident enough to volunteer" (well above the baseline injection gate of ''3.5''). |

===== Runtime files =====

The bot uses two locations.  Short-lived signals and logs sit in the
data-directory root under a base name derived from the persona
(''guru:irc'' → ''guru_irc'').  Persistent per-persona state lives in the
persona's sub-directory ''data/chat/<name>/'' — where ''<name>'' is the code
before the '':'' (''guru'') and each file is prefixed with the mode after it
(''irc'') — alongside the shared RAG index and the per-speaker memory files.

^ File ^ Purpose ^
| ''data/<base>.stop'' | Clean-shutdown signal (see below). |
| ''data/<base>.announce'' | One-shot JOIN announcement (see below). |
| ''data/<base>_bot.log'', ''data/<base>_chat.log'' | Bot and conversation logs. |
| ''data/chat/<name>/<mode>_relay.json'' | Queued [[module:llm_tools|relay_message]] deliveries. |
| ''data/chat/<name>/<mode>_seen.json'' | Nicks the bot has seen (used to accept relays for absent users). |
| ''data/chat/<name>/<mode>_mute.json'' | Users who told the bot to stay quiet toward them. |
| ''data/chat/<name>/<mode>_norelay.json'' | Users who opted out of receiving relayed messages. |

===== Clean shutdown =====

The services subsystem terminates a service abruptly, which doesn't let the
bot leave IRC gracefully.  To quit cleanly:

  - Create ''data/<base>.stop'' (e.g. ''%%touch data/guru_irc.stop%%'').  The bot sees it, sends a ''QUIT'', and exits; it then removes the file.
  - Wait a second or two for the ''QUIT'' to reach the server.
  - Then recycle or shut down the Services server.

===== Announcing changes =====

To have the bot post a short message when it next joins a channel, write the
text (one line per channel message) to ''data/<base>.announce'' before starting
it.  The bot posts each line once on JOIN, then deletes the file so it doesn't
repeat on reconnect.

===== Memory in public channels =====

Per-speaker memory is keyed by ''irc:<server>/<nick>'', so a user's history
follows their nick.  In open channels full of strangers you may not want to
retain anything — set ''memory_persist = false'' in the bot's persona section
(see [[config:chat_llm.ini#persistent_memory]]).

===== See Also =====

  * [[module:chat_llm]] — the shared chat engine
  * [[config:chat_llm.ini]] — all configuration keys
  * [[module:llm_tools]] — the ''relay_message'' tool this adapter delivers
  * [[howto:llm-guru]] — start-to-finish setup

{{tag>chat guru llm chat_llm irc bot ai}}
