added backend which maintains ai instances;
added frontend as control panel
This commit is contained in:
68
backend/ai/services/AiInstance.py
Normal file
68
backend/ai/services/AiInstance.py
Normal file
@@ -0,0 +1,68 @@
|
||||
from typing import AnyStr
|
||||
|
||||
from .DcClient import DcClient
|
||||
from ..ais.AiBase import AiBase
|
||||
from ..ais.QwenAi import QwenAi
|
||||
from ..models import AiConfig
|
||||
|
||||
|
||||
class DiscordStatus:
|
||||
_instance: any
|
||||
_client: DcClient
|
||||
online: bool = False
|
||||
react_to_chat: bool = False
|
||||
|
||||
def __init__(self, instance):
|
||||
self._instance = instance
|
||||
self._client = DcClient(instance)
|
||||
|
||||
def set_online(self, online: bool):
|
||||
if online and not self.online:
|
||||
self._client.connect()
|
||||
elif not online and self.online:
|
||||
self._client.disconnect()
|
||||
else:
|
||||
return
|
||||
self.online = online
|
||||
|
||||
def set_react_to_chat(self, react_to_chat: bool):
|
||||
self.react_to_chat = react_to_chat
|
||||
|
||||
def __del__(self):
|
||||
self.set_online(False)
|
||||
|
||||
|
||||
class AiInstance:
|
||||
_bot: AiBase | None = None
|
||||
configuration: AiConfig
|
||||
discord: DiscordStatus
|
||||
messages = []
|
||||
|
||||
def __init__(self, configuration: AiConfig):
|
||||
print('Initializing AiInstance ' + configuration.name)
|
||||
self.configuration = configuration
|
||||
self.discord = DiscordStatus(self)
|
||||
|
||||
def endure_loaded(self):
|
||||
if self._bot is None:
|
||||
self._bot = QwenAi(self.configuration.model_id_or_path)
|
||||
|
||||
def endure_unloaded(self):
|
||||
if self._bot is not None:
|
||||
del self._bot
|
||||
self._bot = None
|
||||
|
||||
def chat_text(self, user: AnyStr, text: AnyStr):
|
||||
self.endure_loaded()
|
||||
self.messages.append({'role': 'user', 'name': user, 'content': text})
|
||||
self.messages = self._bot.generate(self.messages)
|
||||
return self.messages[-1]
|
||||
|
||||
def chat_conversation(self, conversation):
|
||||
self.endure_loaded()
|
||||
return self._bot.generate(conversation)
|
||||
|
||||
def __del__(self):
|
||||
print('Destructing AiInstance ' + self.configuration.name)
|
||||
del self._bot
|
||||
del self.discord
|
||||
35
backend/ai/services/AiService.py
Normal file
35
backend/ai/services/AiService.py
Normal file
@@ -0,0 +1,35 @@
|
||||
from .AiInstance import AiInstance
|
||||
from ..models import AiConfig
|
||||
|
||||
|
||||
class AiService:
|
||||
instances: [AiInstance] = []
|
||||
|
||||
# Singleton
|
||||
# def __new__(cls):
|
||||
# if not hasattr(cls, 'instance'):
|
||||
# cls.instance = super(AiService, cls).__new__(cls)
|
||||
# return cls.instance
|
||||
|
||||
def __init__(self):
|
||||
print('Initializing AiService')
|
||||
|
||||
def get_configurations(self) -> [AiConfig]:
|
||||
return AiConfig.objects.filter()
|
||||
|
||||
def get_instances(self) -> [AiInstance]:
|
||||
self.__ensure_instances_inited__()
|
||||
return self.instances
|
||||
|
||||
def get_instance(self, name: str) -> AiInstance:
|
||||
return [i for i in self.get_instances() if i.configuration.name == name][0]
|
||||
|
||||
def __ensure_instances_inited__(self):
|
||||
for config in self.get_configurations():
|
||||
if len([i for i in self.instances if i.configuration.name == config.name]) == 0:
|
||||
self.instances.append(AiInstance(config))
|
||||
|
||||
def __del__(self):
|
||||
print('Destructing AiService')
|
||||
for instance in self.instances:
|
||||
del instance
|
||||
49
backend/ai/services/DcClient.py
Normal file
49
backend/ai/services/DcClient.py
Normal file
@@ -0,0 +1,49 @@
|
||||
from threading import Thread
|
||||
|
||||
from discord import Intents, Client
|
||||
|
||||
from . import AiInstance
|
||||
|
||||
|
||||
class DcClient:
|
||||
_intents: Intents
|
||||
_discord_client: Client
|
||||
|
||||
_ai_instance: AiInstance
|
||||
|
||||
def __init__(self, _ai_instance: AiInstance):
|
||||
self._ai_instance = _ai_instance
|
||||
|
||||
self._intents = Intents.default()
|
||||
self._intents.message_content = True
|
||||
self._discord_client = Client(intents=self._intents)
|
||||
|
||||
@self._discord_client.event
|
||||
async def on_ready():
|
||||
print(f'We have logged in as {self._discord_client.user}')
|
||||
|
||||
@self._discord_client.event
|
||||
async def on_message(message):
|
||||
if not self._ai_instance.discord.react_to_chat:
|
||||
return None
|
||||
|
||||
if message.author == self._discord_client.user:
|
||||
return
|
||||
|
||||
if message.content.isspace():
|
||||
await message.channel.send('### Empty message')
|
||||
return
|
||||
|
||||
response = self._ai_instance.chat_text(message.author.name, message.content)
|
||||
if response is not None:
|
||||
await message.channel.send(response['content'])
|
||||
|
||||
def connect(self):
|
||||
def start():
|
||||
self._discord_client.run(self._ai_instance.configuration.discord_token)
|
||||
|
||||
thread = Thread(target=start)
|
||||
thread.start()
|
||||
|
||||
def disconnect(self):
|
||||
self._discord_client.close()
|
||||
Reference in New Issue
Block a user