Skip to content

Commit

Permalink
👌 IMPROVE: Refactored structure, updated dependencies, enhanced quality
Browse files Browse the repository at this point in the history
Refactored codebase for improved readability, updated Poetry dependencies for enhanced security, and restructured files for better organization. This organization should make it easier for us in the future to convert the repository into a Python package.

Update README.md

Update README.md
  • Loading branch information
bearlike committed May 10, 2024
1 parent 97b11f5 commit 576f721
Show file tree
Hide file tree
Showing 35 changed files with 6,491 additions and 426 deletions.
8 changes: 5 additions & 3 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
# * Personal Assistant Configuration
# * Environment file for Meeseeks - Personal Assistant
# * Repository: https://github.com/bearlike/personal-assistant
# - Rename this file to .env to make your application functional
# - Rename this file to .env to make your application functional and remove unused variables.
# TODO-FUTURE: Convert this file to a YAML format for better readability


# * Application Version and Environment Mode
# * Meeseeks Settings
# - VERSION: Version of your application (There is no need to change these value)
# - ENVMODE: Environment mode of your application (valid options: dev, prod)
VERSION=0.0.1
ENVMODE=dev
LOG_LEVEL=DEBUG
CACHE_DIR='/path/to/cache/directory'


# * Home Assistant Configuration
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# Ignore Repo to Prompt
repo-to-prompt.codemod.js

# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
Expand Down
72 changes: 52 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
> Look at me, I'm Mr Meeseeks.

![Screenshot of Meeseks WebUI](docs/screenshot_chat_app_1.png)
<p align="center">
<img src="docs/screenshot_chat_app_1.png" alt="Screenshot of Meeseks WebUI" height="512px">
</p>

## Project Motivation 🚀
Meeseeks is an AI assistant powered by a multi-agent large language model (LLM) architecture that breaks down complex problems into smaller, more manageable tasks. These tasks are then handled by autonomous agents, which leverage the reasoning capabilities of LLMs. By decomposing problems into smaller queries, Meeseeks significantly improves caching efficiency, especially when combined with semantic caching techniques.
Expand All @@ -16,20 +18,21 @@ Meeseeks builds upon recent advancements in LLM-based multi-agent systems, which
## Features 🔥
| Completed | In-Progress | Planned | Scoping |
| :-------: | :---------: | :-----: | :-----: |
| | 🚧 | 📅 | 🧐 |
|| 🚧 | 📅 | 🧐 |


