feat: add IRC channel support

Add comprehensive IRC over TLS channel implementation with:
- TLS support with optional certificate verification
- SASL PLAIN authentication (IRCv3)
- NickServ IDENTIFY authentication
- Server password support (for bouncers like ZNC)
- Channel and private message (DM) support
- Message splitting for IRC 512-byte line limit
- UTF-8 safe splitting at character boundaries
- Case-insensitive nickname allowlist
- IRC style prefix for LLM responses (plain text only)
- Configurable via TOML or onboard wizard

All 959 tests passing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Argenis 2026-02-15 10:00:15 -05:00 committed by GitHub
parent ef00cc9a66
commit b208cc940e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 1226 additions and 2 deletions

View file

@ -537,6 +537,7 @@ pub struct ChannelsConfig {
pub imessage: Option<IMessageConfig>,
pub matrix: Option<MatrixConfig>,
pub whatsapp: Option<WhatsAppConfig>,
pub irc: Option<IrcConfig>,
}
impl Default for ChannelsConfig {
@ -550,6 +551,7 @@ impl Default for ChannelsConfig {
imessage: None,
matrix: None,
whatsapp: None,
irc: None,
}
}
}
@ -612,6 +614,37 @@ pub struct WhatsAppConfig {
pub allowed_numbers: Vec<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct IrcConfig {
/// IRC server hostname
pub server: String,
/// IRC server port (default: 6697 for TLS)
#[serde(default = "default_irc_port")]
pub port: u16,
/// Bot nickname
pub nickname: String,
/// Username (defaults to nickname if not set)
pub username: Option<String>,
/// Channels to join on connect
#[serde(default)]
pub channels: Vec<String>,
/// Allowed nicknames (case-insensitive) or "*" for all
#[serde(default)]
pub allowed_users: Vec<String>,
/// Server password (for bouncers like ZNC)
pub server_password: Option<String>,
/// NickServ IDENTIFY password
pub nickserv_password: Option<String>,
/// SASL PLAIN password (IRCv3)
pub sasl_password: Option<String>,
/// Verify TLS certificate (default: true)
pub verify_tls: Option<bool>,
}
fn default_irc_port() -> u16 {
6697
}
// ── Config impl ──────────────────────────────────────────────────
impl Default for Config {
@ -847,6 +880,7 @@ mod tests {
imessage: None,
matrix: None,
whatsapp: None,
irc: None,
},
memory: MemoryConfig::default(),
tunnel: TunnelConfig::default(),
@ -1059,6 +1093,7 @@ default_temperature = 0.7
allowed_users: vec!["@u:m".into()],
}),
whatsapp: None,
irc: None,
};
let toml_str = toml::to_string_pretty(&c).unwrap();
let parsed: ChannelsConfig = toml::from_str(&toml_str).unwrap();
@ -1215,6 +1250,7 @@ channel_id = "C123"
app_secret: None,
allowed_numbers: vec!["+1".into()],
}),
irc: None,
};
let toml_str = toml::to_string_pretty(&c).unwrap();
let parsed: ChannelsConfig = toml::from_str(&toml_str).unwrap();