diff --git a/Dockerfile b/Dockerfile index 8b3583142..a4a904fe0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -30,12 +30,13 @@ COPY docker_overlay/neon.conf /root/.config/neon/neon.conf RUN pip install wheel && \ pip install . -CMD ["neon_skills_service"] +CMD ["neon", "run-skills", "-i", "/skills"] FROM base as default_skills RUN mkdir -p /root/.local/share/neon -COPY docker_overlay/skill_settings /root/.config/neon/skills +# TODO: This path should move to config in the future +COPY docker_overlay/skill_settings /root/.local/share/neon/skills COPY docker_overlay/ngi_local_conf.yml /config/ RUN neon-install-default-skills RUN rm /config/ngi_local_conf.yml \ No newline at end of file diff --git a/neon_core/cli.py b/neon_core/cli.py new file mode 100644 index 000000000..669bf9168 --- /dev/null +++ b/neon_core/cli.py @@ -0,0 +1,108 @@ +# 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. +from threading import Thread + +import click + +from click_default_group import DefaultGroup +from neon_utils.packaging_utils import get_neon_core_version + + +@click.group("neon", cls=DefaultGroup, + no_args_is_help=True, invoke_without_command=True, + help="Neon Core Commands\n\n" + "See also: neon COMMAND --help") +@click.option("--version", "-v", is_flag=True, required=False, + help="Print the current version") +def neon_core_cli(version: bool = False): + if version: + click.echo(f"Neon version {get_neon_core_version()}") + + +@neon_core_cli.command(help="Start Neon Core") +def start_neon(): + from neon_core.run_neon import start_neon + click.echo("Starting Neon") + Thread(target=start_neon, daemon=False).start() + click.echo("Neon Started") + + +@neon_core_cli.command(help="Stop Neon Core") +def stop_neon(): + from neon_core.run_neon import stop_neon + click.echo("Stopping Neon") + stop_neon() + click.echo("Neon Stopped") + + +@neon_core_cli.command(help="Send Diagnostics") +@click.option("--no-transcripts", is_flag=True, default=False, + help="Skip upload of transcript files") +@click.option("--no-logs", is_flag=True, default=False, + help="Skip upload of log files") +@click.option("--no-config", is_flag=True, default=False, + help="Skip upload of configuration files") +def upload_diagnostics(no_transcripts, no_logs, no_config): + from neon_core.util.diagnostic_utils import send_diagnostics + click.echo("Uploading Diagnostics") + send_diagnostics(not no_logs, not no_transcripts, not no_config) + click.echo("Diagnostic Upload Complete") + + +@neon_core_cli.command(help="Install Default Skills") +def install_default_skills(): + from neon_core.util.skill_utils import install_skills_default + click.echo("Installing Default Skills") + install_skills_default() + click.echo("Default Skills Installed") + + +@neon_core_cli.command(help= + "Install skill requirements for a specified directory") +@click.argument("skill_dir") +def install_skill_requirements(skill_dir): + from neon_core.util.skill_utils import install_local_skills + try: + installed = install_local_skills(skill_dir) + click.echo(f"Installed {len(installed)} skills from {skill_dir}") + except ValueError as e: + click.echo(e) + + +@neon_core_cli.command(help="Start Neon Skills module") +@click.option("--install-skills", "-i", default=None, + help="Path to local skills for which to install dependencies") +def run_skills(install_skills): + from neon_core.util.skill_utils import install_local_skills + from neon_core.skills.__main__ import main + if install_skills: + click.echo(f"Handling installation of skills in: {install_skills}") + install_local_skills(install_skills) + click.echo("Starting Skills Service") + main() + click.echo("Skills Service Shutdown") diff --git a/neon_core/util/diagnostic_utils.py b/neon_core/util/diagnostic_utils.py index 396e2a936..f5fb50b14 100644 --- a/neon_core/util/diagnostic_utils.py +++ b/neon_core/util/diagnostic_utils.py @@ -104,6 +104,7 @@ def cli_send_diags(): """ CLI Entry Point to Send Diagnostics """ + LOG.warning(f"This function is deprecated. Use `neon upload-diagnostics`") import argparse parser = argparse.ArgumentParser(description="Upload Neon Diagnostics Files", add_help=True) parser.add_argument("--no-transcripts", dest="transcripts", default=True, action='store_false', diff --git a/neon_core/util/skill_utils.py b/neon_core/util/skill_utils.py index 70a92a620..1fe72e1fe 100644 --- a/neon_core/util/skill_utils.py +++ b/neon_core/util/skill_utils.py @@ -159,6 +159,7 @@ def install_local_skills(local_skills_dir: str = "/skills") -> list: :param local_skills_dir: Directory to install skills from :returns: list of installed skill directories """ + github_token = get_neon_skills_config()["neon_token"] local_skills_dir = expanduser(local_skills_dir) if not isdir(local_skills_dir): raise ValueError(f"{local_skills_dir} is not a valid directory") @@ -168,7 +169,8 @@ def install_local_skills(local_skills_dir: str = "/skills") -> list: pass LOG.debug(f"Attempting installation of {skill}") try: - entry = SkillEntry.from_directory(join(local_skills_dir, skill)) + entry = SkillEntry.from_directory(join(local_skills_dir, skill), + github_token) _install_skill_dependencies(entry) installed_skills.append(skill) except Exception as e: diff --git a/requirements/client.txt b/requirements/client.txt index cc8535c06..958ef7054 100644 --- a/requirements/client.txt +++ b/requirements/client.txt @@ -2,5 +2,5 @@ neon-transcripts-controller @ git+https://github.com/NeonGeckoCom/transcripts_co # wake word plugins chatterbox-wake-word-plugin-dummy~=0.1 -ovos-ww-plugin-pocketsphinx~=0.1 +ovos-ww-plugin-pocketsphinx~=0.1,>=0.1.1 ovos-ww-plugin-precise~=0.1 diff --git a/requirements/requirements.txt b/requirements/requirements.txt index 99472c588..1806ab5b2 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -2,7 +2,7 @@ ovos-core[skills_lgpl]~=0.0.2a10 # utils -neon-utils~=0.12,>=0.15.1a10 +neon-utils~=0.12,>=0.15.1a11 ovos_utils~=0.0.19,>=0.0.19a3 ovos-skills-manager~=0.0.10a20 ovos-plugin-manager~=0.0.4,>=0.0.7a0 diff --git a/setup.py b/setup.py index 60f2e5999..06af6b32d 100644 --- a/setup.py +++ b/setup.py @@ -88,6 +88,7 @@ def get_requirements(requirements_filename: str): include_package_data=True, entry_points={ 'console_scripts': [ + 'neon=neon_core.cli:neon_core_cli', 'neon_skills_service=neon_core.skills.__main__:main', 'neon-install-default-skills=neon_core.util.skill_utils:install_skills_default', 'neon-upload-diagnostics=neon_core.util.diagnostic_utils:cli_send_diags',