Alisa V Zadzerkalli
C++

Alisa V Zadzerkalli

Alisa v Zadzerkalli - bot Discord napisany w C++

GitHub|
image

Alisa v Zadzerkalli (ukraiński) – Alicja po drugiej stronie lustra. Świat po
drugiej stronie lustra, do którego trafiasz celowo, a wszystko jest
odbite, odwrócone i nie tak.

«Ніколи не вгадаєш, ким станеш за хвилину.»
„Nigdy nie zgadniesz, kim się staniesz za chwilę.” – Alicja, w
Аліса в Країні Див, tłum. Valentyn Korniienko, red. Ivan Malkovych, s. 53.

Bot Discord napisany w C++.

Możliwości

Komendy slash

  • /ping – czas odpowiedzi w obie strony względem bramy
  • /leaderboard – ranking Clube de Programação (UFFS), pobierany z
    grupy vjudge klubu i sortowany według liczby rozwiązanych zadań

Rozmowa

Wspomnij ją, albo napisz alisa lub obliterator w wiadomości, a ona odpowie.
Odpowiedź nie jest generowana lokalnie. Alisa składa kontekst, a Providence
wykonuje myślenie.

To, co wysyła do modelu przy każdej wiadomości:

  • każdego członka klubu, w kolejności rankingu, z jego pseudonimem, liczbą
    rozwiązanych zadań i czasem ostatniej aktywności
  • pełną listę zadań rozwiązanych przez każdego członka, według sędziego
  • dziesięć najczęściej rozwiązywanych zadań w całym klubie

Ten kontekst pozwala jej odpowiadać na pytania, do których nikt nie napisał
komendy. Kto jest w pierwszej trójce, jakie zadania mają wspólne, kto
zamilkł. Model dostarcza rozumowanie, scraping dostarcza fakty.

Dane klubu

Stan członków jest pobierany z vjudge przy starcie przez ograniczoną pulę
ośmiu pracowników, każdy trzymający jedno połączenie dla swojej części grupy.
Każdy członek kosztuje dwa żądania: stronę profilu dla liczb i rangi oraz
punkt końcowy szczegółów rozwiązań dla listy zadań.

Struktura

  • main.cpp – punkt wejścia
  • src/commands/ – komendy slash i dyspozytor
  • src/members/ – lista członków klubu, scraping profilu i listy rozwiązań
  • src/parser/ – zapytania HTML przez lexbor
  • src/network/ – HTTP z ponownym użyciem połączeń
  • src/speech/ – połączenie z Providence i składanie promptu
  • src/onmessage/, src/onready/ – procedury obsługi zdarzeń bramy
  • src/embeds/ – embed domowy
  • src/config/ – konfiguracja klastra i wspólny stan bota

Jak powstaje odpowiedź

Procedura obsługi wiadomości uruchamia się przy każdej wiadomości w każdym
kanale, który bot widzi. Odrzuca boty, odrzuca wszystko, co nie wspomina jej
przez ping lub słowa alisa albo obliterator, a obecnie odrzuca też każdego
autora oprócz jednego – identyfikator zapisany na stałe w src/onmessage.
Wszystko, co przetrwa, otrzymuje natychmiastowy embed z tekstem Thinking...,
opublikowany zanim model zostanie o cokolwiek zapytany, aby kanał widział,
że przyjęła pytanie, nawet gdy odpowiedź jest wolna.

Sama odpowiedź to POST do Providence pod adresem http://127.0.0.1:8931 na
/speech/deepthink/, niosący wiadomość, cały kontekst klubu oraz nazwę
użytkownika Discord jako tożsamość wywołującego. Czeka do 200 sekund.
Odpowiedź jest przycinana do 1990 bajtów na granicy znaku UTF-8, aby cięcie
nigdy nie trafiło w środek punktu kodowego, a następnie embed zastępczy jest
edytowany w miejscu. Przekroczenie czasu, odmowa lub nieparsowalna treść
kończą się tekstem w tym samym embedzie, a nie ciszą.

Providence to osobna usługa i nie znajduje się w tym repozytorium. Bez niej
działającej na tym porcie bot nadal startuje, nadal odpowiada na komendy
slash i nadal scrapuje klub – przestaje tylko myśleć.

Co dodaje Providence

