diff --git a/README.md b/README.md index b122012..5e0971d 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ Terminal-based version at [ollamarama](https://github.com/h1ddenpr0cess20/ollama ## Setup -Install and familiarize yourself with [Ollama](https://ollama.ai/), make sure you can run offline LLMs, etc. +Install and familiarize yourself with [Ollama](https://ollama.ai/), make sure you can run local LLMs, etc. You can install and update it with this command: ``` @@ -17,7 +17,7 @@ curl https://ollama.ai/install.sh | sh ``` -Once it's all set up, you'll need to [download the models](https://ollama.ai/library) you want to use. You can play with the available ones and see what works best for you. Add those to the models.json file. If you want to use the ones I've included, just run ollama pull _modelname_ for each. You can skip this part, and they should download when the model is switched, but the response will be delayed until it finishes downloading. +Once it's all set up, you'll need to [download the models](https://ollama.ai/library) you want to use. You can play with the available ones and see what works best for you. Add those to the config.json file. If you want to use the ones I've included, just run ollama pull _modelname_ for each. You can skip this part, and they should download when the model is switched, but the response will be delayed until it finishes downloading. You'll also need to install matrix-nio and litellm @@ -27,10 +27,10 @@ pip3 install matrix-nio litellm Set up a [Matrix account](https://app.element.io/) for your bot. You'll need the server, username and password. -Plug those into the appropriate variables in the launcher.py file. +Plug those into the appropriate variables in the config.json file. ``` -python3 launcher.py +python3 ollamarama.py ``` ## Use diff --git a/config.json b/config.json new file mode 100644 index 0000000..3b4af61 --- /dev/null +++ b/config.json @@ -0,0 +1,36 @@ +[ + { + "llama3": "ollama/llama3", + "wizardlm2": "ollama/wizardlm2", + "phi3": "ollama/phi3", + "zephyr": "ollama/zephyr", + "solar": "ollama/solar", + "mistral": "ollama/mistral", + "codellama": "ollama/codellama", + "dolphin-mistral": "ollama/dolphin-mistral", + "dolphin-llama3": "dolphin-llama3", + "gemma": "ollama/gemma", + "codegemma": "ollama/codegemma" + }, + { + "server": "https://matrix.org", + "username": "@USERNAME:SERVER.TLD", + "password": "PASSWORD", + + "channels": + [ + "#channel1:SERVER.TLD", + "#channel2:SERVER.TLD", + "#channel3:SERVER.TLD", + "!ExAmPleOfApRivAtErOoM:SERVER.TLD" + ], + + "personality": "a helpful and thorough AI assistant who provides accurate and detailed answers without being too verbose", + "admins": + [ + "admin_nick1", + "admin_nick2" + ] + + } +] \ No newline at end of file diff --git a/help.txt b/help.txt new file mode 100644 index 0000000..d091e88 --- /dev/null +++ b/help.txt @@ -0,0 +1,57 @@ +.ai or botname: + Basic usage. + Personality is preset by bot operator. + +.x + This allows you to talk to another user's chat history. + is the display name of the user whose history you want to use + +.persona + Changes the personality. It can be a character, personality type, object, idea. + +.custom + Allows use of a custom system prompt instead of the roleplaying prompt + +.reset + Reset to preset personality + +.stock + Remove personality and reset to standard model settings + + +Available at https://github.com/h1ddenpr0cess20/ollamarama-matrix + +~~~ + +.admins + List of users authorized to use these commands + +.models + List available models + +.model + Change the model + +.temperature <#> + Set temperature value between 0 and 1. To reset to default, type reset instead of a number. (bot owner only) + +.top_p <#> + Set top_p value between 0 and 1. To reset to default, type reset instead of a number. (bot owner only) + +.repeat_penalty <#> + Set repeat_penalty between 0 and 2. To reset to default, type reset instead of a number. (bot owner only) + +.clear + Reset bot for everyone (bot owner only) + +.gpersona + Change default global personality (bot owner only) + +.gpersona reset + Reset global personality (bot owner only) + +.auth + Add an admin (bot owner only) + +.deauth + Remove an admin (bot owner only) \ No newline at end of file diff --git a/launcher.py b/launcher.py deleted file mode 100644 index 9d4ce2e..0000000 --- a/launcher.py +++ /dev/null @@ -1,24 +0,0 @@ -import asyncio -from ollamarama import ollamarama - - -server = "https://matrix.org" #change if using different homeserver -username = "@USERNAME:SERVER.TLD" -password = "PASSWORD" - -channels = ["#channel1:SERVER.TLD", - "#channel2:SERVER.TLD", - "#channel3:SERVER.TLD", - "!ExAmPleOfApRivAtErOoM:SERVER.TLD", ] #enter the channels you want it to join here - - -personality = "a helpful and thorough AI assistant who provides accurate and detailed answers without being too verbose" - -#users authorized to use special commands -admins = ['BOTOWNER',] - -# create bot instance -bot = ollamarama(server, username, password, channels, personality, admins) - -# run main function loop -asyncio.get_event_loop().run_until_complete(bot.main()) \ No newline at end of file diff --git a/ollamarama.py b/ollamarama.py index 865c546..caedf07 100644 --- a/ollamarama.py +++ b/ollamarama.py @@ -5,11 +5,11 @@ Author: Dustin Whyte Date: December 2023 """ -import asyncio from nio import AsyncClient, MatrixRoom, RoomMessageText -import datetime from litellm import completion import json +import datetime +import asyncio class ollamarama: def __init__(self, server, username, password, channels, personality, admins): @@ -29,15 +29,14 @@ class ollamarama: self.messages = {} #prompt parts - self.prompt = ("you are ", ". speak in the first person and never break character.") + self.prompt = ("you are ", ". roleplay and speak in the first person and never break character.") #open models.json - with open("models.json", "r") as f: - self.models = json.load(f) + with open("config.json", "r") as f: + self.models = json.load(f)[0] f.close() - #set model - self.default_model = self.models['zephyr'] + self.default_model = self.models['llama3'] self.model = self.default_model #no idea if optimal, change if necessary @@ -47,7 +46,12 @@ class ollamarama: #authorized users for changing models self.admins = admins - + + #load help menu + with open("help.txt", "r") as f: + self.help, self.help_admin = f.read().split("~~~") + f.close() + # get the display name for a user async def display_name(self, user): @@ -59,7 +63,7 @@ class ollamarama: # simplifies sending messages to the channel async def send_message(self, channel, message): - await self.client.room_send( + await self.client.room_send( room_id=channel, message_type="m.room.message", content={"msgtype": "m.text", "body": message}, @@ -148,11 +152,10 @@ class ollamarama: await self.messages[channel][sender].clear() except: pass - await self.add_history("system", channel, sender, prompt) - + await self.add_history("system", channel, sender, prompt) + # tracks the messages in channels async def message_callback(self, room: MatrixRoom, event: RoomMessageText): - # Main bot functionality if isinstance(event, RoomMessageText): # convert timestamp @@ -175,8 +178,8 @@ class ollamarama: #model switching if message.startswith(".model"): if message == ".models": - await self.send_message(room_id, f'''Current model: {self.model.removeprefix('ollama/')} -Available models: {', '.join(sorted(list(self.models)))}''') + current_model = f"Current model: {self.model.removeprefix('ollama/')}\nAvailable models: {', '.join(sorted(list(self.models)))}" + await self.send_message(room_id, current_model) if message.startswith(".model "): m = message.split(" ", 1)[1] @@ -346,71 +349,9 @@ Available models: {', '.join(sorted(list(self.models)))}''') # help menu if message.startswith(".help"): - await self.send_message(room_id, -f'''{self.bot_id}, an AI chatbot. - -.ai or {self.bot_id}: - Basic usage. - Personality is preset by bot operator. - -.x - This allows you to talk to another user's chat history. - is the display name of the user whose history you want to use - -.persona - Changes the personality. It can be a character, personality type, object, idea. - -.custom - Allows use of a custom system prompt instead of the roleplaying prompt - -.reset - Reset to preset personality - -.stock - Remove personality and reset to standard model settings - - -Available at https://github.com/h1ddenpr0cess20/ollamarama-matrix - -''') + await self.send_message(room_id, self.help) if sender_display in self.admins: - await self.send_message(room_id, '''Admin commands: - -.admins - List of users authorized to use these commands - -.models - List available models - -.model - Change the model - -.temperature <#> - Set temperature value between 0 and 1. To reset to default, type reset instead of a number. (bot owner only) - -.top_p <#> - Set top_p value between 0 and 1. To reset to default, type reset instead of a number. (bot owner only) - -.repeat_penalty <#> - Set repeat_penalty between 0 and 2. To reset to default, type reset instead of a number. (bot owner only) - -.clear - Reset bot for everyone (bot owner only) - -.gpersona - Change default global personality (bot owner only) - -.gpersona reset - Reset global personality (bot owner only) - -.auth - Add an admin (bot owner only) - -.deauth - Remove an admin (bot owner only) - -''') - + await self.send_message(room_id, self.help_admin) # main loop async def main(self): @@ -431,24 +372,16 @@ Available at https://github.com/h1ddenpr0cess20/ollamarama-matrix # start listening for messages self.client.add_event_callback(self.message_callback, RoomMessageText) - + await self.client.sync_forever(timeout=30000) if __name__ == "__main__": + #load config file + with open("config.json", "r") as f: + config = json.load(f) + f.close() - server = "https://matrix.org" #change if using different homeserver - username = "@USERNAME:SERVER.TLD" - password = "PASSWORD" - - channels = ["#channel1:SERVER.TLD", - "#channel2:SERVER.TLD", - "#channel3:SERVER.TLD", - "!ExAmPleOfApRivAtErOoM:SERVER.TLD", ] #enter the channels you want it to join here - - personality = "a helpful and thorough AI assistant who provides accurate and detailed answers without being too verbose" - - #list of authorized users for admin commands - admins = ['admin_nick1', 'admin_nick2',] + server, username, password, channels, personality, admins = config[1].values() # create bot instance bot = ollamarama(server, username, password, channels, personality, admins)