Skip to content

Commit

Permalink
Change events.reply(_error) with message: str to reply: AIReply
Browse files Browse the repository at this point in the history
  • Loading branch information
yorevs committed Sep 7, 2024
1 parent 88cc997 commit ebbd1bb
Show file tree
Hide file tree
Showing 25 changed files with 192 additions and 174 deletions.
4 changes: 2 additions & 2 deletions src/demo/components/vision_demo.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import os

from askai.core.features.router.tools.vision import offline_captioner

import os

if __name__ == "__main__":
# init_context("vision-demo")
# vision: AIVision = shared.engine.vision()
Expand Down
13 changes: 6 additions & 7 deletions src/main/askai/__classpath__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,17 @@
Copyright (c) 2024, HomeSetup
"""
from askai.core.model.api_keys import ApiKeys
from clitt.core.term.commons import is_a_tty
from hspylib.core.metaclass.classpath import Classpath
from hspylib.core.tools.commons import is_debugging, parent_path, root_dir

import logging as log
import os
import pydantic
import sys
import warnings

import pydantic
from clitt.core.term.commons import is_a_tty
from hspylib.core.metaclass.classpath import Classpath
from hspylib.core.tools.commons import parent_path, root_dir, is_debugging

from askai.core.model.api_keys import ApiKeys

if not is_debugging():
warnings.simplefilter("ignore", category=FutureWarning)
warnings.simplefilter("ignore", category=UserWarning)
Expand Down
23 changes: 11 additions & 12 deletions src/main/askai/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@
Copyright (c) 2024, HomeSetup
"""
import logging as log
import os
import sys
from textwrap import dedent
from typing import Any, Optional

from askai.__classpath__ import classpath
from askai.core.askai import AskAi
from askai.core.askai_cli import AskAiCli
from askai.core.askai_configs import configs
from askai.core.support.shared_instances import shared
from askai.tui.askai_app import AskAiApp
from clitt.core.tui.tui_application import TUIApplication
from hspylib.core.enums.charset import Charset
from hspylib.core.tools.commons import to_bool
Expand All @@ -26,13 +26,12 @@
from hspylib.modules.application.argparse.parser_action import ParserAction
from hspylib.modules.application.exit_status import ExitStatus
from hspylib.modules.application.version import Version
from textwrap import dedent
from typing import Any, Optional

from askai.__classpath__ import classpath
from askai.core.askai import AskAi
from askai.core.askai_cli import AskAiCli
from askai.core.askai_configs import configs
from askai.core.support.shared_instances import shared
from askai.tui.askai_app import AskAiApp
import logging as log
import os
import sys


class Main(TUIApplication):
Expand Down
25 changes: 13 additions & 12 deletions src/main/askai/core/askai.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
from askai.core.engine.ai_engine import AIEngine
from askai.core.enums.router_mode import RouterMode
from askai.core.features.router.ai_processor import AIProcessor
from askai.core.model.ai_reply import AIReply
from askai.core.support.chat_context import ChatContext
from askai.core.support.shared_instances import shared
from askai.core.support.utilities import read_stdin
Expand All @@ -37,7 +38,7 @@
from hspylib.modules.eventbus.event import Event
from openai import RateLimitError
from pathlib import Path
from typing import List, Optional, TypeAlias
from typing import AnyStr, List, Optional, TypeAlias

