Compare commits

...

21 Commits

Author SHA1 Message Date
678dd29918 Fix 2025-02-19 17:48:05 +01:00
3cfea7277f Fix 2025-02-19 17:44:30 +01:00
269245a112 Fix 2025-02-19 17:29:57 +01:00
22e9461a7e Fix 2025-02-19 17:18:03 +01:00
165308d83b Fix 2025-02-19 17:11:32 +01:00
d041f8d903 Fix 2025-02-19 17:04:16 +01:00
8207266d9b Update 2025-02-19 16:58:57 +01:00
9a76f86d41 Update 2025-02-19 16:55:45 +01:00
dc3abeb429 Fix 2025-02-19 16:41:05 +01:00
fa82c96e79 Fix 2025-02-19 16:26:23 +01:00
6f0a236f2f Fix 2025-02-19 16:19:54 +01:00
d645e6db92 Fix scripts 2025-02-19 16:16:39 +01:00
334718a7fb Fix 2025-02-19 16:12:55 +01:00
efa92dc575 Fix 2025-02-19 16:08:05 +01:00
a95d80c8dc Update start scripts 2025-02-19 16:05:32 +01:00
f9603712e8 Fix 2025-02-19 16:01:23 +01:00
fbe8367723 Fix 2025-02-19 15:59:39 +01:00
6e50807381 Update 2025-02-19 15:58:45 +01:00
f907892769 Move to uv 2025-02-19 15:55:49 +01:00
5648bfa024 Fix 2025-02-19 15:29:18 +01:00
7b3a89f41b Fix 2025-02-19 15:28:40 +01:00
10 changed files with 1299 additions and 2212 deletions

2
.gitignore vendored
View File

@@ -1,4 +1,4 @@
venv .venv
.DS_Store .DS_Store

View File

