diff --git a/.github/workflows/publish_test_build.yml b/.github/workflows/publish_test_build.yml index f805d71..ceef5ae 100644 --- a/.github/workflows/publish_test_build.yml +++ b/.github/workflows/publish_test_build.yml @@ -9,9 +9,10 @@ on: - 'neon_minerva/version.py' jobs: - build_and_publish_pypi: + publish_alpha_release: uses: neongeckocom/.github/.github/workflows/publish_alpha_release.yml@master secrets: inherit with: version_file: "neon_minerva/version.py" setup_py: "setup.py" + publish_prerelease: true diff --git a/CHANGELOG.md b/CHANGELOG.md index d99e8d8..a032cc1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,16 +1,24 @@ # Changelog -## [0.0.1](https://github.com/NeonGeckoCom/neon-minerva/tree/0.0.1) (2023-10-26) +## [0.0.2a6](https://github.com/NeonGeckoCom/neon-minerva/tree/0.0.2a6) (2023-12-08) -[Full Changelog](https://github.com/NeonGeckoCom/neon-minerva/compare/1f81d6670a144b65069a882623ff3ef44ae93582...0.0.1) +[Full Changelog](https://github.com/NeonGeckoCom/neon-minerva/compare/0.0.2a5...0.0.2a6) **Merged pull requests:** -- Update GitHub release automation [\#7](https://github.com/NeonGeckoCom/neon-minerva/pull/7) ([NeonDaniel](https://github.com/NeonDaniel)) -- Update GitHub release automation [\#6](https://github.com/NeonGeckoCom/neon-minerva/pull/6) ([NeonDaniel](https://github.com/NeonDaniel)) -- Loosen padacioso dependency spec for neon-core compat. [\#4](https://github.com/NeonGeckoCom/neon-minerva/pull/4) ([NeonDaniel](https://github.com/NeonDaniel)) -- Add integration tests [\#3](https://github.com/NeonGeckoCom/neon-minerva/pull/3) ([NeonDaniel](https://github.com/NeonDaniel)) -- Initial implementation of portable skill tests [\#1](https://github.com/NeonGeckoCom/neon-minerva/pull/1) ([NeonDaniel](https://github.com/NeonDaniel)) +- Move packages with system dependencies to `padatious` extras [\#13](https://github.com/NeonGeckoCom/neon-minerva/pull/13) ([NeonDaniel](https://github.com/NeonDaniel)) + +## [0.0.2a5](https://github.com/NeonGeckoCom/neon-minerva/tree/0.0.2a5) (2023-12-08) + +[Full Changelog](https://github.com/NeonGeckoCom/neon-minerva/compare/0.0.1...0.0.2a5) + +**Merged pull requests:** + +- Update GHA to publish pre-releases [\#12](https://github.com/NeonGeckoCom/neon-minerva/pull/12) ([NeonDaniel](https://github.com/NeonDaniel)) +- Fix bug causing dialog tests to pass when translations are missing [\#11](https://github.com/NeonGeckoCom/neon-minerva/pull/11) ([NeonDaniel](https://github.com/NeonDaniel)) +- Add support for CBF Submind tests [\#10](https://github.com/NeonGeckoCom/neon-minerva/pull/10) ([NeonDaniel](https://github.com/NeonDaniel)) +- Add compat. reference for `bus.emitter` [\#9](https://github.com/NeonGeckoCom/neon-minerva/pull/9) ([NeonDaniel](https://github.com/NeonDaniel)) +- Skill Test Class [\#5](https://github.com/NeonGeckoCom/neon-minerva/pull/5) ([NeonDaniel](https://github.com/NeonDaniel)) diff --git a/README.md b/README.md index 297b728..74278cc 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ The `minerva` entrypoint is available to interact with a bus via CLI. Help is available via `minerva --help`. ## Installation -Since skill intents may use Padatious, the following system packages must be +If testing Padatious intents, the following system packages must be installed before installing this package: ```shell sudo apt install swig libfann-dev @@ -17,6 +17,11 @@ To install this package from PyPI, simply run: pip install neon-minerva ``` +If testing with Padatious, install with the `padatious` extras: +```shell +pip install neon-minerva[padatious] +``` + ## Usage This package provides a CLI for local testing of skills. Skills installed with `pip` can be specified by entrypoint, or skills cloned locally can be specified @@ -36,3 +41,54 @@ To test that skill intents match as expected for all supported languages, the skill's root directory > - is a relative or absolute path to the resource test file, usually `test_intents.yaml` > - The `--padacioso` flag can be added to test with Padacioso instead of Padatious for relevant intents + +## Advanced Usage +In addition to convenient CLI methods, this package also provides test cases that +may be extended. + +### Skill Unit Tests +`neon_minerva.tests.skill_unit_test_base` provides `SkillTestCase`, a class +that supplies boilerplate setup/teardown/mocking for testing a skill. An example +skill test implementation could look like: + +```python +from os import environ +from neon_minerva.tests.skill_unit_test_base import SkillTestCase + +environ['TEST_SKILL_ENTRYPOINT'] = "my_skill.test" + +class MySkillTest(SkillTestCase): + def test_skill_init(self): + self.assertEqual(self.skill.skill_id, "my_skill.test") + ... +``` + +Be sure to review the base class for mocked methods and test paths as these may +change in the future. + +### Chatbot Unit Tests +`neon_minerva.chatbots` contains mocked data for testing as well as some utility +methods. `neon_minerva.tests.chatbot_v1_test_base` provides `TestSubmind` which +may be extended to test a submind bot in a mocked v1 environment. For example: + +```python +from os import environ +from datetime import datetime +from chatbot_core.utils.enum import ConversationState + +from neon_minerva.tests.chatbot_v1_test_base import TestSubmind +from neon_minerva.chatbots.test_constants import PROMPT, RESPONSES + +environ["TEST_BOT_ENTRYPOINT"] = "tester" + + +class TestTester(TestSubmind): + def test_submind_chatbot(self): + self.submind.state = ConversationState.RESP + response = self.submind.ask_chatbot("testrunner", PROMPT, + datetime.now().strftime( + "%I:%M:%S %p")) + self.assertIsInstance(response, str) + self.assertIsNotNone(response) +``` +> Make sure to install the `chatbots` extra to use this test case diff --git a/neon_minerva/chatbots/__init__.py b/neon_minerva/chatbots/__init__.py new file mode 100644 index 0000000..158a323 --- /dev/null +++ b/neon_minerva/chatbots/__init__.py @@ -0,0 +1,18 @@ +# NEON AI (TM) SOFTWARE, Software Development Kit & Application Development System +# +# Copyright 2008-2023 Neongecko.com Inc. | All Rights Reserved +# +# Notice of License - Duplicating this Notice of License near the start of any file containing +# a derivative of this software is a condition of license for this software. +# Friendly Licensing: +# No charge, open source royalty free use of the Neon AI software source and object is offered for +# educational users, noncommercial enthusiasts, Public Benefit Corporations (and LLCs) and +# Social Purpose Corporations (and LLCs). Developers can contact developers@neon.ai +# For commercial licensing, distribution of derivative works or redistribution please contact licenses@neon.ai +# Distributed on an "AS IS” basis without warranties or conditions of any kind, either express or implied. +# Trademarks of Neongecko: Neon AI(TM), Neon Assist (TM), Neon Communicator(TM), Klat(TM) +# Authors: Guy Daniels, Daniel McKnight, Regina Bloomstine, Elon Gasper, Richard Leeds +# +# Specialized conversational reconveyance options from Conversation Processing Intelligence Corp. +# US Patents 2008-2023: US7424516, US20140161250, US20140177813, US8638908, US8068604, US8553852, US10530923, US10530924 +# China Patent: CN102017585 - Europe Patent: EU2156652 - Patents Pending diff --git a/neon_minerva/chatbots/test_constants.py b/neon_minerva/chatbots/test_constants.py new file mode 100644 index 0000000..073b046 --- /dev/null +++ b/neon_minerva/chatbots/test_constants.py @@ -0,0 +1,74 @@ +# NEON AI (TM) SOFTWARE, Software Development Kit & Application Development System +# +# Copyright 2008-2023 Neongecko.com Inc. | All Rights Reserved +# +# Notice of License - Duplicating this Notice of License near the start of any file containing +# a derivative of this software is a condition of license for this software. +# Friendly Licensing: +# No charge, open source royalty free use of the Neon AI software source and object is offered for +# educational users, noncommercial enthusiasts, Public Benefit Corporations (and LLCs) and +# Social Purpose Corporations (and LLCs). Developers can contact developers@neon.ai +# For commercial licensing, distribution of derivative works or redistribution please contact licenses@neon.ai +# Distributed on an "AS IS” basis without warranties or conditions of any kind, either express or implied. +# Trademarks of Neongecko: Neon AI(TM), Neon Assist (TM), Neon Communicator(TM), Klat(TM) +# Authors: Guy Daniels, Daniel McKnight, Regina Bloomstine, Elon Gasper, Richard Leeds +# +# Specialized conversational reconveyance options from Conversation Processing Intelligence Corp. +# US Patents 2008-2023: US7424516, US20140161250, US20140177813, US8638908, US8068604, US8553852, US10530923, US10530924 +# China Patent: CN102017585 - Europe Patent: EU2156652 - Patents Pending + +PROMPT = "hello!" + +RESPONSES = {"Ned": "Hi, I'm Ned. How are you, testrunner?", + "Eliza": "Hello... I'm glad you could drop by today.", + "terry": "Hey", + "Ima": "I am ready to talk", + "wolfram": "Hello, human", + "kbot": "hello!", + "alice": "Hi there!", + "abstain": ""} + +VOTES_BY_USER = { + '1prompt1': { + 'bot1': [], + 'bot2': ['bot1'], + 'bot3': [], + 'bot4': [], + 'abstain': ['bot2', 'bot3', 'bot4'] + }, + '2prompt2': { + 'bot1': [], + 'bot2': [], + 'bot4': [], + 'abstain': ['bot1', 'bot2', 'bot4'] + }, + '3prompt3': { + 'bot1': [], + 'bot2': ['bot1'], + 'bot3': [], + 'bot4': [], + 'abstain': ['bot2', 'bot3', 'bot4'] + } +} + +SELECTIONS = { + 'bot1': [('prompt1', 'bot2'), ('prompt2', 'abstain'), ('prompt3', 'bot2')], + 'bot2': [('prompt1', 'abstain'), ('prompt2', 'abstain'), ('prompt3', 'abstain')], + 'bot3': [('prompt1', 'abstain'), ('prompt3', 'abstain')], + 'bot4': [('prompt1', 'abstain'), ('prompt2', 'abstain'), ('prompt3', 'abstain')] +} + +SELECTION_HISTORY = ['bot2', 'bot2', 'bot2'] + +PARTICIPANT_HISTORY = [(), # element 0 is expected to be an empty tuple + ('bot1', 'bot2', 'bot3', 'bot4'), + ('bot1', 'bot2', 'bot3', 'bot4')] + +# ContextKeeper constants +RECENT_USERS = [f"user{number}" for number in range(20)] +RECENT_SHOUTS = [ + "Who is the president of Ukraine?", + "Who is the president of the US?", + "What is the distance between them?", + "When was he born?" +] diff --git a/neon_minerva/chatbots/util.py b/neon_minerva/chatbots/util.py new file mode 100644 index 0000000..6104de6 --- /dev/null +++ b/neon_minerva/chatbots/util.py @@ -0,0 +1,31 @@ +# NEON AI (TM) SOFTWARE, Software Development Kit & Application Development System +# +# Copyright 2008-2023 Neongecko.com Inc. | All Rights Reserved +# +# Notice of License - Duplicating this Notice of License near the start of any file containing +# a derivative of this software is a condition of license for this software. +# Friendly Licensing: +# No charge, open source royalty free use of the Neon AI software source and object is offered for +# educational users, noncommercial enthusiasts, Public Benefit Corporations (and LLCs) and +# Social Purpose Corporations (and LLCs). Developers can contact developers@neon.ai +# For commercial licensing, distribution of derivative works or redistribution please contact licenses@neon.ai +# Distributed on an "AS IS” basis without warranties or conditions of any kind, either express or implied. +# Trademarks of Neongecko: Neon AI(TM), Neon Assist (TM), Neon Communicator(TM), Klat(TM) +# Authors: Guy Daniels, Daniel McKnight, Regina Bloomstine, Elon Gasper, Richard Leeds +# +# Specialized conversational reconveyance options from Conversation Processing Intelligence Corp. +# US Patents 2008-2023: US7424516, US20140161250, US20140177813, US8638908, US8068604, US8553852, US10530923, US10530924 +# China Patent: CN102017585 - Europe Patent: EU2156652 - Patents Pending +import pkg_resources + + +def load_chatbot(name: str): + try: + from importlib_metadata import entry_points + bot_entrypoints = entry_points(group="neon.plugin.chatbot") + except ImportError: + bot_entrypoints = pkg_resources.iter_entry_points("neon.plugin.chatbot") + + for bot in bot_entrypoints: + if bot.name == name: + return bot.load() diff --git a/neon_minerva/intent_services/padatious.py b/neon_minerva/intent_services/padatious.py index 62f85a4..b4e8931 100644 --- a/neon_minerva/intent_services/padatious.py +++ b/neon_minerva/intent_services/padatious.py @@ -26,7 +26,6 @@ # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -from padatious import IntentContainer from ovos_utils.log import LOG from ovos_utils.messagebus import FakeBus @@ -36,6 +35,7 @@ class PadatiousContainer: def __init__(self, lang: str, cache_path: str, bus: FakeBus): + from padatious import IntentContainer self.cache_dir = cache_path self.lang = lang.lower() self.bus = bus diff --git a/neon_minerva/skill.py b/neon_minerva/skill.py index 6106e66..57e2d4d 100644 --- a/neon_minerva/skill.py +++ b/neon_minerva/skill.py @@ -40,11 +40,14 @@ def get_skill_object(skill_entrypoint: str, bus: FakeBus, @param skill_entrypoint: Skill plugin entrypoint or directory path @param bus: FakeBus instance to bind to skill for testing @param skill_id: skill_id to initialize skill with + @param config_patch: Configuration update to apply @returns: Initialized skill object """ if config_patch: - from ovos_config.config import update_mycroft_config - update_mycroft_config(config_patch) + from ovos_config.config import update_mycroft_config, Configuration + user_config = update_mycroft_config(config_patch) + if user_config not in Configuration.xdg_configs: + Configuration.xdg_configs.append(user_config) if isdir(skill_entrypoint): LOG.info(f"Loading local skill: {skill_entrypoint}") from ovos_workshop.skill_launcher import SkillLoader diff --git a/neon_minerva/tests/chatbot_v1_test_base.py b/neon_minerva/tests/chatbot_v1_test_base.py new file mode 100644 index 0000000..a7a8bcf --- /dev/null +++ b/neon_minerva/tests/chatbot_v1_test_base.py @@ -0,0 +1,50 @@ +# NEON AI (TM) SOFTWARE, Software Development Kit & Application Development System +# +# Copyright 2008-2023 Neongecko.com Inc. | All Rights Reserved +# +# Notice of License - Duplicating this Notice of License near the start of any file containing +# a derivative of this software is a condition of license for this software. +# Friendly Licensing: +# No charge, open source royalty free use of the Neon AI software source and object is offered for +# educational users, noncommercial enthusiasts, Public Benefit Corporations (and LLCs) and +# Social Purpose Corporations (and LLCs). Developers can contact developers@neon.ai +# For commercial licensing, distribution of derivative works or redistribution please contact licenses@neon.ai +# Distributed on an "AS IS” basis without warranties or conditions of any kind, either express or implied. +# Trademarks of Neongecko: Neon AI(TM), Neon Assist (TM), Neon Communicator(TM), Klat(TM) +# Authors: Guy Daniels, Daniel McKnight, Regina Bloomstine, Elon Gasper, Richard Leeds +# +# Specialized conversational reconveyance options from Conversation Processing Intelligence Corp. +# US Patents 2008-2023: US7424516, US20140161250, US20140177813, US8638908, US8068604, US8553852, US10530923, US10530924 +# China Patent: CN102017585 - Europe Patent: EU2156652 - Patents Pending + + +import unittest + +from os import getenv +from time import sleep +from chatbot_core.utils import clean_up_bot +from klat_connector import start_socket +from klat_connector.mach_server import MachKlatServer +from neon_minerva.chatbots.util import load_chatbot + + +class TestSubmind(unittest.TestCase): + # Initialize a server for testing + server = MachKlatServer() + sleep(1) + socket = start_socket("0.0.0.0") + submind = None + + @classmethod + def setUpClass(cls) -> None: + # Determine submind to test + submind_entrypoint = getenv("TEST_BOT_ENTRYPOINT") + bot_class = load_chatbot(submind_entrypoint) + # Initialize a submind instance + cls.submind = bot_class(cls.socket, "Private", "testrunner", + "testpassword", on_server=False) + + @classmethod + def tearDownClass(cls) -> None: + clean_up_bot(cls.submind) + cls.server.shutdown_server() diff --git a/neon_minerva/tests/skill_unit_test_base.py b/neon_minerva/tests/skill_unit_test_base.py new file mode 100644 index 0000000..0732b16 --- /dev/null +++ b/neon_minerva/tests/skill_unit_test_base.py @@ -0,0 +1,80 @@ +# NEON AI (TM) SOFTWARE, Software Development Kit & Application Framework +# All trademark and other rights reserved by their respective owners +# Copyright 2008-2022 Neongecko.com Inc. +# Contributors: Daniel McKnight, Guy Daniels, Elon Gasper, Richard Leeds, +# Regina Bloomstine, Casimiro Ferreira, Andrii Pernatii, Kirill Hrymailo +# BSD-3 License +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# 3. Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived from this +# software without specific prior written permission. +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +# OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import unittest +import shutil + +from os import environ, getenv +from os.path import dirname, join +from unittest.mock import Mock +from ovos_utils.messagebus import FakeBus + +from neon_minerva.skill import get_skill_object + + +class SkillTestCase(unittest.TestCase): + # Define test directories + test_fs = join(dirname(__file__), "skill_fs") + data_dir = join(test_fs, "data") + conf_dir = join(test_fs, "config") + environ["XDG_DATA_HOME"] = data_dir + environ["XDG_CONFIG_HOME"] = conf_dir + + # Define static parameters + bus = FakeBus() + # Patching FakeBus compat. with MessageBusClient + bus.emitter = bus.ee + + bus.run_forever() + test_skill_id = 'test_skill.test' + + skill = None + + @classmethod + def setUpClass(cls) -> None: + # Get test skill + skill_entrypoint = getenv("TEST_SKILL_ENTRYPOINT") + if not skill_entrypoint: + from ovos_plugin_manager.skills import find_skill_plugins + skill_entrypoints = list(find_skill_plugins().keys()) + assert len(skill_entrypoints) == 1 + skill_entrypoint = skill_entrypoints[0] + + cls.skill = get_skill_object(skill_entrypoint=skill_entrypoint, + skill_id=cls.test_skill_id, bus=cls.bus) + # Override speak and speak_dialog to test passed arguments + cls.skill.speak = Mock() + cls.skill.speak_dialog = Mock() + + def setUp(self): + self.skill.speak.reset_mock() + self.skill.speak_dialog.reset_mock() + + @classmethod + def tearDownClass(cls) -> None: + shutil.rmtree(cls.test_fs) diff --git a/neon_minerva/tests/test_skill_intents.py b/neon_minerva/tests/test_skill_intents.py index 71c1a89..0a36513 100644 --- a/neon_minerva/tests/test_skill_intents.py +++ b/neon_minerva/tests/test_skill_intents.py @@ -62,7 +62,18 @@ class TestSkillIntentMatching(unittest.TestCase): if getenv("TEST_PADACIOSO") == "true": container = PadaciosoContainer else: - container = PadatiousContainer + try: + from padatious import IntentContainer + container = PadatiousContainer + except ImportError as e: + LOG.error(f"Padatious not installed. Install " + f"neon-minerva[padatious] to get Padatious requirements") + if getenv("TEST_PADACIOSO") is None: + # Ambiguous request, just use Padacioso + container = PadaciosoContainer + else: + # Explicitly requested Padatious/non-Padacioso + raise e padatious_services = dict() adapt_services = dict() for lang in languages: diff --git a/neon_minerva/tests/test_skill_resources.py b/neon_minerva/tests/test_skill_resources.py index afa4a0a..0dedf76 100644 --- a/neon_minerva/tests/test_skill_resources.py +++ b/neon_minerva/tests/test_skill_resources.py @@ -27,7 +27,6 @@ # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import unittest -import os import json from os import getenv @@ -84,7 +83,8 @@ def test_skill_setup(self): self.assertEqual(self.skill.skill_id, self.test_skill_id) self.assertEqual(set([self.skill._core_lang] + self.skill._secondary_langs), - set(self.supported_languages)) + set(self.supported_languages), + f"expected={self.supported_languages}") def test_intent_registration(self): registered_adapt = list() @@ -137,8 +137,9 @@ def test_intent_registration(self): def test_dialog_files(self): for lang in self.supported_languages: + dialogs = self.skill._lang_resources[lang].dialog_renderer.templates for dialog in self.dialog: - file = self.skill.find_resource(f"{dialog}.dialog", "dialog", - lang) - self.assertIsInstance(file, str, f"{dialog} in {self.dialog}") - self.assertTrue(os.path.isfile(file), dialog) + self.assertIn(dialog, dialogs.keys(), + f"lang={lang}") + + # TODO: Consider adding tests for resource file existence diff --git a/neon_minerva/version.py b/neon_minerva/version.py index ef7228e..4488dcb 100644 --- a/neon_minerva/version.py +++ b/neon_minerva/version.py @@ -26,4 +26,4 @@ # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -__version__ = "0.0.1" +__version__ = "0.1.0" diff --git a/requirements/chatbots.txt b/requirements/chatbots.txt new file mode 100644 index 0000000..0724fe8 --- /dev/null +++ b/requirements/chatbots.txt @@ -0,0 +1,2 @@ +klat-connector +neon-chatbot-core \ No newline at end of file diff --git a/requirements/padatious.txt b/requirements/padatious.txt new file mode 100644 index 0000000..d81499d --- /dev/null +++ b/requirements/padatious.txt @@ -0,0 +1,2 @@ +padatious~=0.4.8 +fann2==1.0.7 diff --git a/requirements/requirements.txt b/requirements/requirements.txt index 55f1e1d..b517944 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -2,7 +2,6 @@ click~=8.0 click-default-group~=1.2 ovos-utils~=0.0.35 ovos-workshop~=0.0.12 -fann2==1.0.7 -padatious~=0.4.8 padacioso~=0.1 -pyyaml~=6.0 \ No newline at end of file +pyyaml>=5.4,<7.0 +# PyYaml 5.4 support left for ovos-core 0.0.7 compat \ No newline at end of file diff --git a/setup.py b/setup.py index 52304e5..3f80cbb 100644 --- a/setup.py +++ b/setup.py @@ -74,6 +74,8 @@ def get_requirements(requirements_filename: str): ], python_requires='>=3.6', install_requires=get_requirements("requirements.txt"), + extras_require={"chatbots": get_requirements("chatbots.txt"), + "padatious": get_requirements("padatious.txt")}, entry_points={ 'console_scripts': ['minerva=neon_minerva.cli:neon_minerva_cli'] }