import logging as log
import os
Expand Down Expand Up @@ -155,24 +156,24 @@ def ask_and_reply(self, question: str) -> tuple[bool, Optional[str]]:
ask_commander(args, standalone_mode=False)
elif not (output := cache.read_reply(question)):
log.debug('Response not found for "%s" in cache. Querying from %s.', question, self.engine.nickname())
events.reply.emit(message=msg.wait(), verbosity="debug")
events.reply.emit(reply=AIReply.debug(msg.wait()))
output = processor.process(question, context=read_stdin(), query_prompt=self._query_prompt)
events.reply.emit(message=(output or msg.no_output("processor")))
events.reply.emit(reply=AIReply.info(output or msg.no_output("processor")))
else:
log.debug("Reply found for '%s' in cache.", question)
events.reply.emit(message=output)
events.reply.emit(reply=AIReply.info(output))
shared.context.push("HISTORY", question)
shared.context.push("HISTORY", output, "assistant")
except (NotImplementedError, ImpossibleQuery) as err:
events.reply_error.emit(message=str(err))
events.reply.emit(reply=AIReply.error(err))
except (MaxInteractionsReached, InaccurateResponse) as err:
events.reply_error.emit(message=msg.unprocessable(str(err)))
events.reply.emit(reply=AIReply.error(msg.unprocessable(err)))
except UsageError as err:
events.reply_error.emit(message=msg.invalid_command(err))
events.reply.emit(reply=AIReply.error(msg.invalid_command(err)))
except IntelligibleAudioError as err:
events.reply_error.emit(message=msg.intelligible(err))
events.reply.emit(reply=AIReply.error(msg.intelligible(err)))
except RateLimitError:
events.reply_error.emit(message=msg.quote_exceeded())
events.reply.emit(reply=AIReply.error(msg.quote_exceeded()))
status = False
except TerminatingQuery:
status = False
Expand All @@ -195,13 +196,13 @@ def _create_console_file(self, overwrite: bool = True) -> None:
)
f_console.flush()

def _reply(self, message: str) -> None:
def _reply(self, message: AnyStr) -> None:
"""Reply to the user with the AI-generated response.
:param message: The message to send as a reply to the user.
"""
...

def _reply_error(self, message: str) -> None:
def _reply_error(self, message: AnyStr) -> None:
"""Reply to the user with an AI-generated error message or system error.
:param message: The error message to be displayed to the user.
"""
Expand All @@ -219,4 +220,4 @@ def _cb_mode_changed_event(self, ev: Event) -> None:
f"`{msg.press_esc_enter()}` \n\n"
f"> {msg.qna_welcome()}"
)
events.reply.emit(message=sum_msg)
events.reply.emit(reply=AIReply.info(sum_msg))
48 changes: 23 additions & 25 deletions src/main/askai/core/askai_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,6 @@
Copyright (c) 2024, HomeSetup
"""
import logging as log
import os
from functools import partial
from pathlib import Path
from threading import Thread
from typing import List, TypeAlias

import nltk
import pause
from clitt.core.term.cursor import cursor
from clitt.core.term.screen import screen
from clitt.core.tui.line_input.keyboard_input import KeyboardInput
from hspylib.modules.eventbus.event import Event
from rich.progress import Progress

from askai.core.askai import AskAi
from askai.core.askai_configs import configs
from askai.core.askai_events import *
Expand All @@ -36,9 +21,23 @@
from askai.core.component.cache_service import cache, CACHE_DIR
from askai.core.component.recorder import recorder
from askai.core.component.scheduler import scheduler
from askai.core.model.ai_reply import AIReply
from askai.core.support.shared_instances import shared
from askai.core.support.text_formatter import text_formatter
from askai.core.support.utilities import display_text
from clitt.core.term.cursor import cursor
from clitt.core.term.screen import screen
from clitt.core.tui.line_input.keyboard_input import KeyboardInput
from hspylib.modules.eventbus.event import Event
from pathlib import Path
from rich.progress import Progress
from threading import Thread
from typing import AnyStr, List, TypeAlias

import logging as log
import nltk
import os
import pause

QueryString: TypeAlias = str | List[str] | None

Expand Down Expand Up @@ -88,7 +87,7 @@ def run(self) -> None:
self._reply(msg.goodbye())
display_text("", markdown=False)

def _reply(self, message: str) -> None:
def _reply(self, message: AnyStr) -> None:
"""Reply to the user with the AI-generated response.
:param message: The message to send as a reply to the user.
"""
Expand All @@ -101,7 +100,7 @@ def _reply(self, message: str) -> None:
else:
display_text(text, f"{shared.nickname}")

def _reply_error(self, message: str) -> None:
def _reply_error(self, message: AnyStr) -> None:
"""Reply to the user with an AI-generated error message or system error.
:param message: The error message to be displayed to the user.
"""
Expand All @@ -118,19 +117,19 @@ def _input(self) -> Optional[str]:
"""
return shared.input_text(f"{shared.username}", f"Message {self.engine.nickname()}")