| Status | Feature |
| :----: | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Status | Feature |
| :----: | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|| [LangFuse](https://github.com/langfuse/langfuse) integrations to accurate log and monitor chains. |
|| Use natural language to interact with integrations and tools. |
| 🚧 | Simple REST API interface for interfacing with the system. Used by the the `HA Conversation Integration`. |
|| Decomposes user queries to a `TaskQueue` with a list of `ActionSteps`. |
| 🚧 | Custom [Home Assistant Conversation Integration](https://www.home-assistant.io/integrations/conversation/) to allow voice assistance via [**HA Assist**](https://www.home-assistant.io/voice_control/). |
| 🧐 | **(Extras - Quality)** Use CRITIC reflection framework to reflect on a response to a task/query using external tools via `llama_index.agent.introspective.ToolInteractiveReflectionAgentWorker`. |
| 📅 | **(Extras - Privacy)** Integrate with [microsoft/presidio](https://github.com/microsoft/presidio) for customizable PII de-identification. |
|| A chat Interface using `streamlit` that shows the action plan, user types, and response from the LLM. |

### Integrations
### Integrations 📦

| Status | Integration Name | Description |
| :----: | :--------------------------------------: | --------------------------------------------------------------------------------------------------------------------------------- |
Expand All @@ -43,37 +46,64 @@ Meeseeks builds upon recent advancements in LLM-based multi-agent systems, which
| 🧐 | Android Debugging Shell | Use Home Assistant ADB Integrations to perform actions on Android TV Variants via `integrations.HomeAssistant`. |



## Project Setup 🛠️

1. **Environment Setup**: This project requires Python 3.7 or later. It is recommended to use a virtual environment to manage the project dependencies. You can create a virtual environment using the following command:
This project is composed of multiple modules, each with its own set of dependencies. Follow the steps below to set up the project on your local machine.

### Prerequisites

- Python 3.10 or higher
- [Poetry](https://python-poetry.org/docs/#installation) - Simplifies managing Python packages and dependencies.


> [!NOTE]
> **Quick Installation for Mac and Linux Users:** Clone the repository, navigate to the project root and run the below script:
> ```bash
> chmod +x build-install.sh
> ./build-install.sh fallback-install
> ```
### Manual Installation
```sh
python3 -m venv env
1. Clone the repository:
```bash
git clone https://github.com/bearlike/Personal-Assistant.git
```
2. **Activate the Virtual Environment**: Activate the virtual environment using the following command:
2. Navigate to the root directory of the project and install the main module's dependencies:
```sh
source env/bin/activate # On Windows use `env\Scripts\activate`
```bash
cd Personal-Assistant
poetry install
```
3. **Install Dependencies**: Install the project dependencies from the [``requirements.txt``](requirements.txt) file using the following command:
3. To install the optional and development dependencies, navigate to the submodule directories (`meeseeks-api` and `meeseeks-chat`), and install their dependencies:
```sh
pip install -r requirements.txt
```bash
poetry install --dev
cd ../meeseeks-api
poetry install
cd ../meeseeks-chat
poetry install
```
4. **Environment Variables**: Copy the [``.env.example``](.env.example") file to a new file named ``.env`` and fill in the necessary environment variables.
4. **Environment Variables**: Copy the [``.env.example``](.env.example) file to a new file named ``.env`` and modify in the necessary environment variables.
## Running the Streamlit Web Interface
To run the Streamlit app [``chat_master.py``](chat_master.py"), use the following command:
## Running the Meeseeks Chat Interface 🤖
```sh
streamlit run chat_master.py
After installing the dependencies, you can run the application with the following command:
```bash
streamlit run main.py
```
---
## Contributing 👏
We welcome contributions from the community to help improve Meeseeks. Whether you want to fix a bug, add a new feature, or integrate a new tool, your contributions are highly appreciated.
Expand All @@ -89,6 +119,8 @@ To contribute to Meeseeks, please follow these steps:
If you encounter any bugs or have ideas for new features, please open an issue on our [issue tracker](https://github.com/bearlike/Personal-Assistant/issues). We appreciate detailed bug reports that include steps to reproduce the issue and any relevant error messages.
Thank you for considering contributing to Meeseeks! Let's build cool stuff!
Thank you for considering contributing to Meeseeks! Let's build cool stuff!
Expand Down
1 change: 1 addition & 0 deletions __init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#!/usr/bin/env python3
27 changes: 0 additions & 27 deletions backend.py

This file was deleted.

105 changes: 105 additions & 0 deletions build-install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
#!/bin/bash

# This script is used to automate the process of building and installing
# local dependencies for the Meeseeks project. It accepts an argument
# to decide which submodule to install or if all submodules need to be installed.

# Usage:
# ./build-install.sh all # Build and install all submodules
# ./build-install.sh api # Build and install the meeseeks-api submodule
# ./build-install.sh chat # Build and install the meeseeks-chat submodule
# ./build-install.sh fallback-install # Install the meeseeks-chat submodule when on non package mode

function print_usage {
echo "Usage: $0 {fallback-install|all|api|chat}"
echo "fallback-install: Install the meeseeks-chat submodule when on non package mode"
# ! Commented since not fully baked yet.
# echo "all: Build and install all submodules"
# echo "api: Build and install the meeseeks-api submodule"
# echo "chat: Build and install the meeseeks-chat submodule"
}

function build_and_install() {
# Navigate to the submodule directory
script_dir=$(dirname "$(readlink -f "$0")")

cd "$script_dir/$1"

# Build the package
if poetry build; then
# Move the wheel file to the root directory
mv dist/*.whl ../

# Install the package
if ! pip install ../$1-0.1.0-py3-none-any.whl; then
echo "Error: Failed to install the $1 package"
exit 1
fi
else
echo "Error: Failed to build the $1 package"
exit 1
fi

# Clean up unwanted files and folders
rm -rf dist
rm -rf $1.egg-info

# Navigate back to the root directory
cd ..
}

# It manually installs dependencies when in non-package mode.
fallback_install() {
# TODO: Fallback for when non package mode installation fails.
# Get the absolute path of the script directory
script_dir=$(dirname "$(readlink -f "$0")")
# Log the file being installed
# Navigate to the submodule directory
cd "$script_dir/$1"
echo "Installing $script_dir/$1"

# Install the dependencies
if ! poetry install; then
echo "Error: Failed to install the dependencies for the $1 module"
exit 1
fi

# Navigate back to the root directory
cd "$script_dir"
}


if [ "$#" -ne 1 ]; then
echo "Error: Invalid number of arguments"
print_usage
exit 1
fi



# Update the case statement in your build.sh script to support 'fallback-install' and 'fallback-build' arguments
case $1 in
all)
build_and_install "meeseeks-api"
build_and_install "meeseeks-chat"
poetry install --extras "api chat"
;;
api)
build_and_install "meeseeks-api"
poetry install --extras "api"
;;
chat)
build_and_install "meeseeks-chat"
poetry install --extras "chat"
;;
fallback-install)
fallback_install "."
fallback_install "meeseeks-api"
fallback_install "meeseeks-chat"
;;
*)
echo "Error: Invalid argument"
print_usage
exit 1
;;
esac
30 changes: 17 additions & 13 deletions core/classes.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from typing import Optional
from typing import List, Any
# Third-party modules
from langchain_community.document_loaders import DirectoryLoader, JSONLoader
from langchain_community.document_loaders import JSONLoader
from langchain_openai import ChatOpenAI
from langchain_core.pydantic_v1 import BaseModel, Field, validator
from langfuse.callback import CallbackHandler
Expand Down Expand Up @@ -43,6 +43,7 @@ class TaskQueue(BaseModel):
action_steps: Optional[List[ActionStep]] = None

@validator("action_steps", allow_reuse=True)
# pylint: disable=E0213,W0613
def validate_actions(cls, field):
for action in field:
# Normalize once and store it
Expand Down Expand Up @@ -74,8 +75,7 @@ def validate_actions(cls, field):
if error_msg_list:
error_msg = "\n".join(error_msg_list)
for msg in error_msg_list:
logging.error(msg) # Log each error message
raise ValueError(error_msg)
logging.error(msg) # Log

return field

Expand Down Expand Up @@ -107,9 +107,14 @@ def __init__(self, name, description, model_name=None, temperature=0.2):
model=self.model_name,
temperature=temperature
)
cache_dir = os.path.join(os.path.dirname(
__file__), "..", ".cache", self._id)

root_cache_dir = os.getenv("CACHE_DIR", None)
if root_cache_dir is None:
raise ValueError("CACHE_DIR environment variable is not set.")

cache_dir = os.path.join(root_cache_dir, "..", ".cache", self._id)
self.cache_dir = os.path.abspath(cache_dir)
logging.debug("%s cache directory is %s.", self._id, self.cache_dir)

def _save_json(self, data, filename):
"""Save a dictionary to a JSON file."""
Expand Down Expand Up @@ -174,10 +179,9 @@ def run(self, action_step: ActionStep) -> str:
"""
if action_step.action_type == "set":
return self.set_state(action_step)
elif action_step.action_type == "get":
if action_step.action_type == "get":
return self.get_state(action_step)
else:
raise ValueError(f"Invalid action type: {action_step.action_type}")
raise ValueError(f"Invalid action type: {action_step.action_type}")


def create_task_queue(
Expand All @@ -195,7 +199,7 @@ def create_task_queue(
A TaskQueue object with the provided action steps.
"""
if action_data is None:
ValueError("Action data cannot be None.")
raise ValueError("Action data cannot be None.")

# Convert the input data to ActionStep objects
action_steps = [
Expand All @@ -211,7 +215,7 @@ def create_task_queue(
return task_queue


def get_task_master_examples(id: int = 0):
def get_task_master_examples(example_id: int = 0):
"""Get the example task queue data."""
examples = [
[
Expand All @@ -227,7 +231,7 @@ def get_task_master_examples(id: int = 0):
"action_argument": "Get today's weather."},
]
]
if id not in range(0, len(examples)):
raise ValueError(f"Invalid example ID: {id}")
if example_id not in range(0, len(examples)):
raise ValueError(f"Invalid example ID: {example_id}")

return create_task_queue(action_data=examples[id], is_example=True).json()
return create_task_queue(action_data=examples[example_id], is_example=True).json()
Loading

0 comments on commit 576f721

Please sign in to comment.