diff --git a/ai_test.py b/ai_test.py index 0c5ebf9..2bf8968 100644 --- a/ai_test.py +++ b/ai_test.py @@ -2,6 +2,7 @@ import asyncio from groq import AsyncGroq +from src.core.common.promt import ROLE, ANALYTIC_PROMT from src.core.settings.base import settings # Убедитесь, что переменная окружения GROQ_API_KEY установлена @@ -11,23 +12,14 @@ client = AsyncGroq( ) -async def create_request(): - +async def create_request_ai(messages: list): chat_completion = await client.chat.completions.create( - messages=[ - { - "role": "system", - "content": "you are a helpful assistant." - }, - { - "role": "user", - "content": "Explain the importance of fast language models", - } - ], + messages=messages, model="llama-3.3-70b-versatile", + temperature=2, ) print(chat_completion.choices[0].message.content) -if __name__ == "__main__": - asyncio.run(create_request()) \ No newline at end of file +# if __name__ == "__main__": +# asyncio.run(create_request()) \ No newline at end of file diff --git a/poetry.lock b/poetry.lock index 0d497fb..e0663e3 100644 --- a/poetry.lock +++ b/poetry.lock @@ -34,6 +34,19 @@ doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21)"] trio = ["trio (>=0.26.1)"] +[[package]] +name = "async-timeout" +version = "5.0.1" +description = "Timeout context manager for asyncio programs" +optional = false +python-versions = ">=3.8" +groups = ["main"] +markers = "python_full_version < \"3.11.3\"" +files = [ + {file = "async_timeout-5.0.1-py3-none-any.whl", hash = "sha256:39e3809566ff85354557ec2398b55e096c8364bacac9405a7a1fa429e77fe76c"}, + {file = "async_timeout-5.0.1.tar.gz", hash = "sha256:d9321a7a3d5a6a5e187e824d2fa0793ce379a202935782d555d6e9d2735677d3"}, +] + [[package]] name = "certifi" version = "2024.12.14" @@ -466,6 +479,25 @@ files = [ [package.extras] cli = ["click (>=5.0)"] +[[package]] +name = "redis" +version = "5.2.1" +description = "Python client for Redis database and key-value store" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "redis-5.2.1-py3-none-any.whl", hash = "sha256:ee7e1056b9aea0f04c6c2ed59452947f34c4940ee025f5dd83e6a6418b6989e4"}, + {file = "redis-5.2.1.tar.gz", hash = "sha256:16f2e22dff21d5125e8481515e386711a34cbec50f0e44413dd7d9c060a54e0f"}, +] + +[package.dependencies] +async-timeout = {version = ">=4.0.3", markers = "python_full_version < \"3.11.3\""} + +[package.extras] +hiredis = ["hiredis (>=3.0.0)"] +ocsp = ["cryptography (>=36.0.1)", "pyopenssl (==23.2.1)", "requests (>=2.31.0)"] + [[package]] name = "sniffio" version = "1.3.1" @@ -655,4 +687,4 @@ files = [ [metadata] lock-version = "2.1" python-versions = ">=3.11, <4.0" -content-hash = "b2defdffca356c862f69d5256e5602faa6f263c4c58f57090bb58fa2dccdbaeb" +content-hash = "c9de7a98768d02152241f4e8000d6186de1c0059ba9dba65dca76ee5a6b60ee2" diff --git a/pyproject.toml b/pyproject.toml index d78cb2d..cb33a37 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,7 +14,8 @@ dependencies = [ "httpx (>=0.28.1,<0.29.0)", "groq (>=0.15.0,<0.16.0)", "sqlalchemy (>=2.0.37,<3.0.0)", - "pydantic-settings (>=2.7.1,<3.0.0)" + "pydantic-settings (>=2.7.1,<3.0.0)", + "redis (>=5.2.1,<6.0.0)" ] diff --git a/src/advatroniks.session-journal b/src/advatroniks.session-journal new file mode 100644 index 0000000..8e006a4 Binary files /dev/null and b/src/advatroniks.session-journal differ diff --git a/src/core/common/constants.py b/src/core/common/constants.py index a0379bc..c82d8ed 100644 --- a/src/core/common/constants.py +++ b/src/core/common/constants.py @@ -1,7 +1,7 @@ from enum import Enum from pathlib import Path -PATH_TO_BASE_FOLDER = Path(__file__).resolve().parents[1] +PATH_TO_BASE_FOLDER = Path(__file__).resolve().parents[3] LOG_DEFAULT_FORMAT = "[%(asctime)s.%(msecs)03d] %(module)10s:%(lineno)-3d %(levelname)-7s - %(message)s" diff --git a/src/core/common/promt.py b/src/core/common/promt.py new file mode 100644 index 0000000..6d5adc9 --- /dev/null +++ b/src/core/common/promt.py @@ -0,0 +1,58 @@ +ROLE = """ +Ты специалист по поиску клиентов в компании, которая занимается разработкой любого софта +на заказ. +""" + +ANALYTIC_PROMT = """ +Ты получаешь json с такими полями +{ + "messages": [ + { + "message_id": integer, + "user_id": integer, + "chat_id": integer, + "text": string, + "date": datetime + } + ] +} +messages - это срез диалога в чате телеграмма. +пользователи могут общаться на абсолютно разные темы. +Твоя задача: +Прочитать эти сообщения, понять тему текущего среза диалога. +И если ты поймешь, что мы можем какому то пользователю предложить свои услуги +например (написать интернет магазин, мобильное приложение или любой другой айти продукт) +то выведи в таком виде ответ. + +ВАЖНО: Если ты уверен на 100 процентов, что они заинтересованы в подобных услугах и им +можно предложить, то верни. + +{ + "user_id": integer, + "chat_id": integer, + "reason": string +} + +поле reason: Кратко(до 100 симоволов) почему ты решил, что это потенциальный клиент. + +Если ты хотя бы чуть чуть не уверен, то верни вот такой json +{ + "user_id": None, + "chat_id": None, + "reason": None, +} + +ВАЖНО: Ты должен вернуть ТОЛЬКО JSON и не словом больше. Иначе я разорюсь. + +""" + +BASE_MESSAGE = [ + { + "role": "system", + "content": ROLE.replace("\n", '') + }, + { + "role": "user", + "content": ANALYTIC_PROMT.replace("\n", ''), + } +] diff --git a/src/core/database/__init__.py b/src/core/database/__init__.py index 400e6f4..f88eba6 100644 --- a/src/core/database/__init__.py +++ b/src/core/database/__init__.py @@ -1,6 +1,10 @@ __all__ = [ "Base", + "TgMessage", + "TgChat", ] -from .base import Base \ No newline at end of file +from .base import Base +from .tg_messages import TgMessage +from .chats import TgChat \ No newline at end of file diff --git a/src/core/database/chats.py b/src/core/database/chats.py index 4323a8a..3c71c07 100644 --- a/src/core/database/chats.py +++ b/src/core/database/chats.py @@ -1,5 +1,9 @@ +from sqlalchemy.orm import Mapped + from src.core.database import Base -class Chat(Base): - pass \ No newline at end of file +class TgChat(Base): + telegram_chat_id: Mapped[int] + chat_type: Mapped[str] + title: Mapped[str] \ No newline at end of file diff --git a/src/core/database/tg_messages.py b/src/core/database/tg_messages.py new file mode 100644 index 0000000..108edd6 --- /dev/null +++ b/src/core/database/tg_messages.py @@ -0,0 +1,18 @@ +from datetime import datetime + +from sqlalchemy import ForeignKey +from sqlalchemy.orm import Mapped, mapped_column + +from src.core.database import Base + + + +class TgMessage(Base): + text: Mapped[str] + message_time: Mapped[datetime] + user_id: Mapped[int] = mapped_column( + ForeignKey("users.telegram_id"), + ) + chat_id: Mapped[int] = mapped_column( + ForeignKey("chats.telegram_chat_id"), + ) diff --git a/src/core/database/users.py b/src/core/database/users.py index af1f6e9..183e71e 100644 --- a/src/core/database/users.py +++ b/src/core/database/users.py @@ -1,9 +1,16 @@ -from sqlalchemy.orm import Mapped +from sqlalchemy import BigInteger +from sqlalchemy.orm import Mapped, mapped_column from src.core.database.base import Base class User(Base): - telegram_id: Mapped[int] - nickname: Mapped[str] - \ No newline at end of file + telegram_id: Mapped[int] = mapped_column( + BigInteger, + primary_key=True, + unique=True, + ) + username: Mapped[str] + first_name: Mapped[str | None] + last_name: Mapped[str | None] + diff --git a/src/core/settings/base.py b/src/core/settings/base.py index 312f2f0..4a570fa 100644 --- a/src/core/settings/base.py +++ b/src/core/settings/base.py @@ -6,6 +6,8 @@ from src.core.settings.database import DatabaseSettings from src.core.settings.groq import GroqSettings +print(EnvFileLocation.PRODUCTION) + class Settings(BaseSettings): model_config = SettingsConfigDict( case_sensitive=True, @@ -13,7 +15,7 @@ class Settings(BaseSettings): env_prefix=PydanticEnvPrefixEnum.APP.value, env_file=( EnvFileLocation.PRODUCTION, - EnvFileLocation.TESTING, + # EnvFileLocation.TESTING, ) ) diff --git a/src/main.py b/src/main.py index 7fa8f9e..f65c47f 100644 --- a/src/main.py +++ b/src/main.py @@ -1,6 +1,12 @@ +import json + from pyrogram import Client, filters +from pyrogram.enums import ChatType from pyrogram.types import Message +from ai_test import create_request_ai +from src.core.common.promt import BASE_MESSAGE + api_id = 17718565 api_hash = "72f93973f4227415572f039d4f847082" @@ -10,18 +16,66 @@ app = Client( api_hash=api_hash, ) +DATA = dict() + @app.on_message(filters.all) # Используем фильтр для сообщений из всех чатов -def listen_messages(client: Client, message: Message): - print(message.chat) +async def listen_messages(client: Client, message: Message): + # print(message.chat) chat_title = message.chat.title or message.chat.first_name or message.chat.username sender = message.from_user.first_name if message.from_user else "Система/Бот" text = message.text or "[не текстовое сообщение]" - print(f"Сообщение из чата: {chat_title}") - print(f"Отправитель: {sender}") - print(f"Текст: {text}") - print("-" * 40) + + + if message.chat.type not in [ChatType.PRIVATE, ChatType.BOT] and message.from_user: + if DATA.get(message.chat.id): + DATA[message.chat.id].append( + { + "message_id": message.id, + "user_id": message.from_user.id, + "chat_id": message.chat.id, + "text": message.text, + "date": message.date.strftime("%d/%m/%Y:%H:%M:%S"), + } + ) + else: + DATA[message.chat.id] = [ + { + "message_id": message.id, + "user_id": message.from_user.id, + "chat_id": message.chat.id, + "text": message.text, + "date": message.date.strftime("%d/%m/%Y:%H:%M:%S"), + } + ] + print(len(DATA[message.chat.id])) + + # print(chat_title, '|', len(DATA[message.chat.id])) + # print(len(DATA[message.chat.id])) + counter = 0 + + for key, value in DATA.items(): + if len(value) == 20 and counter == 0: + extend_message = { + "role": "user", + "content": json.dumps({ + "messages": value + }) + } + BASE_MESSAGE.append(extend_message) + await create_request_ai( + messages=BASE_MESSAGE + ) + + for _ in value: + print(_) + counter += 1 + + # print(f"Сообщение из чата: {chat_title}") + # print(f"Отправитель: {sender}") + # print(f"Текст: {text}") + # print("-" * 40) # Запуск клиента if __name__ == "__main__":