def _cb_reply_event(self, ev: Event, error: bool = False) -> None:
def _cb_reply_event(self, ev: Event) -> None:
"""Callback to handle reply events.
:param ev: The event object representing the reply event.
:param error: Indicates whether the reply is an error (default is False).
"""
if message := ev.args.message:
if error:
self._reply_error(message)
reply: AIReply
if reply := ev.args.reply:
if reply.is_error:
self._reply_error(str(reply))
else:
if ev.args.verbosity.casefold() == "normal" or configs.is_debug:
if ev.args.reply.verbosity <= 1 or configs.is_debug:
if ev.args.erase_last:
cursor.erase_line()
self._reply(message)
self._reply(str(reply))

def _cb_mic_listening_event(self, ev: Event) -> None:
"""Callback to handle microphone listening events.
Expand Down Expand Up @@ -171,7 +170,6 @@ def _startup(self) -> None:
# Start and manage the progress bar
askai_bus = AskAiEvents.bus(ASKAI_BUS_NAME)
askai_bus.subscribe(REPLY_EVENT, self._cb_reply_event)
askai_bus.subscribe(REPLY_ERROR_EVENT, partial(self._cb_reply_event, error=True))
if configs.is_interactive:
splash_thread: Thread = Thread(daemon=True, target=self._splash)
splash_thread.start()
Expand Down
5 changes: 1 addition & 4 deletions src/main/askai/core/askai_events.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@

REPLY_EVENT: str = "askai-reply-event"

REPLY_ERROR_EVENT: str = "askai-reply-error-event"

MIC_LISTENING_EVENT: str = "askai-mic-listening-event"

DEVICE_CHANGED_EVENT: str = "askai-input-device-changed-event"
Expand All @@ -37,8 +35,7 @@ class AskAiEvents(Enumeration):
# fmt: off
ASKAI_BUS = FluidEventBus(
ASKAI_BUS_NAME,
reply=FluidEvent(REPLY_EVENT, verbosity='normal', erase_last=False),
reply_error=FluidEvent(REPLY_ERROR_EVENT),
reply=FluidEvent(REPLY_EVENT, erase_last=False),
listening=FluidEvent(MIC_LISTENING_EVENT, listening=True),
device_changed=FluidEvent(DEVICE_CHANGED_EVENT, device=None),
mode_changed=FluidEvent(MODE_CHANGED_EVENT, mode=None, sum_path=None, glob=None),
Expand Down
25 changes: 13 additions & 12 deletions src/main/askai/core/askai_messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from askai.language.translators.deepl_translator import DeepLTranslator
from functools import cached_property, lru_cache
from hspylib.core.metaclass.singleton import Singleton
from typing import AnyStr

import re

Expand Down Expand Up @@ -50,15 +51,15 @@ def translator(self) -> AITranslator:
return AskAiMessages.get_translator(Language.EN_US, configs.language)

@lru_cache(maxsize=256)
def translate(self, text: str) -> str:
def translate(self, text: AnyStr) -> str:
"""Translate text using the configured language.
:param text: The text to be translated.
:return: The translated text.
"""
# Avoid translating debug messages.
if re.match(r"^~~\[DEBUG]~~.*", text, flags=re.IGNORECASE | re.MULTILINE):
if re.match(r"^~~\[DEBUG]~~.*", str(text), flags=re.IGNORECASE | re.MULTILINE):
return text
return self.translator.translate(text)
return self.translator.translate(str(text))

# Informational

Expand Down Expand Up @@ -179,10 +180,10 @@ def access_grant(self) -> str:
def no_query_string(self) -> str:
return "No query string was provided in non-interactive mode !"

def invalid_response(self, response_text: str) -> str:
def invalid_response(self, response_text: AnyStr) -> str:
return f"Invalid query response/type => '{response_text}' !"

def invalid_command(self, response_text: str) -> str:
def invalid_command(self, response_text: AnyStr) -> str:
return f"Invalid **AskAI** command => '{response_text}' !"

def cmd_no_exist(self, command: str) -> str:
Expand All @@ -200,25 +201,25 @@ def missing_package(self, err: ImportError) -> str:
def summary_not_possible(self, err: BaseException = None) -> str:
return f"Summarization was not possible {'=> ' + str(err) if err else ''}!"

def intelligible(self, reason: str) -> str:
def intelligible(self, reason: AnyStr) -> str:
return f"Your speech was not intelligible => '{reason}' !"

def impossible(self, reason: str) -> str:
def impossible(self, reason: AnyStr) -> str:
return f"Impossible to fulfill your request => `{reason}` !"

def timeout(self, reason: str) -> str:
def timeout(self, reason: AnyStr) -> str:
return f"Time out while {reason} !"

def llm_error(self, error: str) -> str:
def llm_error(self, error: AnyStr) -> str:
return f"**LLM** failed to reply: {error} !"

def fail_to_search(self, error: str) -> str:
def fail_to_search(self, error: AnyStr) -> str:
return f"'Internet Search' failed: {error} !"

def too_many_actions(self) -> str:
def too_many_actions(self) -> AnyStr:
return "Failed to complete the request => 'Max chained actions reached' !"

def unprocessable(self, reason: str) -> str:
def unprocessable(self, reason: AnyStr) -> str:
return f"Sorry, {reason}"

def quote_exceeded(self) -> str:
Expand Down
4 changes: 1 addition & 3 deletions src/main/askai/core/commander/commander.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
Copyright (c) 2024, HomeSetup
"""
from askai.core.askai_configs import configs
from askai.core.askai_events import ASKAI_BUS_NAME, AskAiEvents, REPLY_ERROR_EVENT, REPLY_EVENT
from askai.core.askai_events import ASKAI_BUS_NAME, AskAiEvents, REPLY_EVENT
from askai.core.commander.commands.cache_cmd import CacheCmd
from askai.core.commander.commands.camera_cmd import CameraCmd
from askai.core.commander.commands.general_cmd import GeneralCmd
Expand All @@ -26,7 +26,6 @@
from askai.language.language import AnyLocale, Language
from click import Command, Group
from clitt.core.term.cursor import cursor
from functools import partial
from hspylib.core.enums.charset import Charset
from hspylib.core.tools.commons import sysout, to_bool
from hspylib.modules.eventbus.event import Event
Expand Down Expand Up @@ -154,7 +153,6 @@ def _reply_event(ev: Event, error: bool = False) -> None:
shared.create_context(context_size)
askai_bus = AskAiEvents.bus(ASKAI_BUS_NAME)
askai_bus.subscribe(REPLY_EVENT, _reply_event)
askai_bus.subscribe(REPLY_ERROR_EVENT, partial(_reply_event, error=True))