@@ -1,33 +1,19 @@
FROM python:3.12-slim AS build FROM ghcr.io/astral-sh/uv:python3.12-bookworm-slim
ARG POETRY_EXPORT_EXTRA_ARGS=''
WORKDIR /opt/venv
RUN python -m venv /opt/venv && /opt/venv/bin/pip install --upgrade pip && /opt/venv/bin/pip install --no-cache-dir httpx poetry poetry-plugin-export
COPY ./pyproject.toml ./poetry.lock ./
RUN --mount=type=ssh /opt/venv/bin/poetry export --without-hashes ${POETRY_EXPORT_EXTRA_ARGS} > requirements.txt \
&& /opt/venv/bin/pip install --no-cache-dir -r requirements.txt
FROM python:3.12-slim AS runtime
RUN apt update && \
apt install -y --no-install-recommends curl jq && \
apt clean
COPY ./src/ /app
COPY ./scripts/*.sh / COPY ./scripts/*.sh /
RUN chmod +x /*.sh RUN chmod +x /*.sh
ENV PATH="/opt/venv/bin:$PATH"
ENV VENV_PATH=/opt/venv
COPY --from=build /opt/venv /opt/venv
WORKDIR /app WORKDIR /app
COPY ./pyproject.toml ./
COPY ./uv.lock ./
RUN uv venv && uv sync --frozen
COPY ./src ./src
ENV PATH="/app/.venv/bin:$PATH"
EXPOSE 80 EXPOSE 80
CMD ["python", "main.py"] CMD ["uv", "run", "src/main.py"]

2152
poetry.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,30 +1,33 @@
[tool.poetry] [project]
name = "discord-bot" name = "discord-bot"
version = "0.1.0" version = "0.1.0"
description = "" description = ""
authors = ["Bulat Kurbanov <kurbanovbul@gmail.com>"] authors = [{ name = "Bulat Kurbanov", email = "kurbanovbul@gmail.com" }]
readme = "README.md" requires-python = "~=3.12"
packages = [{include = "discord_bot"}] dependencies = [
"discord-py>=2.4.0,<3",
"twitchapi>=4.4.0,<5",
"pydantic>=2.10.5,<3",
"pydantic-settings>=2.7.1,<3",
"httpx>=0.28.1,<0.29",
"icalendar>=6.1.0,<7",
"pytz~=2024.2",
"mongojet>=0.2.7,<0.3",
"taskiq>=0.11.11,<0.12",
"taskiq-redis>=1.0.2,<2",
"redis[hiredis]>=5.2.1,<6",
"fastapi>=0.115.8,<0.116",
"authx>=1.4.1,<2",
"httpx-oauth>=0.16.1,<0.17",
"uvicorn[standard]>=0.34.0,<0.35",
]
[tool.poetry.dependencies] [tool.hatch.build.targets.sdist]
python = "^3.11" include = ["discord_bot"]
discord-py = "^2.4.0"
twitchapi = "^4.4.0"
pydantic = "^2.10.5"
pydantic-settings = "^2.7.1"
httpx = "^0.28.1"
icalendar = "^6.1.0"
pytz = "^2024.2"
mongojet = "^0.2.7"
taskiq = "^0.11.11"
taskiq-redis = "^1.0.2"
redis = {extras = ["hiredis"], version = "^5.2.1"}
fastapi = "^0.115.8"
authx = "^1.4.1"
httpx-oauth = "^0.16.1"
uvicorn = {extras = ["standard"], version = "^0.34.0"}
[tool.hatch.build.targets.wheel]
include = ["discord_bot"]
[build-system] [build-system]
requires = ["poetry-core"] requires = ["hatchling"]
build-backend = "poetry.core.masonry.api" build-backend = "hatchling.build"

View File

@@ -1,3 +1,3 @@
#! /usr/bin/env sh #! /usr/bin/env sh
/opt/venv/bin/python main.py $1 uv run ./src/main.py $1

View File

@@ -1,3 +1,3 @@
#! /usr/bin/env sh #! /usr/bin/env sh
/opt/venv/bin/taskiq scheduler core.broker:scheduler modules.tasks uv run --directory src taskiq scheduler core.broker:scheduler modules.tasks

View File

@@ -1,3 +1,3 @@
#! /usr/bin/env sh #! /usr/bin/env sh
/opt/venv/bin/uvicorn modules.web_app.app:app --host 0.0.0.0 --port 80 uv run --directory src uvicorn modules.web_app.app:app --host 0.0.0.0 --port 80

View File

@@ -1,3 +1,3 @@
#! /usr/bin/env sh #! /usr/bin/env sh
/opt/venv/bin/taskiq worker core.broker:broker modules.tasks uv run --directory src taskiq worker core.broker:broker modules.tasks

View File

@@ -96,6 +96,19 @@ async def get_completion(messages: list[dict]) -> str:
logger.info(f"Getting completion for message: {messages}") logger.info(f"Getting completion for message: {messages}")
data_messages = [ data_messages = [
{
"role": "system",
"content": (
"Don't use markdown! "
"Don't use blocked words on Twitch! "
"Make answers short and clear! "
"You are not language model! "
"You are not a bot! "
"You are human! "
"Your name is kurbezz or Bulat! "
"Don't start answer with @kurbezz!"
)
},
*( *(
{ {
"role": "assistant" if message["user"] == "kurbezz" else "user", "role": "assistant" if message["user"] == "kurbezz" else "user",
@@ -103,10 +116,6 @@ async def get_completion(messages: list[dict]) -> str:
} }
for message in messages for message in messages
), ),
{
"role": "system",
"content": "Don't use markdown! Don't use blocked words on Twitch! Make answers short and clear!"
}
] ]
async with AsyncClient() as client: async with AsyncClient() as client:
@@ -154,8 +163,13 @@ class MessagesProc:
def get_message_history_with_thread(cls, message_id: str, thread_id: str | None = None) -> list[dict]: def get_message_history_with_thread(cls, message_id: str, thread_id: str | None = None) -> list[dict]:
logger.info(f"HISTORY: {cls.MESSAGE_HISTORY}") logger.info(f"HISTORY: {cls.MESSAGE_HISTORY}")
return [m for m in cls.MESSAGE_HISTORY if m["thread_id"] == thread_id] + \ if thread_id is not None:
[m for m in cls.MESSAGE_HISTORY if m["id"] == message_id] return (
[m for m in cls.MESSAGE_HISTORY if m["id"] == thread_id]
+ [m for m in cls.MESSAGE_HISTORY if m["thread_id"] == thread_id]
)
return [m for m in cls.MESSAGE_HISTORY if m["id"] == message_id]
@classmethod @classmethod
async def on_message(cls, event: MessageEvent): async def on_message(cls, event: MessageEvent):
@@ -182,7 +196,29 @@ class MessagesProc:
) )
if "lasqexx" in event.chatter_user_login: if "lasqexx" in event.chatter_user_login:
pass # Todo: Здароу if "здароу" in event.message.text.lower():
await twitch.send_chat_message(
event.broadcaster_user_id,
config.TWITCH_ADMIN_USER_ID,
"Здароу, давай иди уже",
reply_parent_message_id=event.message_id
)
if "сосал?" in event.message.text.lower():
await twitch.send_chat_message(
event.broadcaster_user_id,
config.TWITCH_ADMIN_USER_ID,
"А ты? Иди уже",
reply_parent_message_id=event.message_id
)
if "лан я пошёл" in event.message.text.lower():
await twitch.send_chat_message(
event.broadcaster_user_id,
config.TWITCH_ADMIN_USER_ID,
"да да, иди уже",
reply_parent_message_id=event.message_id
)
if event.message.text.lower().startswith("!ai"): if event.message.text.lower().startswith("!ai"):
try: try:
@@ -202,6 +238,13 @@ class MessagesProc:
part, part,
reply_parent_message_id=event.message_id reply_parent_message_id=event.message_id
) )
cls.update_message_history(
id="ai",
text=part,
user="kurbezz",
thread_id=event.message_id
)
except Exception as e: except Exception as e:
logger.error("Failed to get completion: {}", e, exc_info=True) logger.error("Failed to get completion: {}", e, exc_info=True)
@@ -236,6 +279,13 @@ class MessagesProc:
part, part,
reply_parent_message_id=event.message_id reply_parent_message_id=event.message_id
) )
cls.update_message_history(
id="ai",
text=part,
user="kurbezz",
thread_id=event.message_id
)
except Exception as e: except Exception as e:
logger.error(f"Failed to get completion: {e}") logger.error(f"Failed to get completion: {e}")

1200
uv.lock generated Normal file

File diff suppressed because it is too large Load Diff