diff --git a/README.md b/README.md index 1e8ad0d7..6da0ca4c 100644 --- a/README.md +++ b/README.md @@ -82,14 +82,15 @@ usage: oobabot [-h] [-c CONFIG] [--generate-config] [--invite-url] [--ai-name AI [--stable-diffusion-url STABLE_DIFFUSION_URL] [--extra-prompt-text EXTRA_PROMPT_TEXT] -oobabot v0.2.1: Discord bot for oobabooga's text-generation-webui +oobabot v0.2.2: Discord bot for oobabooga's text-generation-webui General Settings: -h, --help -c CONFIG, --config CONFIG - Path to a config file to read settings from. Command line settings - will override settings in this file. (default: config.yml) + Path to a config file to read settings from. Command line + settings will override settings in this file. (default: + config.yml) --generate-config If set, oobabot will print its configuration as a .yml file, then exit. Any command-line settings also passed will be reflected in this file. (default: False) @@ -99,26 +100,27 @@ General Settings: Persona: --ai-name AI_NAME Name the AI will use to refer to itself (default: oobabot) - --persona PERSONA This prefix will be added in front of every user-supplied request. - This is useful for setting up a 'character' for the bot to play. - Alternatively, this can be set with the OOBABOT_PERSONA environment - variable. (default: ) + --persona PERSONA This prefix will be added in front of every user-supplied + request. This is useful for setting up a 'character' for the bot + to play. Alternatively, this can be set with the OOBABOT_PERSONA + environment variable. (default: ) --wakewords [WAKEWORDS ...] - One or more words that the bot will listen for. The bot will listen - in all discord channels it can access for one of these words to be - mentioned, then reply to any messages it sees with a matching word. - The bot will always reply to @-mentions and direct messages, even - if no wakewords are supplied. (default: ['oobabot']) + One or more words that the bot will listen for. The bot will + listen in all discord channels it can access for one of these + words to be mentioned, then reply to any messages it sees with a + matching word. The bot will always reply to @-mentions and direct + messages, even if no wakewords are supplied. (default: + ['oobabot']) Discord: --discord-token DISCORD_TOKEN - Token to log into Discord with. For security purposes it's strongly - recommended that you set this via the DISCORD_TOKEN environment - variable instead, if possible. (default: None) + Token to log into Discord with. For security purposes it's + strongly recommended that you set this via the DISCORD_TOKEN + environment variable instead, if possible. (default: ) --dont-split-responses - Post the entire response as a single message, rather than splitting - it into separate messages by sentence. (default: False) + Post the entire response as a single message, rather than + splitting it into separate messages by sentence. (default: False) --history-lines HISTORY_LINES Number of lines of chat history the AI will see when generating a response. (default: 7) @@ -126,15 +128,15 @@ Discord: False) --reply-in-thread If set, the bot will generate a thread to respond in if it is not already in one. (default: False) - --stream-responses FEATURE PREVIEW: Stream responses into a single message as they are - generated. Note: may be janky (default: False) + --stream-responses FEATURE PREVIEW: Stream responses into a single message as they + are generated. Note: may be janky (default: False) Oobabooga: --base-url BASE_URL Base URL for the oobabooga instance. This should be ws://hostname[:port] for plain websocket connections, or - wss://hostname[:port] for websocket connections over TLS. (default: - ws://localhost:5005) + wss://hostname[:port] for websocket connections over TLS. + (default: ws://localhost:5005) --log-all-the-things Print all AI input and output to STDOUT. (default: False) --message-regex MESSAGE_REGEX A regex that will be used to extract message lines from the AI's @@ -145,9 +147,9 @@ Oobabooga: Stable Diffusion: --image-words [IMAGE_WORDS ...] - When one of these words is used in a message, the bot will generate - an image. (default: ['draw me', 'drawing', 'photo', 'pic', - 'picture', 'image', 'sketch']) + When one of these words is used in a message, the bot will + generate an image. (default: ['draw me', 'drawing', 'photo', + 'pic', 'picture', 'image', 'sketch']) --stable-diffusion-url STABLE_DIFFUSION_URL URL for an AUTOMATIC1111 Stable Diffusion server. (default: ) --extra-prompt-text EXTRA_PROMPT_TEXT diff --git a/docs/RELEASE-0.2.2.md b/docs/RELEASE-0.2.2.md new file mode 100644 index 00000000..d0743ada --- /dev/null +++ b/docs/RELEASE-0.2.2.md @@ -0,0 +1,5 @@ + +# Release v.0.2.2 + +Version 0.2.2 only involved an update to oobabot-plugin, not +oobabot. The next update for oobabot is [v0.2.3](RELEASE-0.2.3.md). diff --git a/docs/RELEASE-0.2.3.md b/docs/RELEASE-0.2.3.md new file mode 100644 index 00000000..beac1a46 --- /dev/null +++ b/docs/RELEASE-0.2.3.md @@ -0,0 +1,59 @@ + +# Release v.0.2.3 + +Note: version 0.2.2 only updated oobabot-plugin, not oobabot. This +shows changes to oobabot since the prior release, [v0.2.1](RELEASE-0.2.1.md). + +## What's Changed + +Mainly a bugfix update for 0.2.1, with a few fixes and configuration +parameters. + +## New Features + +* Option to disable unsolicited replies entirely + +Unsolicited replies are still enabled by default, but you can now disable them entirely by changing this setting in your config.yml: + +```yaml + # If set, the bot will not reply to any messages that do not @-mention it or include a + # wakeword. If unsolicited replies are disabled, the unsolicited_channel_cap setting will + # have no effect. + # default: False + disable_unsolicited_replies: true +``` + +The objective of this change is to support cases where +unsolicited replies are not desired, such as when the bot is used in a +channel with a high volume of messages. + +## Bug Fixes / Tech Improvements + +* Unicode logging reliability fix ooba_client.py + + Unicode bugs in oobabooga seem to be a moving target, so +this fix gates the fix applied in 0.2.1 to only be applied +in cases where oobabooga is known to be broken. + +* Security fix: Bump aiohttp from 3.8.4 to 3.8.5 + + Update dependency aiohttp to v3.8.5. This fixes [a security +issue in aiohttp](https://github.com/aio-libs/aiohttp/blob/v3.8.5/CHANGES.rst). On a quick scan it doesn't seem to be something +a user could exploit within oobabot, but better to update anyway. + +* Preserve newlines when prompting the bot + + In some cases the whitespace in user messages is important. One case is +described in the [issue 76, reported by @xydreen](https://github.com/aio-libs/aiohttp/security/advisories/GHSA-45c4-8wx5-qw6w). + + When sending a prompt to the bot, we will now preserve any newlines +that the bot itself had generated in the past. + + We will still strip newlines from messages from user-generated messages, +as otherwise they would have the ability to imitate our prompt format. +This would let users so inclined to fool the bot into thinking a +message was sent by another user, or even itself. + +### Full Changelog + +[All changes from 0.2.1 to 0.2.3](https://github.com/chrisrude/oobabot/compare/v0.2.1...v0.2.3) diff --git a/docs/config.sample.yml b/docs/config.sample.yml index f793dcb4..62abf4eb 100644 --- a/docs/config.sample.yml +++ b/docs/config.sample.yml @@ -6,7 +6,7 @@ # "config.yml" from the current directory when it is run. # -version: 0.2.1 +version: 0.2.3 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # persona diff --git a/poetry.lock b/poetry.lock index dea26338..dd7d3247 100644 --- a/poetry.lock +++ b/poetry.lock @@ -313,13 +313,13 @@ files = [ [[package]] name = "click" -version = "8.1.6" +version = "8.1.7" description = "Composable command line interface toolkit" optional = false python-versions = ">=3.7" files = [ - {file = "click-8.1.6-py3-none-any.whl", hash = "sha256:fa244bb30b3b5ee2cae3da8f55c9e5e0c0e86093306301fb418eb9dc40fbded5"}, - {file = "click-8.1.6.tar.gz", hash = "sha256:48ee849951919527a045bfe3bf7baa8a959c423134e1a5b98c05c20ba75a1cbd"}, + {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, + {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, ] [package.dependencies] @@ -397,18 +397,21 @@ test = ["pytest (>=6)"] [[package]] name = "filelock" -version = "3.12.2" +version = "3.12.3" description = "A platform independent file lock." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "filelock-3.12.2-py3-none-any.whl", hash = "sha256:cbb791cdea2a72f23da6ac5b5269ab0a0d161e9ef0100e653b69049a7706d1ec"}, - {file = "filelock-3.12.2.tar.gz", hash = "sha256:002740518d8aa59a26b0c76e10fb8c6e15eae825d34b6fdf670333fd7b938d81"}, + {file = "filelock-3.12.3-py3-none-any.whl", hash = "sha256:f067e40ccc40f2b48395a80fcbd4728262fab54e232e090a4063ab804179efeb"}, + {file = "filelock-3.12.3.tar.gz", hash = "sha256:0ecc1dd2ec4672a10c8550a8182f1bd0c0a5088470ecd5a125e45f49472fac3d"}, ] +[package.dependencies] +typing-extensions = {version = ">=4.7.1", markers = "python_version < \"3.11\""} + [package.extras] -docs = ["furo (>=2023.5.20)", "sphinx (>=7.0.1)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)"] -testing = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "diff-cover (>=7.5)", "pytest (>=7.3.1)", "pytest-cov (>=4.1)", "pytest-mock (>=3.10)", "pytest-timeout (>=2.1)"] +docs = ["furo (>=2023.7.26)", "sphinx (>=7.1.2)", "sphinx-autodoc-typehints (>=1.24)"] +testing = ["covdefaults (>=2.3)", "coverage (>=7.3)", "diff-cover (>=7.7)", "pytest (>=7.4)", "pytest-cov (>=4.1)", "pytest-mock (>=3.11.1)", "pytest-timeout (>=2.1)"] [[package]] name = "flake8" @@ -498,13 +501,13 @@ files = [ [[package]] name = "identify" -version = "2.5.26" +version = "2.5.27" description = "File identification library for Python" optional = false python-versions = ">=3.8" files = [ - {file = "identify-2.5.26-py2.py3-none-any.whl", hash = "sha256:c22a8ead0d4ca11f1edd6c9418c3220669b3b7533ada0a0ffa6cc0ef85cf9b54"}, - {file = "identify-2.5.26.tar.gz", hash = "sha256:7243800bce2f58404ed41b7c002e53d4d22bcf3ae1b7900c2d7aefd95394bf7f"}, + {file = "identify-2.5.27-py2.py3-none-any.whl", hash = "sha256:fdb527b2dfe24602809b2201e033c2a113d7bdf716db3ca8e3243f735dcecaba"}, + {file = "identify-2.5.27.tar.gz", hash = "sha256:287b75b04a0e22d727bc9a41f0d4f3c1bcada97490fa6eabb5b28f0e9097e733"}, ] [package.extras] @@ -752,13 +755,13 @@ test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4)", "pytest-co [[package]] name = "pluggy" -version = "1.2.0" +version = "1.3.0" description = "plugin and hook calling mechanisms for python" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "pluggy-1.2.0-py3-none-any.whl", hash = "sha256:c2fd55a7d7a3863cba1a013e4e2414658b1d07b6bc57b3919e0c63c9abb99849"}, - {file = "pluggy-1.2.0.tar.gz", hash = "sha256:d12f0c4b579b15f5e054301bb226ee85eeeba08ffec228092f8defbaa3a4c4b3"}, + {file = "pluggy-1.3.0-py3-none-any.whl", hash = "sha256:d89c696a773f8bd377d18e5ecda92b7a3793cbe66c87060a6fb58c7b6e1061f7"}, + {file = "pluggy-1.3.0.tar.gz", hash = "sha256:cf61ae8f126ac6f7c451172cf30e3e43d3ca77615509771b3a984a0730651e12"}, ] [package.extras] @@ -836,13 +839,13 @@ testutils = ["gitpython (>3)"] [[package]] name = "pyright" -version = "1.1.322" +version = "1.1.325" description = "Command line wrapper for pyright" optional = false python-versions = ">=3.7" files = [ - {file = "pyright-1.1.322-py3-none-any.whl", hash = "sha256:1bcddb55c4fca5d3c86eee71db0e8aad80536527f2084284998c6cbceda10e4e"}, - {file = "pyright-1.1.322.tar.gz", hash = "sha256:c8299d8b5d8c6e6f6ea48a77bf330a6df79e23305d21d25043bba8a23c1e1ed8"}, + {file = "pyright-1.1.325-py3-none-any.whl", hash = "sha256:8f3ab88ba4843f053ab5b5c886d676161aba6f446776bfb57cc0434ed4d88672"}, + {file = "pyright-1.1.325.tar.gz", hash = "sha256:879a3f66944ffd59d3facd54872fed814830fed64daf3e8eb71b146ddd83bb67"}, ] [package.dependencies] @@ -999,17 +1002,17 @@ files = [ [[package]] name = "setuptools" -version = "68.1.0" +version = "68.1.2" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "setuptools-68.1.0-py3-none-any.whl", hash = "sha256:e13e1b0bc760e9b0127eda042845999b2f913e12437046e663b833aa96d89715"}, - {file = "setuptools-68.1.0.tar.gz", hash = "sha256:d59c97e7b774979a5ccb96388efc9eb65518004537e85d52e81eaee89ab6dd91"}, + {file = "setuptools-68.1.2-py3-none-any.whl", hash = "sha256:3d8083eed2d13afc9426f227b24fd1659489ec107c0e86cec2ffdde5c92e790b"}, + {file = "setuptools-68.1.2.tar.gz", hash = "sha256:3d4dfa6d95f1b101d695a6160a7626e15583af71a5f52176efa5d39a054d475d"}, ] [package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (==0.8.3)", "sphinx-reredirects", "sphinxcontrib-towncrier"] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5,<=7.1.2)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (==0.8.3)", "sphinx-reredirects", "sphinxcontrib-towncrier"] testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] @@ -1048,13 +1051,13 @@ files = [ [[package]] name = "virtualenv" -version = "20.24.3" +version = "20.24.4" description = "Virtual Python Environment builder" optional = false python-versions = ">=3.7" files = [ - {file = "virtualenv-20.24.3-py3-none-any.whl", hash = "sha256:95a6e9398b4967fbcb5fef2acec5efaf9aa4972049d9ae41f95e0972a683fd02"}, - {file = "virtualenv-20.24.3.tar.gz", hash = "sha256:e5c3b4ce817b0b328af041506a2a299418c98747c4b1e68cb7527e74ced23efc"}, + {file = "virtualenv-20.24.4-py3-none-any.whl", hash = "sha256:29c70bb9b88510f6414ac3e55c8b413a1f96239b6b789ca123437d5e892190cb"}, + {file = "virtualenv-20.24.4.tar.gz", hash = "sha256:772b05bfda7ed3b8ecd16021ca9716273ad9f4467c801f27e83ac73430246dca"}, ] [package.dependencies] @@ -1063,7 +1066,7 @@ filelock = ">=3.12.2,<4" platformdirs = ">=3.9.1,<4" [package.extras] -docs = ["furo (>=2023.5.20)", "proselint (>=0.13)", "sphinx (>=7.0.1)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"] +docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.2)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"] test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8)", "pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=68)", "time-machine (>=2.10)"] [[package]] @@ -1240,4 +1243,4 @@ multidict = ">=4.0" [metadata] lock-version = "2.0" python-versions = "^3.8.1" -content-hash = "849f092c50a1c41734bbcdbdec0b17cb86e2540f0ece9446e1259239a7ad2a66" +content-hash = "d28b7f9f1646639d1a5c690d69814baf92d6874ffc5939285ab59bb97b618eb4" diff --git a/pyproject.toml b/pyproject.toml index 0f750437..1c0f94c7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "oobabot" -version = "0.2.1" +version = "0.2.3" description = "A Discord bot which talks to Large Language Model AIs running on oobabooga's text-generation-webui" authors = ["Christopher Rude "] license = "MIT" @@ -34,7 +34,7 @@ black = "^23.3.0" flake8 = "^6.0.0" isort = "^5.12.0" pre-commit = "^3.2.0" -pyright = "^1.1.316" +pyright = "^1.1.325" pytest = "^7.1" pylint = "^2.17.4" diff --git a/src/oobabot/__init__.py b/src/oobabot/__init__.py index a4085637..c927d110 100644 --- a/src/oobabot/__init__.py +++ b/src/oobabot/__init__.py @@ -4,4 +4,4 @@ """ # todo: sync this up automatically -__version__ = "0.2.1" +__version__ = "0.2.3" diff --git a/src/oobabot/fancy_logger.py b/src/oobabot/fancy_logger.py index 7c55b3e0..29c81788 100644 --- a/src/oobabot/fancy_logger.py +++ b/src/oobabot/fancy_logger.py @@ -323,8 +323,7 @@ def get_all(self) -> typing.List[str]: # return wrapper -def excepthook(*exc_info): - exc_type = exc_info[0] +def excepthook(exc_type, exc_value, exc_traceback): if issubclass(exc_type, (KeyboardInterrupt, SystemExit)): - sys.__excepthook__(*exc_info) - get().error("Unhandled exception", exc_info=exc_info) + sys.__excepthook__(exc_type, exc_value, exc_traceback) + get().error("Unhandled exception", exc_info=(exc_type, exc_value, exc_traceback))