mirror of
https://github.com/tcsenpai/delAIMain.git
synced 2025-06-02 16:30:03 +00:00
Initial commit
This commit is contained in:
commit
d1f16eb40d
22
.gitignore
vendored
Normal file
22
.gitignore
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
### AL ###
|
||||
#Template for AL projects for Dynamics 365 Business Central
|
||||
#launch.json folder
|
||||
.vscode/
|
||||
#Cache folder
|
||||
.alcache/
|
||||
#Symbols folder
|
||||
.alpackages/
|
||||
#Snapshots folder
|
||||
.snapshots/
|
||||
#Testing Output folder
|
||||
.output/
|
||||
#Extension App-file
|
||||
*.app
|
||||
#Rapid Application Development File
|
||||
rad.json
|
||||
#Translation Base-file
|
||||
*.g.xlf
|
||||
#License-file
|
||||
*.flf
|
||||
#Test results file
|
||||
TestResults.xml
|
21
LICENSE
Normal file
21
LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2023 Blockdrops LLC
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
91
README.md
Normal file
91
README.md
Normal file
@ -0,0 +1,91 @@
|
||||
# Delaimain
|
||||
|
||||
Delaimain is an AI-Powered personal assistant that runs on your CPU (no GPU needed!) and locally (no OpenAI API keys needed!). It is designed to be flexible and extensible, allowing it to be customized for specific needs. One of the main features of Delaimain is the modular architecture: you can create modules for Delamain to run using basically any language installed on your computer.
|
||||
|
||||
This repository contains the source code for Delaimain. It includes the core components of the assistant, as well as example plugins and language support.
|
||||
|
||||
## Requirements and Models
|
||||
|
||||
This software with the default model has been tested against a 14GB RAM (heh, it's a laptop) Ryzen 7730U (yeah, it's a laptop) machine running Kubuntu 23.10 .
|
||||
Theoretically, if you can run gpt4all client on your computer you can also run Delaimain as it uses gpt4all python bindings.
|
||||
|
||||
You are free to change the model in config.json using any model supported by gpt4all. As an additional tip, many external models like the ones available on huggingface work like a charm.
|
||||
|
||||
## Getting Started
|
||||
|
||||
To get started using Delaimain, follow these steps:
|
||||
|
||||
1. Clone this repository to your local machine.
|
||||
2. Install the required dependencies by running `pip install -r requirements.txt` in the root directory of the repository.
|
||||
3. Start the assistant by running `python delaMain.py` in the root directory of the repository.
|
||||
4. Chat with the assistant or use one of the configured commands
|
||||
|
||||
## Language Support
|
||||
|
||||
Delaimain supports a wide range of programming languages.
|
||||
Besides the growing officially supported languages, Delamain will fallback to a standalone binary if it detects an unsupported language.
|
||||
For example, if a language named "xyz" is installed and is runnable through "xyz script.x", Delaimain is able to execute it anyway.
|
||||
Other languages (like nodeJS which is officially supported) requires a proper configuration as their binary does not correspond to their names.
|
||||
|
||||
## Scripting
|
||||
|
||||
By following the examples in modules.json and the linked modules in scripts/, it is easy to create a new module for your Delaimain.
|
||||
Let's say you want to execute a script that shutdown your Linux machine:
|
||||
|
||||
sudo shutdown now
|
||||
|
||||
While being quite simple, this script is useful to show how Delaimain can be configured.
|
||||
Let's save this script as shutdown.sh in scripts/ and let's open modules.json.
|
||||
We now want to add our script in response to a command. Let's add:
|
||||
|
||||
{
|
||||
"goBed": {
|
||||
"script": "shutdown.sh",
|
||||
"type": "sh",
|
||||
"description": "Shutting down your computer"
|
||||
}
|
||||
}
|
||||
|
||||
After reloading Delaimain, you will be able to write 'goBed' to see your script executed.
|
||||
|
||||
Of course you are encouraged to hack and change everything in Delaimain so to have your perfect assistant.
|
||||
|
||||
## Optional features
|
||||
|
||||
The following features are disabled by default and can be enabled by setting the related flag in config.json .
|
||||
Please note that experimental features can lead to unexpected behaviour. Report bugs and feedback please.
|
||||
|
||||
### Face
|
||||
|
||||
By setting the parameter 'face' to 'true', Delaimain will spawn a little window representing a (work in progess) visual GIF animation of Delaimain itself. By replacing the corresponding GIF in your code you can give Delaimain any aspect you want.
|
||||
|
||||
### TTS
|
||||
|
||||
The TTS module is currently not working and is a work in progress.
|
||||
|
||||
## Future features
|
||||
|
||||
The following features are ordered by priority but they can change anytime.
|
||||
Contributions to this features are welcome and prioritized: please open an issue to notify the others of your contribution.
|
||||
Feedback is greatly appreciated.
|
||||
|
||||
- [ ] Working TTS engine (feel free to change the library used)
|
||||
- [ ] Smoother face.py engine and management (now is an horrible subprocess)
|
||||
- [ ] CLI Interface (using https://www.textualize.io)
|
||||
- [ ] Microphone support (privacy oriented of course)
|
||||
- [ ] Consequently, hotword support using or on the model of https://thalhammer.github.io/snowman/ or any other alternative that works
|
||||
- [ ] face.py animations
|
||||
- [ ] Better overall user experience
|
||||
|
||||
## Contributing
|
||||
|
||||
We welcome contributions from the community to help make Delaimain even better. If you would like to contribute, please follow these steps:
|
||||
|
||||
1. Fork this repository.
|
||||
2. Create a new branch for your changes.
|
||||
3. Make your changes and ensure they pass all tests.
|
||||
4. Submit a pull request to merge your changes into the main repository.
|
||||
|
||||
## License
|
||||
|
||||
Delaimain is licensed under the MIT License. See the [LICENSE](LICENSE) file for more information.
|
BIN
base_small.gif
Normal file
BIN
base_small.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.1 MiB |
BIN
call_talking.gif
Normal file
BIN
call_talking.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.0 MiB |
6
config.json
Normal file
6
config.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"tts": false,
|
||||
"face": false,
|
||||
"model": "mistral-7b-openorca.Q4_0.gguf",
|
||||
"supported_languages": ["python", "tsx", "tsc", "perl", "php", "ruby"]
|
||||
}
|
141
delaMain.py
Normal file
141
delaMain.py
Normal file
@ -0,0 +1,141 @@
|
||||
import json
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
import pyttsx3
|
||||
from gpt4all import GPT4All
|
||||
|
||||
engine = pyttsx3.init() # FIXME aplay error?
|
||||
|
||||
|
||||
# ANCHOR Configuration and pre-flight globals
|
||||
config = None
|
||||
with open("config.json", "r") as conf:
|
||||
config = json.load(conf)
|
||||
print("Loaded configuration:")
|
||||
for key, value in config.items():
|
||||
print(key, value)
|
||||
config["face_process"] = None
|
||||
|
||||
model = GPT4All(model_name=config["model"])
|
||||
|
||||
# ANCHOR Modules loading
|
||||
with open("modules.json", "r") as f:
|
||||
modules = json.load(f)
|
||||
print("Loaded configuration:")
|
||||
for key, value in modules.items():
|
||||
print(key, value)
|
||||
|
||||
|
||||
# NOTE Chat handler: this is the main loop for the program to work
|
||||
def chat_session():
|
||||
global tts
|
||||
print(".:: Delamain is starting ::.")
|
||||
with model.chat_session():
|
||||
# Endless chat session with ctrl-c interrupt
|
||||
try:
|
||||
# Being polite is important
|
||||
output = model.generate(prompt="Hello!")
|
||||
print("Delamain > " + output)
|
||||
while True:
|
||||
text = input("> ")
|
||||
# Custom modules
|
||||
is_done = view_modules(text)
|
||||
if is_done:
|
||||
continue
|
||||
# SECTION Built in modules are defined here
|
||||
# Also 'exit' can be used to exit the chat session
|
||||
if text == "exit":
|
||||
print("Exiting...")
|
||||
do_exit()
|
||||
elif text.startswith("complete the following: "):
|
||||
to_complete = text.split("complete the following: ")[1]
|
||||
print("Completing message: " + to_complete)
|
||||
output = complete(to_complete)
|
||||
else:
|
||||
# Here delamain generates its own message if nothing has been requested above
|
||||
output = model.generate(text, max_tokens=1024)
|
||||
# Is reply time!
|
||||
print("Delamain >" + output)
|
||||
if config["tts"]:
|
||||
engine.say(output)
|
||||
engine.runAndWait()
|
||||
except KeyboardInterrupt:
|
||||
print("Exiting...")
|
||||
do_exit()
|
||||
|
||||
|
||||
# INFO Simple completion module
|
||||
def complete(text):
|
||||
output = model.generate(text, max_tokens=20)
|
||||
return output
|
||||
|
||||
|
||||
# INFO Priority to custom modules
|
||||
def view_modules(text):
|
||||
# SECTION Modules are defined here
|
||||
global modules
|
||||
is_done = False
|
||||
for key, value in modules.items():
|
||||
if text.startswith(key):
|
||||
is_done = True
|
||||
arguments = text.split(key)[1]
|
||||
if arguments == "":
|
||||
print("Warning: no arguments given for module: " + key)
|
||||
script = value["script"]
|
||||
typeOf = value["type"]
|
||||
description = value["description"]
|
||||
print("Executing script: " + description)
|
||||
dispatcher(script, typeOf, arguments)
|
||||
return is_done
|
||||
|
||||
|
||||
# INFO Heavy work is done here
|
||||
def dispatcher(script, typeOf, arguments):
|
||||
global config
|
||||
cmd = ""
|
||||
# NOTE We avoid defining types that have the same syntax as the invocation module
|
||||
if typeOf == "javascript":
|
||||
cmd = "node "
|
||||
else:
|
||||
supported_languages = config["supported_languages"]
|
||||
if typeOf not in supported_languages:
|
||||
print("Language not officially supported: " + typeOf)
|
||||
print("Trying to append it like a standalone binary: " + typeOf)
|
||||
cmd = typeOf + " "
|
||||
# Finding the script
|
||||
path = os.path.dirname(os.path.realpath(__file__)) + "/scripts/" + script
|
||||
if not os.path.isfile(path):
|
||||
print("Script not found: " + script)
|
||||
return
|
||||
# Executing the script
|
||||
print("Executing script: " + cmd + path + " " + arguments)
|
||||
proc = subprocess.run(
|
||||
cmd + path + " " + arguments,
|
||||
# TODO Try to remove this shell=True to improve security
|
||||
# trunk-ignore(bandit/B602)
|
||||
shell=True,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT,
|
||||
)
|
||||
out = proc.stdout.decode("utf-8")
|
||||
print(out)
|
||||
if config["tts"]:
|
||||
engine.say(out)
|
||||
engine.runAndWait()
|
||||
|
||||
|
||||
# Terminating gracefully
|
||||
def do_exit():
|
||||
global config
|
||||
if config["face_process"]:
|
||||
config["face_process"].terminate()
|
||||
exit()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Starting face in background
|
||||
if config["face"]:
|
||||
config["face_process"] = subprocess.Popen(["python3", "face.py"])
|
||||
# Chatting session
|
||||
chat_session()
|
25
face.py
Normal file
25
face.py
Normal file
@ -0,0 +1,25 @@
|
||||
import pyglet
|
||||
|
||||
# Replace 'your_gif_file.gif' with the path to your GIF file
|
||||
gif_path = 'base_small.gif'
|
||||
|
||||
# Create a window
|
||||
window = pyglet.window.Window()
|
||||
window.set_exclusive_mouse(True)
|
||||
|
||||
# Load the GIF
|
||||
animation = pyglet.image.load_animation(gif_path)
|
||||
sprite = pyglet.sprite.Sprite(animation)
|
||||
|
||||
# Set the window size to match the GIF
|
||||
window.width = 180
|
||||
window.height = 180
|
||||
|
||||
@window.event
|
||||
def on_draw():
|
||||
window.clear()
|
||||
window.set_caption = "Delamain"
|
||||
sprite.draw()
|
||||
|
||||
# Start the application
|
||||
pyglet.app.run()
|
1
scripts/nodeVersion.js
Normal file
1
scripts/nodeVersion.js
Normal file
@ -0,0 +1 @@
|
||||
console.log(process.version)
|
Loading…
x
Reference in New Issue
Block a user