@click.group()
Expand Down
16 changes: 8 additions & 8 deletions src/main/askai/core/commander/commands/tts_stt_cmd.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,19 @@
Copyright (c) 2024, HomeSetup
"""
import os
from abc import ABC
from pathlib import Path

import pause
from clitt.core.tui.mselect.mselect import mselect

from askai.core.askai_configs import configs
from askai.core.askai_settings import settings
from askai.core.component.audio_player import player
from askai.core.component.recorder import recorder, InputDevice
from askai.core.component.recorder import InputDevice, recorder
from askai.core.support.shared_instances import shared
from askai.core.support.text_formatter import text_formatter
from askai.core.support.utilities import copy_file
from clitt.core.tui.mselect.mselect import mselect
from pathlib import Path

import os
import pause


class TtsSttCmd(ABC):
Expand Down Expand Up @@ -118,7 +117,8 @@ def _set_device(_device) -> bool:

if not name_or_index:
device: InputDevice = mselect(
all_devices, f"{'-=' * 40}%EOL%AskAI::Select the Audio Input device%EOL%{'=-' * 40}%EOL%")
all_devices, f"{'-=' * 40}%EOL%AskAI::Select the Audio Input device%EOL%{'=-' * 40}%EOL%"
)
elif name_or_index.isdecimal() and 0 <= int(name_or_index) <= len(all_devices):
name_or_index = all_devices[int(name_or_index)][1]
device = next((dev for dev in all_devices if dev[1] == name_or_index), None)
Expand Down
Loading

0 comments on commit ebbd1bb

Please sign in to comment.