feat: add OpenRouter LLM chat plugin (!ask, !chat)

Single-shot (!ask) and conversational (!chat) LLM commands backed by
OpenRouter's API. Per-user history (20 msg cap), 5s cooldown, reasoning
model fallback, and model switching via subcommands.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
user
2026-02-22 05:39:11 +01:00
parent 66116d2caf
commit 95981275b5
4 changed files with 889 additions and 0 deletions

View File

@@ -187,6 +187,8 @@ unchanged. The server name is derived from the hostname automatically.
| `!username list` | Show available services by category |
| `!alert <add\|del\|list\|check\|info\|history>` | Keyword alert subscriptions across platforms |
| `!searx <query>` | Search SearXNG and show top results |
| `!ask <question>` | Single-shot LLM question via OpenRouter |
| `!chat <msg\|clear\|model\|models>` | Conversational LLM chat with history |
| `!jwt <token>` | Decode JWT header, claims, and flag issues |
| `!mac <address\|random\|update>` | MAC OUI vendor lookup / random MAC |
| `!abuse <ip> [ip2 ...]` | AbuseIPDB reputation check |
@@ -815,6 +817,55 @@ Title Two -- https://example.com/page2
Title Three -- https://example.com/page3
```
### `!ask` / `!chat` -- LLM Chat (OpenRouter)
Chat with large language models via [OpenRouter](https://openrouter.ai/)'s
API. `!ask` is stateless (single question), `!chat` maintains per-user
conversation history.
```
!ask <question> Single-shot question (no history)
!chat <message> Chat with conversation history
!chat clear Clear your history
!chat model Show current model
!chat model <name> Switch model
!chat models List suggested free models
```
Output format:
```
<alice> !ask what is DNS
<derp> DNS (Domain Name System) translates domain names to IP addresses...
<alice> !chat explain TCP
<derp> TCP is a connection-oriented transport protocol...
<alice> !chat how does the handshake work
<derp> The TCP three-way handshake: SYN, SYN-ACK, ACK...
```
- Open to all users, works in channels and PMs
- Per-user cooldown: 5 seconds between requests
- Conversation history capped at 20 messages per user (ephemeral, not
persisted across restarts)
- Responses truncated to 400 characters; multi-line replies use paste overflow
- Default model: `openrouter/auto` (auto-routes to best available free model)
- Reasoning models (DeepSeek R1) are handled transparently -- falls back to
the `reasoning` field when `content` is empty
- Rate limit errors (HTTP 429) produce a clear user-facing message
Configuration:
```toml
[openrouter]
api_key = "" # or set OPENROUTER_API_KEY env var
model = "openrouter/auto" # default model
system_prompt = "You are a helpful IRC bot assistant. Keep responses concise and under 200 words."
```
API key: set `OPENROUTER_API_KEY` env var (preferred) or `api_key` under
`[openrouter]` in config. The env var takes precedence.
### `!alert` -- Keyword Alert Subscriptions
Search keywords across 27 platforms and announce new results. Unlike