Alisa V Zadzerkalli
C++

Alisa V Zadzerkalli

Alisa v Zadzerkalli - Discord-бот, написанный на C++

GitHub|
image

Alisa v Zadzerkalli (українською) — Аліса в Задзеркаллі. Світ по той бік дзеркала, куди йдеш навмисно, і все відображене, перевернуте й неправильне.

«Ніколи не вгадаєш, ким станеш за хвилину.»
"You can never guess who you'll become in a minute." — Аліса, у
Аліса в Країні Див, пер. Валентин Корнієнко, ред. Іван Малкович, с. 53.

Discord-бот, написаний на C++.

Можливості

Слеш-команди

  • /ping — час обходу до шлюзу
  • /leaderboard — таблиця лідерів Clube de Programação (UFFS), отримана з
    групи клубу на vjudge та відсортована за кількістю розв'язаних задач

Розмова

Згадайте її, або напишіть alisa чи obliterator у повідомленні — і вона відповість.
Відповідь не генерується локально. Аліса збирає контекст, а Providence думає.

Що вона передає моделі в кожному повідомленні:

  • кожного члена клубу, у порядку таблиці лідерів, з їхнім нікнеймом, кількістю
    розв'язаних задач і часом останньої активності
  • повний список задач, які розв'язав кожен учасник, за кожним суддею
  • десять задач, які розв'язують найчастіше в усьому клубі

Саме цей контекст дозволяє їй відповідати на питання, під які ніхто не писав команду.
Хто в топ-трійці, які задачі в них спільні, хто замовк. Модель забезпечує міркування,
скрапінг забезпечує факти.

Дані клубу

Стан учасників отримується з vjudge під час запуску пулом із восьми робітників,
кожен з яких тримає одне з'єднання для своєї частки групи. Кожен учасник коштує
два запити: сторінка профілю для кількості та рейтингу, і кінцева точка деталей
розв'язків для списку задач.

Структура

  • main.cpp — точка входу
  • src/commands/ — слеш-команди та диспетчер
  • src/members/ — склад клубу, скрапінг профілів і списків розв'язків
  • src/parser/ — запити до HTML через lexbor
  • src/network/ — HTTP із повторним використанням з'єднань
  • src/speech/ — зв'язок із Providence і збірка промптів
  • src/onmessage/, src/onready/ — обробники подій шлюзу
  • src/embeds/ — фірмовий ембед
  • src/config/ — налаштування кластера та спільний стан бота

Як відбувається відповідь

Обробник повідомлень прокидається на кожне повідомлення в кожному каналі, який бачить бот.
Він відкидає ботів, відкидає все, що не згадує її через пінг або слова alisa чи obliterator,
а зараз також відкидає всіх авторів, окрім одного, — ID захардкоджений у src/onmessage.
Усе, що виживає, отримує миттєвий ембед із текстом Thinking..., опублікований до того,
як модель щось запитають, щоб канал бачив, що вона взяла питання, навіть якщо відповідь повільна.

Сама відповідь — це POST до Providence на http://127.0.0.1:8931 на
/speech/deepthink/, який несе повідомлення, весь контекст клубу та ім'я користувача
Discord як особу, що викликає. Він чекає до 200 секунд. Відповідь обрізається до 1990 байтів
на межі UTF-8-символу, щоб обрізання ніколи не потрапило в середину кодової точки,
а потім ембед-заглушка редагується на місці. Таймаут, відмова або нерозбірливе тіло
завершуються текстом у тому ж ембеді, а не мовчанням.

Providence — це окремий сервіс, і його немає в цьому репозиторії. Якщо він не запущений
на цьому порту, бот все одно стартує, відповідає на слеш-команди та скрапить клуб,
він просто перестає думати.

Що додає Providence

Аліса надсилає light true, що є дешевим шляхом: один вузол міркування і без розгалужень.
Приберіть цей прапорець — і та сама кінцева точка запускає обмежене дерево думок замість
цього: глибина два, щонайменше дві позначені гілки на вузол, кожна оцінюється за ймовірністю
успіху та за тим, скільки потенціалу вона додає чи знищує, і кожен вузол генерується
нативним мислителем, запущеним як субпроцес. Цей механізм просто лежить невикористаним
у кожному повідомленні, яке вона надсилає.

Вона також сама вирішує, чи потребує питання більше, ніж розмови. Якщо так,
класифікатор зіставляє повідомлення з однією командою та її аргументом, запускає її
та вбудовує результат у фінальну відповідь. Що зараз у цьому списку:

  • побудова графіків, 2D-крива або 3D-поверхня з функції, яку ви описуєте словами
  • алгебра, спрощення, розкладання, факторизація, розв'язок змінної
  • математичний аналіз, похідні, визначені та невизначені інтеграли, границі
  • матриці, визначник, обернена матриця, власні значення
  • рендеринг будь-якого виразу як LaTeX
  • портал UFFS SIGAA, поточні дисципліни, розклад, майбутні завдання
  • ресторан UFFS, які прийоми їжі відкриті для бронювання і як минулі пройшли,
    керується через справжній headless-браузер із власними обліковими даними

Кожна з цих відповідей несе структуровані поля поруч із прозою. Графік або LaTeX-рендер
повертається як base64 PNG під image, читання порталу повертається як JSON під data,
а власний коментар моделі розташований поруч під response. Аліса читає response
і викидає решту, тому сьогодні питання, яке створює графік, доходить до Discord
як речення про графік, який ніхто не бачить. Надсилання зображення як вкладення —
це очевидна наступна річ, якої цей бот має навчитися.

Доступ надається за викликачем, а не за ботом. Вона ідентифікує себе як discord
та ім'я користувача автора, і Providence перевіряє цю пару та відмовляє будь-кому,
кого не знає, — це відмова, яку вона друкує дослівно. Додавання члена клубу означає
додавання його там, а не тут.

Збірка

Потрібен компілятор C++20, CMake 3.16 або новіший, і три бібліотеки: DPP для шлюзу,
cpr для HTTP, lexbor для HTML. На Arch Makefile встановлює відсутні через yay або paru.
У будь-якому іншому місці спершу встановіть їх самостійно.

make deps      завантажити DPP, cpr і lexbor, якщо їх немає
make           налаштувати та зібрати в build/
make run       завантажити .env, потім запустити бінарник
make rebuild   стерти build/ і почати заново

Дві речі в збірці навмисні. Тип збірки за замовчуванням — RelWithDebInfo,
а паралельні завдання компіляції обмежені двома. Заголовки DPP досить шаблонні,
щоб неоптимізована збірка коштувала кілька гігабайт на кожен процес компілятора,
а один процес на ядро звалить машину разом із собою. Дайте більше, коли маєте пам'ять:
make JOBS=8.

Джерела збираються через CONFIGURE_DEPENDS, тому новий файл у src/ підхоплюється
при наступній збірці без змін у CMakeLists.

Конфігурація

Бот читає DISCORD_TOKEN із середовища і більше нічого. Покладіть його в .env
у корені репозиторію, і make run експортує його за вас, або експортуйте самі
та запустіть build/alisa-v-zadzerkalli_core безпосередньо. Вона підключається
зі стандартними інтентами плюс вміст повідомлень, що є привілейованим інтентом,
тому увімкніть його для застосунку в порталі розробника Discord, інакше обробник
повідомлень бачитиме лише порожні рядки.

Ключі Providence лежать поруч у .env для сервісу на іншому кінці сокета.
Цей бінарник їх ніколи не читає.