agentirc 1.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- agentirc-1.0.0/.dockerignore +10 -0
- agentirc-1.0.0/.env.example +40 -0
- agentirc-1.0.0/.github/workflows/dockerhub.yml +49 -0
- agentirc-1.0.0/.github/workflows/pypi-publish.yml +31 -0
- agentirc-1.0.0/.gitignore +5 -0
- agentirc-1.0.0/Dockerfile +11 -0
- agentirc-1.0.0/LICENSE +21 -0
- agentirc-1.0.0/PKG-INFO +115 -0
- agentirc-1.0.0/README.md +94 -0
- agentirc-1.0.0/agentirc/__init__.py +9 -0
- agentirc-1.0.0/agentirc/__main__.py +97 -0
- agentirc-1.0.0/agentirc/api.py +369 -0
- agentirc-1.0.0/agentirc/bot.py +437 -0
- agentirc-1.0.0/agentirc/config.py +114 -0
- agentirc-1.0.0/agentirc/history.py +202 -0
- agentirc-1.0.0/agentirc/models.py +156 -0
- agentirc-1.0.0/agentirc/tools.py +81 -0
- agentirc-1.0.0/docker-compose.yml +10 -0
- agentirc-1.0.0/docs/ai-agent.md +94 -0
- agentirc-1.0.0/docs/ai-output-disclaimer.md +87 -0
- agentirc-1.0.0/docs/commands.md +145 -0
- agentirc-1.0.0/docs/configuration.md +61 -0
- agentirc-1.0.0/docs/docker.md +95 -0
- agentirc-1.0.0/docs/extending.md +155 -0
- agentirc-1.0.0/docs/not-a-companion.md +28 -0
- agentirc-1.0.0/ircbot/__init__.py +15 -0
- agentirc-1.0.0/ircbot/__main__.py +41 -0
- agentirc-1.0.0/ircbot/bot.py +279 -0
- agentirc-1.0.0/ircbot/commands.py +52 -0
- agentirc-1.0.0/ircbot/config.py +64 -0
- agentirc-1.0.0/ircbot/connection.py +133 -0
- agentirc-1.0.0/ircbot/protocol.py +109 -0
- agentirc-1.0.0/pyproject.toml +36 -0
- agentirc-1.0.0/tests/__init__.py +0 -0
- agentirc-1.0.0/tests/conftest.py +46 -0
- agentirc-1.0.0/tests/test_agentirc_api.py +191 -0
- agentirc-1.0.0/tests/test_agentirc_commands.py +107 -0
- agentirc-1.0.0/tests/test_agentirc_models_tools.py +90 -0
- agentirc-1.0.0/tests/test_bot.py +429 -0
- agentirc-1.0.0/tests/test_commands.py +209 -0
- agentirc-1.0.0/tests/test_config.py +182 -0
- agentirc-1.0.0/tests/test_connection.py +449 -0
- agentirc-1.0.0/tests/test_country_and_store.py +168 -0
- agentirc-1.0.0/tests/test_history_location.py +81 -0
- agentirc-1.0.0/tests/test_history_persistence.py +77 -0
- agentirc-1.0.0/tests/test_protocol.py +203 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
IRC_HOST=irc.rizon.net
|
|
2
|
+
IRC_PORT=6667
|
|
3
|
+
IRC_NICK=mybot
|
|
4
|
+
IRC_USER=mybot
|
|
5
|
+
IRC_REALNAME=My IRC Bot
|
|
6
|
+
IRC_CHANNELS=#general,#bots
|
|
7
|
+
IRC_PASSWORD=
|
|
8
|
+
IRC_USE_TLS=false
|
|
9
|
+
IRC_CMD_PREFIX=!
|
|
10
|
+
|
|
11
|
+
# AI agent provider settings (used by: python -m agentirc)
|
|
12
|
+
OPENAI_API_BASE=https://api.openai.com
|
|
13
|
+
OPENAI_API_KEY=
|
|
14
|
+
OPENAI_MODELS=
|
|
15
|
+
|
|
16
|
+
XAI_API_BASE=https://api.x.ai/v1
|
|
17
|
+
XAI_API_KEY=
|
|
18
|
+
XAI_MODELS=
|
|
19
|
+
|
|
20
|
+
LMSTUDIO_BASE_URL=http://127.0.0.1:1234/v1
|
|
21
|
+
LMSTUDIO_API_KEY=
|
|
22
|
+
LMSTUDIO_MODELS=
|
|
23
|
+
|
|
24
|
+
DEFAULT_MODEL=gpt-5-mini
|
|
25
|
+
AGENTIRC_TOOLS=web_search,x_search,code_interpreter,mcp
|
|
26
|
+
AGENTIRC_MCP_SERVERS=[]
|
|
27
|
+
AGENTIRC_ADMINS=
|
|
28
|
+
AGENTIRC_SERVER_MODELS=true
|
|
29
|
+
AGENTIRC_DEFAULT_PERSONALITY="a helpful agentic chatbot named agentirc."
|
|
30
|
+
AGENTIRC_PROMPT_PREFIX="You are "
|
|
31
|
+
AGENTIRC_PROMPT_SUFFIX=". Roleplay and never break character. Do not use markdown or lists in your responses, this is a text-only environment."
|
|
32
|
+
AGENTIRC_PROMPT_SUFFIX_EXTRA=" Keep responses concise, around 400 characters. Do not output a character count."
|
|
33
|
+
AGENTIRC_MAX_TOKENS=1024
|
|
34
|
+
|
|
35
|
+
# Search country bias for web_search tool (ISO 3166-1 alpha-2 code, e.g. US)
|
|
36
|
+
WEB_SEARCH_COUNTRY=
|
|
37
|
+
|
|
38
|
+
# Fernet encryption key for persisting conversation history across restarts.
|
|
39
|
+
# Generate one with: python -m agentirc --generate-key
|
|
40
|
+
HISTORY_ENCRYPTION_KEY=
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
name: Publish to Docker Hub
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
tags:
|
|
8
|
+
- "v*"
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
build-and-push:
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
steps:
|
|
14
|
+
- name: Checkout
|
|
15
|
+
uses: actions/checkout@v4
|
|
16
|
+
|
|
17
|
+
- name: Set up QEMU
|
|
18
|
+
uses: docker/setup-qemu-action@v3
|
|
19
|
+
|
|
20
|
+
- name: Set up Docker Buildx
|
|
21
|
+
uses: docker/setup-buildx-action@v3
|
|
22
|
+
|
|
23
|
+
- name: Log in to Docker Hub
|
|
24
|
+
uses: docker/login-action@v3
|
|
25
|
+
with:
|
|
26
|
+
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
|
27
|
+
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
|
28
|
+
|
|
29
|
+
- name: Extract metadata
|
|
30
|
+
id: meta
|
|
31
|
+
uses: docker/metadata-action@v5
|
|
32
|
+
with:
|
|
33
|
+
images: h1ddenpr0cess20/agentirc
|
|
34
|
+
tags: |
|
|
35
|
+
type=ref,event=branch
|
|
36
|
+
type=semver,pattern={{version}}
|
|
37
|
+
type=semver,pattern={{major}}.{{minor}}
|
|
38
|
+
type=raw,value=latest,enable={{is_default_branch}}
|
|
39
|
+
|
|
40
|
+
- name: Build and push
|
|
41
|
+
uses: docker/build-push-action@v6
|
|
42
|
+
with:
|
|
43
|
+
context: .
|
|
44
|
+
platforms: linux/amd64,linux/arm64
|
|
45
|
+
push: true
|
|
46
|
+
tags: ${{ steps.meta.outputs.tags }}
|
|
47
|
+
labels: ${{ steps.meta.outputs.labels }}
|
|
48
|
+
cache-from: type=gha
|
|
49
|
+
cache-to: type=gha,mode=max
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
id-token: write
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
publish:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
environment: pypi
|
|
15
|
+
steps:
|
|
16
|
+
- name: Checkout
|
|
17
|
+
uses: actions/checkout@v4
|
|
18
|
+
|
|
19
|
+
- name: Set up Python
|
|
20
|
+
uses: actions/setup-python@v5
|
|
21
|
+
with:
|
|
22
|
+
python-version: "3.11"
|
|
23
|
+
|
|
24
|
+
- name: Install build tools
|
|
25
|
+
run: pip install build
|
|
26
|
+
|
|
27
|
+
- name: Build package
|
|
28
|
+
run: python -m build
|
|
29
|
+
|
|
30
|
+
- name: Publish to PyPI
|
|
31
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
agentirc-1.0.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Dustin Whyte
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
agentirc-1.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: agentirc
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: AI-powered IRC agent with multi-provider LLM support
|
|
5
|
+
Project-URL: Homepage, https://github.com/h1ddenpr0cess20/agentirc
|
|
6
|
+
Project-URL: Repository, https://github.com/h1ddenpr0cess20/agentirc
|
|
7
|
+
Project-URL: Issues, https://github.com/h1ddenpr0cess20/agentirc/issues
|
|
8
|
+
License-Expression: MIT
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Keywords: agent,ai,bot,chatbot,irc,llm,ollama,openai
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Topic :: Communications :: Chat
|
|
15
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
16
|
+
Requires-Python: >=3.10
|
|
17
|
+
Requires-Dist: httpx>=0.27
|
|
18
|
+
Provides-Extra: crypto
|
|
19
|
+
Requires-Dist: cryptography>=43; extra == 'crypto'
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
|
|
22
|
+
# agentirc
|
|
23
|
+
|
|
24
|
+
An AI-powered IRC agent built on a minimal async IRC bot framework. Supports multiple LLM providers (OpenAI, xAI, LM Studio) with per-user conversation history, tool use, and encrypted persistence.
|
|
25
|
+
|
|
26
|
+
## Table of Contents
|
|
27
|
+
|
|
28
|
+
- [Quick Start](#quick-start)
|
|
29
|
+
- [CLI Options](#cli-options)
|
|
30
|
+
- [Commands](#commands)
|
|
31
|
+
- [Documentation](#documentation)
|
|
32
|
+
- [License](#license)
|
|
33
|
+
|
|
34
|
+
## Quick Start
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
git clone <repo-url>
|
|
38
|
+
cd agentirc
|
|
39
|
+
cp .env.example .env
|
|
40
|
+
# Edit .env with your IRC server, nick, and at least one API provider
|
|
41
|
+
pip install .
|
|
42
|
+
agentirc
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Or with Docker:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
cp .env.example .env
|
|
49
|
+
# Edit .env
|
|
50
|
+
docker compose up -d
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
> **Requirements:** Python 3.10+, `httpx`, and optionally `cryptography` for encrypted history persistence.
|
|
54
|
+
|
|
55
|
+
## CLI Options
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
agentirc [options]
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
| Flag | Description |
|
|
62
|
+
|---|---|
|
|
63
|
+
| `--env-file PATH` | Path to .env file (default: `.env`) |
|
|
64
|
+
| `--debug` | Enable debug logging |
|
|
65
|
+
| `--host HOST` | IRC server hostname (overrides `IRC_HOST`) |
|
|
66
|
+
| `--port PORT` | IRC server port (overrides `IRC_PORT`) |
|
|
67
|
+
| `--nick NICK` | Bot nickname (overrides `IRC_NICK`) |
|
|
68
|
+
| `--channels CHANS` | Comma-separated channels (overrides `IRC_CHANNELS`) |
|
|
69
|
+
| `--tls` | Connect with TLS (overrides `IRC_USE_TLS`) |
|
|
70
|
+
| `--model MODEL` | Default model (overrides `DEFAULT_MODEL`) |
|
|
71
|
+
| `--generate-key` | Generate a Fernet encryption key and exit |
|
|
72
|
+
|
|
73
|
+
CLI flags override their corresponding environment variables.
|
|
74
|
+
|
|
75
|
+
## Commands
|
|
76
|
+
|
|
77
|
+
### User Commands
|
|
78
|
+
|
|
79
|
+
| Command | Aliases | Description |
|
|
80
|
+
|---|---|---|
|
|
81
|
+
| `!ai <message>` | `!chat`, `!ask` | Talk to the AI |
|
|
82
|
+
| `!persona <text>` | | Set a persona and reintroduce |
|
|
83
|
+
| `!custom <prompt>` | | Set a custom system prompt |
|
|
84
|
+
| `!reset` | | Reset conversation to defaults |
|
|
85
|
+
| `!stock` | | Reset conversation with no system prompt |
|
|
86
|
+
| `!mymodel [name]` | | Show or set your model |
|
|
87
|
+
| `!location <place>` | | Set your location for contextual answers |
|
|
88
|
+
| `!x <nick> <message>` | | Talk as another user |
|
|
89
|
+
|
|
90
|
+
### Admin Commands
|
|
91
|
+
|
|
92
|
+
| Command | Description |
|
|
93
|
+
|---|---|
|
|
94
|
+
| `!model [name\|reset]` | Show/set global default model |
|
|
95
|
+
| `!tools [on\|off\|toggle\|status]` | Enable/disable tool use |
|
|
96
|
+
| `!verbose [on\|off\|toggle]` | Toggle verbose mode |
|
|
97
|
+
| `!clear` | Clear all conversation state |
|
|
98
|
+
| `!country [on\|off\|status]` | Toggle search country filtering |
|
|
99
|
+
| `!join <#channel>` | Join a channel |
|
|
100
|
+
| `!part [#channel] [reason]` | Leave a channel |
|
|
101
|
+
|
|
102
|
+
Built-in IRC commands (`!ping`, `!time`, `!help`) are also available.
|
|
103
|
+
|
|
104
|
+
## Documentation
|
|
105
|
+
|
|
106
|
+
- [docs/configuration.md](docs/configuration.md) -- IRC and AI provider configuration
|
|
107
|
+
- [docs/commands.md](docs/commands.md) -- command registry and decorator API
|
|
108
|
+
- [docs/extending.md](docs/extending.md) -- subclassing IRCBot, event hooks
|
|
109
|
+
- [docs/ai-agent.md](docs/ai-agent.md) -- AI agent architecture, providers, tools, and history
|
|
110
|
+
- [docs/ai-output-disclaimer.md](docs/ai-output-disclaimer.md) -- AI output disclaimer and conditions of use
|
|
111
|
+
- [docs/not-a-companion.md](docs/not-a-companion.md) -- project scope and intended use
|
|
112
|
+
|
|
113
|
+
## License
|
|
114
|
+
|
|
115
|
+
MIT
|
agentirc-1.0.0/README.md
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# agentirc
|
|
2
|
+
|
|
3
|
+
An AI-powered IRC agent built on a minimal async IRC bot framework. Supports multiple LLM providers (OpenAI, xAI, LM Studio) with per-user conversation history, tool use, and encrypted persistence.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
- [Quick Start](#quick-start)
|
|
8
|
+
- [CLI Options](#cli-options)
|
|
9
|
+
- [Commands](#commands)
|
|
10
|
+
- [Documentation](#documentation)
|
|
11
|
+
- [License](#license)
|
|
12
|
+
|
|
13
|
+
## Quick Start
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
git clone <repo-url>
|
|
17
|
+
cd agentirc
|
|
18
|
+
cp .env.example .env
|
|
19
|
+
# Edit .env with your IRC server, nick, and at least one API provider
|
|
20
|
+
pip install .
|
|
21
|
+
agentirc
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Or with Docker:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
cp .env.example .env
|
|
28
|
+
# Edit .env
|
|
29
|
+
docker compose up -d
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
> **Requirements:** Python 3.10+, `httpx`, and optionally `cryptography` for encrypted history persistence.
|
|
33
|
+
|
|
34
|
+
## CLI Options
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
agentirc [options]
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
| Flag | Description |
|
|
41
|
+
|---|---|
|
|
42
|
+
| `--env-file PATH` | Path to .env file (default: `.env`) |
|
|
43
|
+
| `--debug` | Enable debug logging |
|
|
44
|
+
| `--host HOST` | IRC server hostname (overrides `IRC_HOST`) |
|
|
45
|
+
| `--port PORT` | IRC server port (overrides `IRC_PORT`) |
|
|
46
|
+
| `--nick NICK` | Bot nickname (overrides `IRC_NICK`) |
|
|
47
|
+
| `--channels CHANS` | Comma-separated channels (overrides `IRC_CHANNELS`) |
|
|
48
|
+
| `--tls` | Connect with TLS (overrides `IRC_USE_TLS`) |
|
|
49
|
+
| `--model MODEL` | Default model (overrides `DEFAULT_MODEL`) |
|
|
50
|
+
| `--generate-key` | Generate a Fernet encryption key and exit |
|
|
51
|
+
|
|
52
|
+
CLI flags override their corresponding environment variables.
|
|
53
|
+
|
|
54
|
+
## Commands
|
|
55
|
+
|
|
56
|
+
### User Commands
|
|
57
|
+
|
|
58
|
+
| Command | Aliases | Description |
|
|
59
|
+
|---|---|---|
|
|
60
|
+
| `!ai <message>` | `!chat`, `!ask` | Talk to the AI |
|
|
61
|
+
| `!persona <text>` | | Set a persona and reintroduce |
|
|
62
|
+
| `!custom <prompt>` | | Set a custom system prompt |
|
|
63
|
+
| `!reset` | | Reset conversation to defaults |
|
|
64
|
+
| `!stock` | | Reset conversation with no system prompt |
|
|
65
|
+
| `!mymodel [name]` | | Show or set your model |
|
|
66
|
+
| `!location <place>` | | Set your location for contextual answers |
|
|
67
|
+
| `!x <nick> <message>` | | Talk as another user |
|
|
68
|
+
|
|
69
|
+
### Admin Commands
|
|
70
|
+
|
|
71
|
+
| Command | Description |
|
|
72
|
+
|---|---|
|
|
73
|
+
| `!model [name\|reset]` | Show/set global default model |
|
|
74
|
+
| `!tools [on\|off\|toggle\|status]` | Enable/disable tool use |
|
|
75
|
+
| `!verbose [on\|off\|toggle]` | Toggle verbose mode |
|
|
76
|
+
| `!clear` | Clear all conversation state |
|
|
77
|
+
| `!country [on\|off\|status]` | Toggle search country filtering |
|
|
78
|
+
| `!join <#channel>` | Join a channel |
|
|
79
|
+
| `!part [#channel] [reason]` | Leave a channel |
|
|
80
|
+
|
|
81
|
+
Built-in IRC commands (`!ping`, `!time`, `!help`) are also available.
|
|
82
|
+
|
|
83
|
+
## Documentation
|
|
84
|
+
|
|
85
|
+
- [docs/configuration.md](docs/configuration.md) -- IRC and AI provider configuration
|
|
86
|
+
- [docs/commands.md](docs/commands.md) -- command registry and decorator API
|
|
87
|
+
- [docs/extending.md](docs/extending.md) -- subclassing IRCBot, event hooks
|
|
88
|
+
- [docs/ai-agent.md](docs/ai-agent.md) -- AI agent architecture, providers, tools, and history
|
|
89
|
+
- [docs/ai-output-disclaimer.md](docs/ai-output-disclaimer.md) -- AI output disclaimer and conditions of use
|
|
90
|
+
- [docs/not-a-companion.md](docs/not-a-companion.md) -- project scope and intended use
|
|
91
|
+
|
|
92
|
+
## License
|
|
93
|
+
|
|
94
|
+
MIT
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"""Entry point: python -m agentirc"""
|
|
2
|
+
|
|
3
|
+
import argparse
|
|
4
|
+
import asyncio
|
|
5
|
+
import logging
|
|
6
|
+
import os
|
|
7
|
+
|
|
8
|
+
from .config import ChatConfig
|
|
9
|
+
from .bot import ChatBot
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def main() -> None:
|
|
13
|
+
parser = argparse.ArgumentParser(description="AI-powered IRC agent")
|
|
14
|
+
parser.add_argument(
|
|
15
|
+
"--generate-key",
|
|
16
|
+
action="store_true",
|
|
17
|
+
help="Generate a Fernet encryption key for history persistence and exit",
|
|
18
|
+
)
|
|
19
|
+
parser.add_argument(
|
|
20
|
+
"--env-file",
|
|
21
|
+
metavar="PATH",
|
|
22
|
+
default=".env",
|
|
23
|
+
help="Path to .env file (default: .env)",
|
|
24
|
+
)
|
|
25
|
+
parser.add_argument(
|
|
26
|
+
"--debug",
|
|
27
|
+
action="store_true",
|
|
28
|
+
help="Enable debug logging",
|
|
29
|
+
)
|
|
30
|
+
parser.add_argument(
|
|
31
|
+
"--host",
|
|
32
|
+
metavar="HOST",
|
|
33
|
+
help="IRC server hostname (overrides IRC_HOST)",
|
|
34
|
+
)
|
|
35
|
+
parser.add_argument(
|
|
36
|
+
"--port",
|
|
37
|
+
type=int,
|
|
38
|
+
metavar="PORT",
|
|
39
|
+
help="IRC server port (overrides IRC_PORT)",
|
|
40
|
+
)
|
|
41
|
+
parser.add_argument(
|
|
42
|
+
"--nick",
|
|
43
|
+
metavar="NICK",
|
|
44
|
+
help="Bot nickname (overrides IRC_NICK)",
|
|
45
|
+
)
|
|
46
|
+
parser.add_argument(
|
|
47
|
+
"--channels",
|
|
48
|
+
metavar="CHANS",
|
|
49
|
+
help="Comma-separated channels to join (overrides IRC_CHANNELS)",
|
|
50
|
+
)
|
|
51
|
+
parser.add_argument(
|
|
52
|
+
"--tls",
|
|
53
|
+
action="store_true",
|
|
54
|
+
default=None,
|
|
55
|
+
help="Connect with TLS (overrides IRC_USE_TLS)",
|
|
56
|
+
)
|
|
57
|
+
parser.add_argument(
|
|
58
|
+
"--model",
|
|
59
|
+
metavar="MODEL",
|
|
60
|
+
help="Default model (overrides DEFAULT_MODEL)",
|
|
61
|
+
)
|
|
62
|
+
args = parser.parse_args()
|
|
63
|
+
|
|
64
|
+
if args.generate_key:
|
|
65
|
+
from cryptography.fernet import Fernet
|
|
66
|
+
print(Fernet.generate_key().decode())
|
|
67
|
+
return
|
|
68
|
+
|
|
69
|
+
# Load .env first, then apply CLI overrides (which win via direct set)
|
|
70
|
+
from ircbot.config import load_env
|
|
71
|
+
load_env(args.env_file)
|
|
72
|
+
|
|
73
|
+
if args.host:
|
|
74
|
+
os.environ["IRC_HOST"] = args.host
|
|
75
|
+
if args.port is not None:
|
|
76
|
+
os.environ["IRC_PORT"] = str(args.port)
|
|
77
|
+
if args.nick:
|
|
78
|
+
os.environ["IRC_NICK"] = args.nick
|
|
79
|
+
if args.channels:
|
|
80
|
+
os.environ["IRC_CHANNELS"] = args.channels
|
|
81
|
+
if args.tls:
|
|
82
|
+
os.environ["IRC_USE_TLS"] = "true"
|
|
83
|
+
if args.model:
|
|
84
|
+
os.environ["DEFAULT_MODEL"] = args.model
|
|
85
|
+
|
|
86
|
+
logging.basicConfig(
|
|
87
|
+
level=logging.DEBUG if args.debug else logging.INFO,
|
|
88
|
+
format="%(asctime)s %(levelname)-8s %(name)s: %(message)s",
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
config = ChatConfig.from_env()
|
|
92
|
+
bot = ChatBot(config)
|
|
93
|
+
asyncio.run(bot.run())
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
if __name__ == "__main__":
|
|
97
|
+
main()
|