From 4009b975ff8f68eced1a19b64d5a591238a058b5 Mon Sep 17 00:00:00 2001 From: Hugo Saporetti Junior Date: Mon, 21 Oct 2024 17:38:55 -0300 Subject: [PATCH] Refactorings + Initial splitter pipeline --- assets/images/AskAI-New-Flow.drawio.png | Bin 0 -> 42575 bytes dependencies.hspd | 1 + src/demo/components/camera_demo.py | 2 +- src/demo/components/vision_demo.py | 2 +- src/demo/components/webcam_demo.py | 2 +- src/demo/features/rag/x_refs_demo.py | 2 +- src/demo/features/router_demo.py | 2 +- src/demo/features/tools/query_output_demo.py | 2 +- src/demo/others/screenshot_demo.py | 2 +- src/main/askai/core/askai.py | 2 +- .../core/commander/commands/camera_cmd.py | 2 +- src/main/askai/core/component/camera.py | 2 +- src/main/askai/core/component/image_store.py | 2 +- src/main/askai/core/enums/router_mode.py | 12 +- src/main/askai/core/features/__init__.py | 13 --- .../{features => }/processors/__init__.py | 0 .../{features => }/processors/ai_processor.py | 0 .../core/{features => }/processors/chat.py | 4 +- .../core/{features => }/processors/qna.py | 14 +++ .../core/{features => }/processors/qstring.py | 14 +++ .../core/{features => }/processors/rag.py | 14 +++ .../core/processors/splitter/__init__.py | 0 .../processors/splitter/splitter_executor.py | 105 +++++++++++++++++ .../processors/splitter/splitter_pipeline.py | 108 ++++++++++++++++++ .../processors/splitter/splitter_states.py | 29 +++++ .../splitter/splitter_transitions.py | 43 +++++++ .../processors/task_splitter.py | 10 +- .../core/{features => }/router/__init__.py | 0 .../core/{features => }/router/agent_tools.py | 18 +-- .../core/{features => }/router/evaluation.py | 2 +- .../{features => }/router/model_selector.py | 2 +- .../core/{features => }/router/task_agent.py | 18 ++- .../{features => router}/tools/__init__.py | 0 .../{features => router}/tools/analysis.py | 2 +- .../{features => router}/tools/browser.py | 4 +- .../{features => router}/tools/general.py | 2 +- .../{features => router}/tools/generation.py | 2 +- .../tools/summarization.py | 2 +- .../{features => router}/tools/terminal.py | 4 +- .../core/{features => router}/tools/vision.py | 2 +- .../core/{features => router}/tools/webcam.py | 2 +- 41 files changed, 389 insertions(+), 60 deletions(-) create mode 100644 assets/images/AskAI-New-Flow.drawio.png delete mode 100644 src/main/askai/core/features/__init__.py rename src/main/askai/core/{features => }/processors/__init__.py (100%) rename src/main/askai/core/{features => }/processors/ai_processor.py (100%) rename src/main/askai/core/{features => }/processors/chat.py (97%) rename src/main/askai/core/{features => }/processors/qna.py (77%) rename src/main/askai/core/{features => }/processors/qstring.py (84%) rename src/main/askai/core/{features => }/processors/rag.py (93%) create mode 100644 src/main/askai/core/processors/splitter/__init__.py create mode 100644 src/main/askai/core/processors/splitter/splitter_executor.py create mode 100644 src/main/askai/core/processors/splitter/splitter_pipeline.py create mode 100644 src/main/askai/core/processors/splitter/splitter_states.py create mode 100644 src/main/askai/core/processors/splitter/splitter_transitions.py rename src/main/askai/core/{features => }/processors/task_splitter.py (97%) rename src/main/askai/core/{features => }/router/__init__.py (100%) rename src/main/askai/core/{features => }/router/agent_tools.py (94%) rename src/main/askai/core/{features => }/router/evaluation.py (99%) rename src/main/askai/core/{features => }/router/model_selector.py (97%) rename src/main/askai/core/{features => }/router/task_agent.py (90%) rename src/main/askai/core/{features => router}/tools/__init__.py (100%) rename src/main/askai/core/{features => router}/tools/analysis.py (97%) rename src/main/askai/core/{features => router}/tools/browser.py (95%) rename src/main/askai/core/{features => router}/tools/general.py (97%) rename src/main/askai/core/{features => router}/tools/generation.py (98%) rename src/main/askai/core/{features => router}/tools/summarization.py (96%) rename src/main/askai/core/{features => router}/tools/terminal.py (98%) rename src/main/askai/core/{features => router}/tools/vision.py (98%) rename src/main/askai/core/{features => router}/tools/webcam.py (97%) diff --git a/assets/images/AskAI-New-Flow.drawio.png b/assets/images/AskAI-New-Flow.drawio.png new file mode 100644 index 0000000000000000000000000000000000000000..bb7973e5964c1bd44e087e9661c56a0525b57dfe GIT binary patch literal 42575 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 literal 0 HcmV?d00001 diff --git a/dependencies.hspd b/dependencies.hspd index d7823367..3e78317d 100644 --- a/dependencies.hspd +++ b/dependencies.hspd @@ -19,6 +19,7 @@ package: tqdm, version: 4.66.5, mode: ge package: pyperclip, version: 1.9.0, mode: ge package: python-magic, version: 0.4.27, mode: ge package: pytz, version: 2024.1, mode: ge +package: transitions, version: 0.9.2, mode: ge /* LangChain */ package: langchain, version: 0.3.0, mode: ge diff --git a/src/demo/components/camera_demo.py b/src/demo/components/camera_demo.py index 2a474e5a..11b85619 100644 --- a/src/demo/components/camera_demo.py +++ b/src/demo/components/camera_demo.py @@ -1,6 +1,6 @@ from askai.core.component.camera import camera from askai.core.component.image_store import ImageMetadata, store -from askai.core.features.tools.terminal import open_command +from askai.core.router.tools.terminal import open_command from clitt.core.term.cursor import cursor from clitt.core.tui.line_input.line_input import line_input from hspylib.core.tools.text_tools import strip_escapes diff --git a/src/demo/components/vision_demo.py b/src/demo/components/vision_demo.py index b69309fd..1c10b699 100644 --- a/src/demo/components/vision_demo.py +++ b/src/demo/components/vision_demo.py @@ -1,4 +1,4 @@ -from askai.core.features.tools.vision import offline_captioner +from askai.core.router.tools.vision import offline_captioner import os diff --git a/src/demo/components/webcam_demo.py b/src/demo/components/webcam_demo.py index 551a2e56..960ed034 100644 --- a/src/demo/components/webcam_demo.py +++ b/src/demo/components/webcam_demo.py @@ -12,7 +12,7 @@ Copyright (c) 2024, HomeSetup """ -from askai.core.features.tools.webcam import webcam_capturer +from askai.core.router.tools.webcam import webcam_capturer from hspylib.core.tools.commons import sysout from utils import init_context diff --git a/src/demo/features/rag/x_refs_demo.py b/src/demo/features/rag/x_refs_demo.py index 16ebdd0a..a0c8c7a6 100644 --- a/src/demo/features/rag/x_refs_demo.py +++ b/src/demo/features/rag/x_refs_demo.py @@ -1,4 +1,4 @@ -from askai.core.features.router.evaluation import resolve_x_refs +from askai.core.router.evaluation import resolve_x_refs from askai.core.support.shared_instances import shared from askai.core.support.utilities import display_text from utils import get_resource, init_context diff --git a/src/demo/features/router_demo.py b/src/demo/features/router_demo.py index 674ec727..a50d3a27 100644 --- a/src/demo/features/router_demo.py +++ b/src/demo/features/router_demo.py @@ -1,4 +1,4 @@ -from askai.core.features.processors.task_splitter import splitter +from askai.core.router.processors.task_splitter import splitter from askai.core.support.shared_instances import shared from askai.core.support.utilities import display_text from utils import init_context diff --git a/src/demo/features/tools/query_output_demo.py b/src/demo/features/tools/query_output_demo.py index eef80d6c..d8ee5656 100644 --- a/src/demo/features/tools/query_output_demo.py +++ b/src/demo/features/tools/query_output_demo.py @@ -1,4 +1,4 @@ -from askai.core.features.tools.analysis import query_output +from askai.core.router.tools.analysis import query_output from askai.core.support.shared_instances import shared from askai.core.support.utilities import display_text from utils import get_resource, init_context diff --git a/src/demo/others/screenshot_demo.py b/src/demo/others/screenshot_demo.py index efe37eaa..ea6bb706 100644 --- a/src/demo/others/screenshot_demo.py +++ b/src/demo/others/screenshot_demo.py @@ -1,4 +1,4 @@ -from askai.core.features.tools.vision import take_screenshot +from askai.core.router.tools.vision import take_screenshot from hspylib.core.tools.commons import sysout from utils import init_context diff --git a/src/main/askai/core/askai.py b/src/main/askai/core/askai.py index 28c2e7a3..53d81457 100644 --- a/src/main/askai/core/askai.py +++ b/src/main/askai/core/askai.py @@ -21,8 +21,8 @@ from askai.core.component.cache_service import cache, CACHE_DIR from askai.core.engine.ai_engine import AIEngine from askai.core.enums.router_mode import RouterMode -from askai.core.features.processors.ai_processor import AIProcessor from askai.core.model.ai_reply import AIReply +from askai.core.router.processors.ai_processor import AIProcessor from askai.core.support.chat_context import ChatContext from askai.core.support.shared_instances import shared from askai.core.support.utilities import read_stdin diff --git a/src/main/askai/core/commander/commands/camera_cmd.py b/src/main/askai/core/commander/commands/camera_cmd.py index c789d5ea..95e562d0 100644 --- a/src/main/askai/core/commander/commands/camera_cmd.py +++ b/src/main/askai/core/commander/commands/camera_cmd.py @@ -1,7 +1,7 @@ from abc import ABC from askai.core.askai_configs import configs from askai.core.component.camera import camera -from askai.core.features.tools.webcam import webcam_capturer, webcam_identifier +from askai.core.router.tools.webcam import webcam_capturer, webcam_identifier from askai.core.support.text_formatter import text_formatter from askai.core.support.utilities import display_text from hspylib.core.metaclass.classpath import AnyPath diff --git a/src/main/askai/core/component/camera.py b/src/main/askai/core/component/camera.py index 1c4ec29e..418a561e 100644 --- a/src/main/askai/core/component/camera.py +++ b/src/main/askai/core/component/camera.py @@ -19,9 +19,9 @@ from askai.core.component.audio_player import player from askai.core.component.cache_service import FACE_DIR, IMG_IMPORTS_DIR, PHOTO_DIR from askai.core.component.image_store import ImageData, ImageFile, ImageMetadata, store -from askai.core.features.tools.vision import image_captioner, parse_caption from askai.core.model.ai_reply import AIReply from askai.core.model.image_result import ImageResult +from askai.core.router.tools.vision import image_captioner, parse_caption from askai.core.support.utilities import build_img_path from askai.exception.exceptions import CameraAccessFailure, WebCamInitializationFailure from hspylib.core.metaclass.classpath import AnyPath diff --git a/src/main/askai/core/component/image_store.py b/src/main/askai/core/component/image_store.py index b10f8e3d..240be561 100644 --- a/src/main/askai/core/component/image_store.py +++ b/src/main/askai/core/component/image_store.py @@ -12,7 +12,7 @@ Copyright (c) 2024, HomeSetup """ -from askai.core.features.tools.vision import offline_captioner +from askai.core.router.tools.vision import offline_captioner from chromadb.api.types import IncludeEnum from chromadb.utils.data_loaders import ImageLoader from chromadb.utils.embedding_functions.open_clip_embedding_function import OpenCLIPEmbeddingFunction diff --git a/src/main/askai/core/enums/router_mode.py b/src/main/askai/core/enums/router_mode.py index 4f17be0e..b3426eb4 100644 --- a/src/main/askai/core/enums/router_mode.py +++ b/src/main/askai/core/enums/router_mode.py @@ -14,12 +14,12 @@ """ from askai.core.askai_configs import configs from askai.core.askai_messages import msg -from askai.core.features.processors.ai_processor import AIProcessor -from askai.core.features.processors.chat import chat -from askai.core.features.processors.qna import qna -from askai.core.features.processors.qstring import qstring -from askai.core.features.processors.rag import rag -from askai.core.features.processors.task_splitter import splitter +from askai.core.router.processors.ai_processor import AIProcessor +from askai.core.router.processors.chat import chat +from askai.core.router.processors.qna import qna +from askai.core.router.processors.qstring import qstring +from askai.core.router.processors.rag import rag +from askai.core.router.processors.task_splitter import splitter from functools import lru_cache from hspylib.core.enums.enumeration import Enumeration from hspylib.core.tools.dict_tools import get_or_default_by_key diff --git a/src/main/askai/core/features/__init__.py b/src/main/askai/core/features/__init__.py deleted file mode 100644 index 0371ce64..00000000 --- a/src/main/askai/core/features/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -# _*_ coding: utf-8 _*_ -# -# hspylib-askai v1.1.0 -# -# Package: main.askai.core.features -"""Package initialization.""" - -__all__ = [ - 'processors', - 'router', - 'tools' -] -__version__ = '1.1.0' diff --git a/src/main/askai/core/features/processors/__init__.py b/src/main/askai/core/processors/__init__.py similarity index 100% rename from src/main/askai/core/features/processors/__init__.py rename to src/main/askai/core/processors/__init__.py diff --git a/src/main/askai/core/features/processors/ai_processor.py b/src/main/askai/core/processors/ai_processor.py similarity index 100% rename from src/main/askai/core/features/processors/ai_processor.py rename to src/main/askai/core/processors/ai_processor.py diff --git a/src/main/askai/core/features/processors/chat.py b/src/main/askai/core/processors/chat.py similarity index 97% rename from src/main/askai/core/features/processors/chat.py rename to src/main/askai/core/processors/chat.py index 51656a78..f97a612a 100644 --- a/src/main/askai/core/features/processors/chat.py +++ b/src/main/askai/core/processors/chat.py @@ -3,8 +3,8 @@ """ @project: taius-coder - @package: taius-coder.main.taius_coder.core - @file: chat_processor.py + @package: askai.core.processors.chat + @file: chat.py @created: Mon, 23 Sep 2024 @author: Hugo Saporetti Junior" @site: https://github.com/yorevs/taius-coder diff --git a/src/main/askai/core/features/processors/qna.py b/src/main/askai/core/processors/qna.py similarity index 77% rename from src/main/askai/core/features/processors/qna.py rename to src/main/askai/core/processors/qna.py index a80cb1f5..ecff9e6f 100644 --- a/src/main/askai/core/features/processors/qna.py +++ b/src/main/askai/core/processors/qna.py @@ -1,3 +1,17 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +""" + @project: HsPyLib-AskAI + @package: askai.core.processors.qna + @file: qna.py + @created: Fri, 5 May 2024 + @author: Hugo Saporetti Junior + @site: https://github.com/yorevs/askai + @license: MIT - Please refer to + + Copyright (c) 2024, HomeSetup +""" from askai.core.askai_events import events from askai.core.askai_messages import msg from askai.core.component.summarizer import summarizer diff --git a/src/main/askai/core/features/processors/qstring.py b/src/main/askai/core/processors/qstring.py similarity index 84% rename from src/main/askai/core/features/processors/qstring.py rename to src/main/askai/core/processors/qstring.py index f1ee99be..8c48addf 100644 --- a/src/main/askai/core/features/processors/qstring.py +++ b/src/main/askai/core/processors/qstring.py @@ -1,3 +1,17 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +""" + @project: HsPyLib-AskAI + @package: askai.core.processors.qstring + @file: qstring.py + @created: Fri, 5 May 2024 + @author: Hugo Saporetti Junior + @site: https://github.com/yorevs/askai + @license: MIT - Please refer to + + Copyright (c) 2024, HomeSetup +""" from askai.core.askai_prompt import prompt from askai.core.component.cache_service import cache from askai.core.engine.openai.temperature import Temperature diff --git a/src/main/askai/core/features/processors/rag.py b/src/main/askai/core/processors/rag.py similarity index 93% rename from src/main/askai/core/features/processors/rag.py rename to src/main/askai/core/processors/rag.py index b6c273ce..acb8aec0 100644 --- a/src/main/askai/core/features/processors/rag.py +++ b/src/main/askai/core/processors/rag.py @@ -1,3 +1,17 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +""" + @project: HsPyLib-AskAI + @package: askai.core.processors.rag + @file: rag.py + @created: Fri, 5 May 2024 + @author: Hugo Saporetti Junior + @site: https://github.com/yorevs/askai + @license: MIT - Please refer to + + Copyright (c) 2024, HomeSetup +""" import logging as log import os import shutil diff --git a/src/main/askai/core/processors/splitter/__init__.py b/src/main/askai/core/processors/splitter/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/main/askai/core/processors/splitter/splitter_executor.py b/src/main/askai/core/processors/splitter/splitter_executor.py new file mode 100644 index 00000000..b7a05440 --- /dev/null +++ b/src/main/askai/core/processors/splitter/splitter_executor.py @@ -0,0 +1,105 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +""" + @project: HsPyLib-AskAI + @package: askai.core.processors.splitter.splitter_executor + @file: splitter_executor.py + @created: Mon, 21 Oct 2024 + @author: Hugo Saporetti Junior + @site: https://github.com/yorevs/askai + @license: MIT - Please refer to + + Copyright (c) 2024, HomeSetup +""" +from threading import Thread + +from hspylib.core.decorator.decorators import profiled +from rich.console import Console + +from askai.core.askai_configs import configs +from askai.core.enums.acc_color import AccColor +from askai.core.processors.splitter.splitter_pipeline import SplitterPipeline +from askai.core.processors.splitter.splitter_states import States + + +class SplitterExecutor(Thread): + """Responsible for executing a Taius Coder pipeline.""" + + def __init__(self, pipeline: SplitterPipeline): + super().__init__() + self._pipeline = pipeline + self._console = Console() + + @property + def pipeline(self) -> SplitterPipeline: + return self._pipeline + + @profiled + def run(self): + with self._console.status("Processing query...", spinner="dots") as spinner: + max_retries: int = configs.max_router_retries + while not self.pipeline.state == States.COMPLETE: + self.pipeline.track_previous() + spinner.update(f"[green]{self.pipeline.state.value}[/green]") + if 0 < max_retries < self.pipeline.failures[self.pipeline.state.value]: + spinner.update(f"\nMax state retries reached: {max_retries}") + break + match self.pipeline.state: + case States.STARTUP: + if self.pipeline.st_startup(): + self.pipeline.ev_pipeline_started() + case States.QUERY_QUEUED: + if self.pipeline.st_query_queued(): + self.pipeline.ev_query_queued() + case States.MODEL_SELECT: + if self.pipeline.st_model_select(): + self.pipeline.ev_model_selected() + case States.TASK_SPLIT: + status, direct = self.pipeline.st_task_split() + if status: + if direct: + self.pipeline.ev_direct_answer() + else: + self.pipeline.ev_plan_created() + case States.EXECUTE_TASK: + color, has_next = self.pipeline.st_execute_next() + if color.passed: + if has_next: + self.pipeline.st_execute_next() + else: + self.pipeline.ev_task_executed() + case States.ACCURACY_CHECK: + color: AccColor = self.pipeline.st_accuracy_check() + if color.passed: + self.pipeline.ev_accuracy_passed() + else: + self.pipeline.ev_accuracy_failed() + case States.REFINE_ANSWER: + if self.pipeline.st_refine_answer(): + self.pipeline.ev_answer_refined() + case _: + spinner.update(f"Error: Machine stopped before it was done ({self.pipeline.state}) %NC%") + break + execution_status: bool = self.pipeline.previous != self.pipeline.state + execution_status_str: str = ( + f"{'[green]√[/green]' if execution_status else '[red]X[/red]'}" + f" {str(self.pipeline.previous)}" + ) + self.pipeline.failures[self.pipeline.state.value] += 1 if not execution_status else 0 + self._console.print(f"[green]{execution_status_str}[/green]") + + final_state: States = self.pipeline.state + final_state_str: str = '[green]√ Succeeded[/green] ' if final_state == States.COMPLETE else '[red]X Failed [/red]' + self._console.print(f"[cyan]Pipeline Execution {final_state_str} [cyan][{final_state}][/cyan]") + + if final_state != States.COMPLETE: + self._console.print(f"Failed to generate a response") + + +if __name__ == '__main__': + query: str = "What is the size of the moon" + p: SplitterPipeline = SplitterPipeline(query) + executor: SplitterExecutor = SplitterExecutor(p) + executor.start() + executor.join() diff --git a/src/main/askai/core/processors/splitter/splitter_pipeline.py b/src/main/askai/core/processors/splitter/splitter_pipeline.py new file mode 100644 index 00000000..177be609 --- /dev/null +++ b/src/main/askai/core/processors/splitter/splitter_pipeline.py @@ -0,0 +1,108 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +""" + @project: HsPyLib-AskAI + @package: askai.core.processors.splitter.splitter_pipeline + @file: ai_engine.py + @created: Mon, 21 Oct 2024 + @author: Hugo Saporetti Junior + @site: https://github.com/yorevs/askai + @license: MIT - Please refer to + + Copyright (c) 2024, HomeSetup +""" +import random +from collections import defaultdict +from typing import AnyStr + +import pause +from transitions import Machine + +from askai.core.enums.acc_color import AccColor +from askai.core.model.action_plan import ActionPlan +from askai.core.processors.splitter.splitter_states import States +from askai.core.processors.splitter.splitter_transitions import Transition, TRANSITIONS + + +class SplitterPipeline: + """TODO""" + + state: States + + FAKE_SLEEP: int = 1 + + def __init__(self, query: AnyStr): + self._transitions: list[Transition] = [t for t in TRANSITIONS] + self._machine: Machine = Machine( + name="Taius-Coder", + model=self, + initial=States.STARTUP, + states=States, + transitions=self._transitions, + auto_transitions=False + ) + self._previous: States | None = None + self._failures: dict[str, int] = defaultdict(int) + self._iteractions: int = 0 + self._query: str = query + self._plan: ActionPlan | None = None + + @property + def failures(self) -> dict[str, int]: + return self._failures + + @property + def plan(self) -> ActionPlan: + return self._plan + + @property + def previous(self) -> States: + return self._previous + + def track_previous(self) -> None: + self._previous = self.state + + def has_next(self) -> bool: + """TODO""" + return len(self.plan.tasks) > 0 if self.plan else False + + def is_direct(self) -> bool: + """TODO""" + return self.plan.is_direct if self.plan else True + + def st_startup(self) -> bool: + result = random.choice([True, False]) + pause.seconds(self.FAKE_SLEEP) + return result + + def st_query_queued(self) -> bool: + result = random.choice([True, False]) + pause.seconds(self.FAKE_SLEEP) + return result + + def st_model_select(self) -> bool: + result = random.choice([True, False]) + pause.seconds(self.FAKE_SLEEP) + return result + + def st_task_split(self) -> tuple[bool, bool]: + result1, result2 = random.choice([True, False]), random.choice([True, False]) + pause.seconds(self.FAKE_SLEEP) + return result1, result2 + + def st_execute_next(self) -> tuple[AccColor, bool]: + color = AccColor.value_of(random.choice(AccColor.names())) + result = random.choice([True, False]) + pause.seconds(self.FAKE_SLEEP) + return color, result + + def st_accuracy_check(self) -> AccColor: + color = AccColor.value_of(random.choice(AccColor.names())) + pause.seconds(self.FAKE_SLEEP) + return color + + def st_refine_answer(self) -> bool: + result = random.choice([True, False]) + pause.seconds(self.FAKE_SLEEP) + return result diff --git a/src/main/askai/core/processors/splitter/splitter_states.py b/src/main/askai/core/processors/splitter/splitter_states.py new file mode 100644 index 00000000..babf7f76 --- /dev/null +++ b/src/main/askai/core/processors/splitter/splitter_states.py @@ -0,0 +1,29 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +""" + @project: HsPyLib-AskAI + @package: askai.core.processors.splitter.splitter_states + @file: splitter_states.py + @created: Mon, 21 Oct 2024 + @author: Hugo Saporetti Junior + @site: https://github.com/yorevs/askai + @license: MIT - Please refer to + + Copyright (c) 2024, HomeSetup +""" +from hspylib.core.enums.enumeration import Enumeration + + +class States(Enumeration): + """Enumeration of possible task splitter states.""" + # fmt: off + STARTUP = 'Processing query' + QUERY_QUEUED = 'Queuing Query' + MODEL_SELECT = 'Selecting Model' + TASK_SPLIT = 'Splitting Task' + ACCURACY_CHECK = 'Checking Accuracy' + EXECUTE_TASK = 'Executing Task' + REFINE_ANSWER = 'Refining Answer' + COMPLETE = 'Completed' + # fmt: on diff --git a/src/main/askai/core/processors/splitter/splitter_transitions.py b/src/main/askai/core/processors/splitter/splitter_transitions.py new file mode 100644 index 00000000..d38a80b4 --- /dev/null +++ b/src/main/askai/core/processors/splitter/splitter_transitions.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +""" + @project: HsPyLib-AskAI + @package: askai.core.processors.splitter.splitter_transitions + @file: splitter_transitions.py + @created: Mon, 21 Oct 2024 + @author: Hugo Saporetti Junior + @site: https://github.com/yorevs/askai + @license: MIT - Please refer to + + Copyright (c) 2024, HomeSetup +""" +from typing import TypeAlias + +from askai.core.processors.splitter.splitter_states import States + +# Define the transitions between states +Transition: TypeAlias = dict[str, str | States] + +# Define transitions from the workflow +TRANSITIONS = [ + {'trigger': 'ev_pipeline_started', 'source': States.STARTUP, 'dest': States.QUERY_QUEUED}, + {'trigger': 'ev_query_queued', 'source': States.QUERY_QUEUED, 'dest': States.MODEL_SELECT}, + {'trigger': 'ev_model_selected', 'source': States.MODEL_SELECT, 'dest': States.TASK_SPLIT}, + + {'trigger': 'ev_direct_answer', 'source': States.TASK_SPLIT, 'dest': States.ACCURACY_CHECK}, + {'trigger': 'ev_plan_created', 'source': States.TASK_SPLIT, 'dest': States.EXECUTE_TASK}, + + {'trigger': 'ev_accuracy_check', 'source': States.ACCURACY_CHECK, 'dest': States.EXECUTE_TASK}, + + {'trigger': 'ev_task_executed', 'source': States.EXECUTE_TASK, 'dest': States.ACCURACY_CHECK}, + + {'trigger': 'ev_accuracy_passed', 'source': States.ACCURACY_CHECK, 'dest': States.EXECUTE_TASK, 'conditions': ['has_next']}, + {'trigger': 'ev_accuracy_passed', 'source': States.ACCURACY_CHECK, 'dest': States.COMPLETE, 'unless': ['has_next']}, + {'trigger': 'ev_accuracy_failed', 'source': States.ACCURACY_CHECK, 'dest': States.EXECUTE_TASK, 'conditions': ['has_next']}, + {'trigger': 'ev_refine_required', 'source': States.ACCURACY_CHECK, 'dest': States.REFINE_ANSWER, 'conditions': ['is_direct']}, + + {'trigger': 'ev_answer_refined', 'source': States.REFINE_ANSWER, 'dest': States.COMPLETE}, + + {'trigger': 'ev_task_complete', 'source': States.TASK_SPLIT, 'dest': States.COMPLETE}, +] diff --git a/src/main/askai/core/features/processors/task_splitter.py b/src/main/askai/core/processors/task_splitter.py similarity index 97% rename from src/main/askai/core/features/processors/task_splitter.py rename to src/main/askai/core/processors/task_splitter.py index fae1af1a..850edbf8 100644 --- a/src/main/askai/core/features/processors/task_splitter.py +++ b/src/main/askai/core/processors/task_splitter.py @@ -3,7 +3,7 @@ """ @project: HsPyLib-AskAI - @package: askai.core.features.router + @package: askai.core.router.router @file: task_splitter.py @created: Mon, 01 Apr 2024 @author: Hugo Saporetti Junior @@ -21,14 +21,14 @@ from askai.core.engine.openai.temperature import Temperature from askai.core.enums.acc_color import AccColor from askai.core.enums.response_model import ResponseModel -from askai.core.features.router.agent_tools import features -from askai.core.features.router.evaluation import assert_accuracy -from askai.core.features.router.task_agent import agent -from askai.core.features.tools.general import final_answer from askai.core.model.acc_response import AccResponse from askai.core.model.action_plan import ActionPlan from askai.core.model.ai_reply import AIReply from askai.core.model.model_result import ModelResult +from askai.core.router.agent_tools import features +from askai.core.router.evaluation import assert_accuracy +from askai.core.router.task_agent import agent +from askai.core.router.tools.general import final_answer from askai.core.support.langchain_support import lc_llm from askai.core.support.shared_instances import shared from askai.exception.exceptions import InaccurateResponse, InterruptionRequest, TerminatingQuery diff --git a/src/main/askai/core/features/router/__init__.py b/src/main/askai/core/router/__init__.py similarity index 100% rename from src/main/askai/core/features/router/__init__.py rename to src/main/askai/core/router/__init__.py diff --git a/src/main/askai/core/features/router/agent_tools.py b/src/main/askai/core/router/agent_tools.py similarity index 94% rename from src/main/askai/core/features/router/agent_tools.py rename to src/main/askai/core/router/agent_tools.py index ec3c3226..8834f59e 100644 --- a/src/main/askai/core/features/router/agent_tools.py +++ b/src/main/askai/core/router/agent_tools.py @@ -3,7 +3,7 @@ """ @project: HsPyLib-AskAI - @package: askai.core.features.actions + @package: askai.core.router @file: agent_tools.py @created: Mon, 01 Apr 2024 @author: Hugo Saporetti Junior @@ -13,14 +13,14 @@ Copyright (c) 2024, HomeSetup """ from askai.core.askai_messages import msg -from askai.core.features.tools.analysis import query_output -from askai.core.features.tools.browser import browse, open_url -from askai.core.features.tools.general import display_tool -from askai.core.features.tools.generation import generate_content, save_content -from askai.core.features.tools.summarization import summarize -from askai.core.features.tools.terminal import execute_command, list_contents, open_command -from askai.core.features.tools.vision import image_captioner, parse_caption -from askai.core.features.tools.webcam import webcam_capturer, webcam_identifier +from askai.core.router.tools.analysis import query_output +from askai.core.router.tools.browser import browse, open_url +from askai.core.router.tools.general import display_tool +from askai.core.router.tools.generation import generate_content, save_content +from askai.core.router.tools.summarization import summarize +from askai.core.router.tools.terminal import execute_command, list_contents, open_command +from askai.core.router.tools.vision import image_captioner, parse_caption +from askai.core.router.tools.webcam import webcam_capturer, webcam_identifier from askai.exception.exceptions import TerminatingQuery from clitt.core.tui.line_input.line_input import line_input from functools import lru_cache diff --git a/src/main/askai/core/features/router/evaluation.py b/src/main/askai/core/router/evaluation.py similarity index 99% rename from src/main/askai/core/features/router/evaluation.py rename to src/main/askai/core/router/evaluation.py index e6e1d204..fd41a63f 100644 --- a/src/main/askai/core/features/router/evaluation.py +++ b/src/main/askai/core/router/evaluation.py @@ -3,7 +3,7 @@ """ @project: HsPyLib-AskAI - @package: askai.core.features.rag.commons + @package: askai.core.router.evaluation @file: analysis.py @created: Fri, 03 Apr 2024 @author: Hugo Saporetti Junior diff --git a/src/main/askai/core/features/router/model_selector.py b/src/main/askai/core/router/model_selector.py similarity index 97% rename from src/main/askai/core/features/router/model_selector.py rename to src/main/askai/core/router/model_selector.py index 95d55687..9805cf9b 100644 --- a/src/main/askai/core/features/router/model_selector.py +++ b/src/main/askai/core/router/model_selector.py @@ -3,7 +3,7 @@ """ @project: HsPyLib-AskAI - @package: askai.core.features.router.model_selector + @package: askai.core.router.model_selector @file: model_selector.py @created: Tue, 24 Jun 2024 @author: Hugo Saporetti Junior diff --git a/src/main/askai/core/features/router/task_agent.py b/src/main/askai/core/router/task_agent.py similarity index 90% rename from src/main/askai/core/features/router/task_agent.py rename to src/main/askai/core/router/task_agent.py index 7bedc1a7..9cab51d0 100644 --- a/src/main/askai/core/features/router/task_agent.py +++ b/src/main/askai/core/router/task_agent.py @@ -1,12 +1,26 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +""" + @project: HsPyLib-AskAI + @package: askai.core.router.task_agent + @file: task_agent.py + @created: Tue, 24 Jun 2024 + @author: Hugo Saporetti Junior + @site: https://github.com/yorevs/askai + @license: MIT - Please refer to + + Copyright (c) 2024, HomeSetup +""" from askai.core.askai_configs import configs from askai.core.askai_events import events from askai.core.askai_messages import msg from askai.core.askai_prompt import prompt from askai.core.engine.openai.temperature import Temperature from askai.core.enums.acc_color import AccColor -from askai.core.features.router.agent_tools import features -from askai.core.features.router.evaluation import assert_accuracy from askai.core.model.ai_reply import AIReply +from askai.core.router.agent_tools import features +from askai.core.router.evaluation import assert_accuracy from askai.core.support.langchain_support import lc_llm from askai.core.support.shared_instances import shared from askai.exception.exceptions import InaccurateResponse diff --git a/src/main/askai/core/features/tools/__init__.py b/src/main/askai/core/router/tools/__init__.py similarity index 100% rename from src/main/askai/core/features/tools/__init__.py rename to src/main/askai/core/router/tools/__init__.py diff --git a/src/main/askai/core/features/tools/analysis.py b/src/main/askai/core/router/tools/analysis.py similarity index 97% rename from src/main/askai/core/features/tools/analysis.py rename to src/main/askai/core/router/tools/analysis.py index e68cecbb..8c6f4a84 100644 --- a/src/main/askai/core/features/tools/analysis.py +++ b/src/main/askai/core/router/tools/analysis.py @@ -3,7 +3,7 @@ """ @project: HsPyLib-AskAI - @package: askai.core.features.tools.analysis + @package: askai.core.router.tools.analysis @file: analysis.py @created: Mon, 01 Apr 2024 @author: Hugo Saporetti Junior diff --git a/src/main/askai/core/features/tools/browser.py b/src/main/askai/core/router/tools/browser.py similarity index 95% rename from src/main/askai/core/features/tools/browser.py rename to src/main/askai/core/router/tools/browser.py index 6c51b781..cee94773 100644 --- a/src/main/askai/core/features/tools/browser.py +++ b/src/main/askai/core/router/tools/browser.py @@ -3,7 +3,7 @@ """ @project: HsPyLib-AskAI - @package: askai.core.features.tools.browser + @package: askai.core.router.tools.browser @file: browser.py @created: Mon, 01 Apr 2024 @author: Hugo Saporetti Junior @@ -17,8 +17,8 @@ from askai.core.component.geo_location import geo_location from askai.core.component.internet_service import internet from askai.core.engine.openai.temperature import Temperature -from askai.core.features.tools.terminal import execute_bash from askai.core.model.search_result import SearchResult +from askai.core.router.tools.terminal import execute_bash from askai.core.support.langchain_support import lc_llm from askai.core.support.shared_instances import shared from langchain_core.prompts import PromptTemplate diff --git a/src/main/askai/core/features/tools/general.py b/src/main/askai/core/router/tools/general.py similarity index 97% rename from src/main/askai/core/features/tools/general.py rename to src/main/askai/core/router/tools/general.py index cf4401dc..714c0537 100644 --- a/src/main/askai/core/features/tools/general.py +++ b/src/main/askai/core/router/tools/general.py @@ -3,7 +3,7 @@ """ @project: HsPyLib-AskAI - @package: askai.core.features.tools.general + @package: askai.core.router.tools.general @file: general.py @created: Mon, 01 Apr 2024 @author: Hugo Saporetti Junior diff --git a/src/main/askai/core/features/tools/generation.py b/src/main/askai/core/router/tools/generation.py similarity index 98% rename from src/main/askai/core/features/tools/generation.py rename to src/main/askai/core/router/tools/generation.py index b73d280d..97674c7d 100644 --- a/src/main/askai/core/features/tools/generation.py +++ b/src/main/askai/core/router/tools/generation.py @@ -3,7 +3,7 @@ """ @project: HsPyLib-AskAI - @package: askai.core.features.tools.generation + @package: askai.core.router.tools.generation @file: generation.py @created: Mon, 01 Apr 2024 @author: Hugo Saporetti Junior diff --git a/src/main/askai/core/features/tools/summarization.py b/src/main/askai/core/router/tools/summarization.py similarity index 96% rename from src/main/askai/core/features/tools/summarization.py rename to src/main/askai/core/router/tools/summarization.py index 1c66f8d1..3e5764e4 100644 --- a/src/main/askai/core/features/tools/summarization.py +++ b/src/main/askai/core/router/tools/summarization.py @@ -3,7 +3,7 @@ """ @project: HsPyLib-AskAI - @package: askai.core.features.tools.summarization + @package: askai.core.router.tools.summarization @file: summarization.py @created: Mon, 01 Apr 2024 @author: Hugo Saporetti Junior diff --git a/src/main/askai/core/features/tools/terminal.py b/src/main/askai/core/router/tools/terminal.py similarity index 98% rename from src/main/askai/core/features/tools/terminal.py rename to src/main/askai/core/router/tools/terminal.py index b573fc05..d23b02bb 100644 --- a/src/main/askai/core/features/tools/terminal.py +++ b/src/main/askai/core/router/tools/terminal.py @@ -3,7 +3,7 @@ """ @project: HsPyLib-AskAI - @package: askai.core.features.tools.terminal + @package: askai.core.router.tools.terminal @file: terminal.py @created: Mon, 01 Apr 2024 @author: Hugo Saporetti Junior @@ -15,8 +15,8 @@ from askai.core.askai_events import events from askai.core.askai_messages import msg -from askai.core.features.router.evaluation import resolve_x_refs from askai.core.model.ai_reply import AIReply +from askai.core.router.evaluation import resolve_x_refs from askai.core.support.shared_instances import shared from askai.core.support.utilities import extract_path, media_type_of from clitt.core.term.terminal import terminal diff --git a/src/main/askai/core/features/tools/vision.py b/src/main/askai/core/router/tools/vision.py similarity index 98% rename from src/main/askai/core/features/tools/vision.py rename to src/main/askai/core/router/tools/vision.py index 78fe35e7..010f2615 100644 --- a/src/main/askai/core/features/tools/vision.py +++ b/src/main/askai/core/router/tools/vision.py @@ -2,9 +2,9 @@ from askai.core.askai_messages import msg from askai.core.component.cache_service import PICTURE_DIR from askai.core.engine.ai_vision import AIVision -from askai.core.features.router.evaluation import resolve_x_refs from askai.core.model.ai_reply import AIReply from askai.core.model.image_result import ImageResult +from askai.core.router.evaluation import resolve_x_refs from askai.core.support.shared_instances import shared from hspylib.core.config.path_object import PathObject from hspylib.core.enums.enumeration import Enumeration diff --git a/src/main/askai/core/features/tools/webcam.py b/src/main/askai/core/router/tools/webcam.py similarity index 97% rename from src/main/askai/core/features/tools/webcam.py rename to src/main/askai/core/router/tools/webcam.py index 554dd4bf..12679bf9 100644 --- a/src/main/askai/core/features/tools/webcam.py +++ b/src/main/askai/core/router/tools/webcam.py @@ -1,6 +1,6 @@ from askai.core.askai_configs import configs from askai.core.component.camera import camera -from askai.core.features.tools.vision import image_captioner, parse_caption +from askai.core.router.tools.vision import image_captioner, parse_caption from askai.core.support.utilities import display_text from hspylib.core.tools.text_tools import ensure_endswith, ensure_startswith from os.path import basename