Merge branch 'dev' of https://manufactorum.kanium.org/Kanium-PUBLIC/KaniumCogs into dev
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
from abc import ABC, abstractmethod
|
||||
from enum import Enum
|
||||
from discord import Message
|
||||
from discord import Message, Attachment
|
||||
|
||||
|
||||
class IClientMessage(ABC):
|
||||
@@ -18,56 +18,59 @@ class ClientMessage(IClientMessage):
|
||||
|
||||
class IMessageBuilder(ABC):
|
||||
@abstractmethod
|
||||
def __init__(self, raw_message: object):
|
||||
self.raw_message = raw_message
|
||||
self.message: IClientMessage = None
|
||||
|
||||
def create_message(self) -> ClientMessage:
|
||||
self.set_content() \
|
||||
.set_author_name() \
|
||||
.set_image_urls()
|
||||
return self.message
|
||||
|
||||
@abstractmethod
|
||||
def set_content(self):
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def set_author_name(self):
|
||||
def set_content(self, value: str):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def set_image_urls(self):
|
||||
def set_author_name(self, value: str):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def set_image_urls(self, value: list[str]):
|
||||
pass
|
||||
|
||||
|
||||
class DiscordMessageBuilder(IMessageBuilder):
|
||||
def __init__(self, raw_message: Message):
|
||||
self.raw_message = raw_message
|
||||
self.message = ClientMessage()
|
||||
def __init__(self, message: IClientMessage):
|
||||
self.message = message
|
||||
|
||||
def create_message(self) -> ClientMessage:
|
||||
return super().create_message()
|
||||
|
||||
def set_author_name(self) -> 'DiscordMessageBuilder':
|
||||
self.message.author_name = self.raw_message.author.name
|
||||
def set_author_name(self, value: str):
|
||||
self.message.author_name = value
|
||||
return self
|
||||
|
||||
def set_content(self) -> 'DiscordMessageBuilder':
|
||||
self.message.content = self.raw_message.content
|
||||
def set_content(self, value: str):
|
||||
self.message.content = value
|
||||
return self
|
||||
|
||||
def set_image_urls(self) -> 'DiscordMessageBuilder':
|
||||
self.message.image_urls = [
|
||||
i.url
|
||||
for i in self.raw_message.attachments
|
||||
if i.content_type in ('image/jpeg', 'image/png', 'image/webp', 'image/gif')
|
||||
]
|
||||
def set_image_urls(self, value: list[str]):
|
||||
self.message.image_urls = value
|
||||
return self
|
||||
|
||||
|
||||
class MessengerTypes(Enum):
|
||||
DISCORD = DiscordMessageBuilder
|
||||
class IMessageAdapter(ABC):
|
||||
@abstractmethod
|
||||
def create_message(self, message: object) -> IClientMessage:
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def validate_image_urls(urls_list: list[Attachment]) -> list[str]:
|
||||
supported_image_formats = ('image/jpeg', 'image/png', 'image/webp', 'image/gif')
|
||||
return [i_attachment.url for i_attachment in urls_list if i_attachment.content_type in supported_image_formats]
|
||||
|
||||
|
||||
class DiscordMessageAdapter(IMessageAdapter):
|
||||
def create_message(self, message: Message) -> IClientMessage:
|
||||
client_message = ClientMessage()
|
||||
message_builder = DiscordMessageBuilder(client_message)
|
||||
urls_list = self.validate_image_urls(message.attachments)
|
||||
message_builder.set_content(message.content)\
|
||||
.set_author_name(message.author.name)\
|
||||
.set_image_urls(urls_list)
|
||||
return client_message
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
import asyncio
|
||||
from discord import Message
|
||||
from reginaldCog.messenger_clients.messenger_client import ClientMessage, DiscordMessageAdapter as MessengerDiscordAdapter
|
||||
from reginaldCog.llm_clients.llm_client import LMMClientType, MessengerClientMessageAdapter
|
||||
|
||||
|
||||
class MessageService:
|
||||
def __init__(self, message: Message, llm_client: LMMClientType = LMMClientType.OPENAI):
|
||||
self.message = message
|
||||
self.llm_client = llm_client
|
||||
|
||||
async def get_llm_response(self) -> str:
|
||||
# Adapt discord.Message to ClientMessage domain object
|
||||
client_message: ClientMessage = MessengerDiscordAdapter().create_message(self.message)
|
||||
|
||||
# Create prompt and prompt builder for this LLM client
|
||||
prompt = self.llm_client.value.prompt_class()
|
||||
prompt_builder = self.llm_client.value.prompt_builder_class(prompt)
|
||||
|
||||
# Adapt the messenger client message into LLM message and add it to prompt
|
||||
llm_message = MessengerClientMessageAdapter(client_message, self.llm_client).to_message()
|
||||
prompt_builder.add_message(llm_message)
|
||||
|
||||
# Call the LLM client; run in executor if method is blocking sync
|
||||
llm_client_instance = self.llm_client.value()
|
||||
|
||||
loop = asyncio.get_running_loop()
|
||||
# Assuming get_response is blocking - run in executor:
|
||||
response = await loop.run_in_executor(None, llm_client_instance.get_response, prompt)
|
||||
|
||||
# Extract plain text from the response (assuming OpenAIResponseAdapter is present)
|
||||
from reginaldCog.llm_clients.llm_client import OpenAIResponseAdapter
|
||||
|
||||
response_adapter = OpenAIResponseAdapter(response)
|
||||
message_obj = response_adapter.to_message()
|
||||
|
||||
# Concatenate all textual outputs for sending to Discord
|
||||
texts = [item.get("text", "") for item in message_obj.content.content_items if item.get("type") == "output_text"]
|
||||
return "\n".join(texts) if texts else "Sorry, no response generated."
|
||||
Reference in New Issue
Block a user