Alisa wysyła light true, czyli tanią ścieżkę – jeden węzeł rozumowania i bez
rozgałęzień. Usuń tę flagę, a ten sam punkt końcowy uruchomi ograniczone
drzewo myśli, głębokość dwa, co najmniej dwie oznaczone gałęzie na węzeł,
każda oceniana pod kątem prawdopodobieństwa sukcesu oraz tego, ile potencjału
dodaje lub niszczy, a każdy węzeł generowany przez natywnego myśliciela
uruchamianego jako podproces. Ta maszyneria siedzi tam niewykorzystana przy
każdej wysyłanej przez nią wiadomości.

Usługa decyduje też sama, czy pytanie wymaga czegoś więcej niż rozmowy. Jeśli
tak, klasyfikator mapuje wiadomość na jedną komendę i jej argument, uruchamia
ją i włącza wynik do końcowej odpowiedzi. Co jest obecnie na tej liście:

  • wykresy – krzywa 2D lub powierzchnia 3D z funkcji opisanej słownie
  • algebra – upraszczanie, rozwijanie, rozkład na czynniki, rozwiązywanie dla zmiennej
  • analiza matematyczna – pochodne, całki oznaczone i nieoznaczone, granice
  • macierze – wyznacznik, macierz odwrotna, wartości własne
  • renderowanie dowolnego wyrażenia jako LaTeX
  • portal UFFS SIGAA – bieżące przedmioty, plan zajęć, nadchodzące zadania
  • restauracja UFFS – które posiłki są otwarte do rezerwacji i jak przebiegły
    poprzednie, obsługiwane przez prawdziwą przeglądarkę bez interfejsu z własnymi
    poświadczeniami

Każda z tych odpowiedzi niesie obok prozy pola strukturalne. Wykres lub
render LaTeX wraca jako obraz PNG w base64 pod image, odczyt portalu wraca
jako JSON pod data, a własny komentarz modelu znajduje się obok pod response.
Alisa czyta response i wyrzuca resztę, więc dziś pytanie, które generuje
wykres, dociera do Discorda jako zdanie o wykresie, którego nikt nie widzi.
Wysyłanie obrazu jako załącznika to oczywista następna rzecz, której ten bot
powinien się nauczyć.

Dostęp jest per wywołujący, nie per bot. Identyfikuje się jako discord oraz
nazwę użytkownika autora, a Providence sprawdza tę parę i odmawia każdemu,
kogo nie zna – to właśnie odmowa, którą ona wypisuje dosłownie. Dodanie
członka klubu oznacza dodanie go tam, nie tutaj.

Budowanie

Wymaga kompilatora C++20, CMake 3.16 lub nowszego oraz trzech bibliotek: DPP
dla bramy, cpr dla HTTP, lexbor dla HTML. Na Archu Makefile instaluje
brakujące przez yay lub paru. Gdzie indziej zainstaluj je samodzielnie.

make deps      pobierz DPP, cpr i lexbor, jeśli ich brak
make           skonfiguruj i zbuduj w build/
make run       wczytaj .env, potem uruchom binarkę
make rebuild   wyczyść build/ i zacznij od nowa

Dwie rzeczy w budowaniu są celowe. Domyślny typ budowania to
RelWithDebInfo, a liczba równoległych zadań kompilacji jest ograniczona do
dwóch. Nagłówki DPP są na tyle bogate w szablony, że niezoptymalizowane
budowanie kosztuje kilka gigabajtów na proces kompilatora, a jeden proces na
rdzeń położy maszynę. Daj więcej, gdy masz pamięć: make JOBS=8.

Źródła są zbierane przez CONFIGURE_DEPENDS, więc nowy plik w src/ zostanie
wychwycony przy następnym budowaniu bez dotykania CMakeLists.

Konfiguracja

Bot czyta DISCORD_TOKEN ze środowiska i niczego więcej. Umieść go w .env
w katalogu głównym repozytorium, a make run wyeksportuje go za ciebie, albo
wyeksportuj sam i uruchom build/alisa-v-zadzerkalli_core bezpośrednio.
Łączy się z domyślnymi intencjami plus treścią wiadomości, która jest intencją
uprzywilejowaną, więc włącz ją dla aplikacji w portalu deweloperskim Discord,
inaczej procedura obsługi wiadomości będzie widzieć tylko puste ciągi.

Klucze Providence znajdują się obok w .env dla usługi po drugiej stronie
gniazda. Ta binarka nigdy ich nie czyta.