
Alisa v Zadzerkalli (ukrainien) — Alice au pays du miroir. Le monde de l'autre
côté du miroir, où l'on va exprès et où tout est reflété, inversé, et faux.
«Ніколи не вгадаєш, ким станеш за хвилину.»
« On ne peut jamais deviner qui l'on deviendra dans une minute. » — Alice, dans
Аліса в Країні Див, trad. Valentyn Korniienko, éd. Ivan Malkovych p. 53.
Un bot Discord écrit en C++.
Capacités
Commandes slash
- /ping — latence aller-retour contre la passerelle
- /leaderboard — le classement du Clube de Programação (UFFS), récupéré depuis
le groupe vjudge du club et classé par nombre de problèmes résolus
Conversation
Mentionnez-la, ou dites alisa ou obliterator dans un message, et elle répond. La
réponse n'est pas générée localement. Alisa assemble le contexte et Providence
fait la réflexion.
Ce qu'elle place devant le modèle à chaque message :
- chaque membre du club, dans l'ordre du classement, avec son pseudo, son nombre
de résolutions et sa dernière activité - la liste complète des problèmes résolus par chaque membre, par juge
- les dix problèmes les plus souvent résolus dans tout le club
Ce contexte lui permet de répondre aux questions pour lesquelles personne n'a
écrit de commande. Qui est dans le top trois, quels problèmes ils ont en commun,
qui s'est tu. Le modèle fournit le raisonnement, le scraping fournit les faits.
Données du club
L'état des membres est récupéré depuis vjudge au démarrage par un pool borné de
huit travailleurs, chacun tenant une connexion pour sa part du groupe. Chaque
membre coûte deux requêtes : la page de profil pour les compteurs et le rang, et
le point de terminaison des détails de résolution pour la liste des problèmes.
Structure
- main.cpp — point d'entrée
- src/commands/ — commandes slash et le répartiteur
- src/members/ — effectif du club, scraping du profil et des listes de résolutions
- src/parser/ — requêtes HTML sur lexbor
- src/network/ — HTTP avec réutilisation de connexion
- src/speech/ — le lien Providence et l'assemblage des invites
- src/onmessage/, src/onready/ — gestionnaires d'événements de passerelle
- src/embeds/ — l'embed maison
- src/config/ — configuration du cluster et état partagé du bot
Comment une réponse se produit
Le gestionnaire de messages se réveille à chaque message dans chaque canal que
le bot peut voir. Il ignore les bots, ignore tout ce qui ne la mentionne pas par
ping ou par les mots alisa ou obliterator, et pour l'instant il ignore aussi
tout auteur sauf un, un identifiant codé en dur dans src/onmessage. Ce qui
survit reçoit immédiatement un embed affichant Thinking..., posté avant que le
modèle ne soit interrogé, afin que le canal la voie prendre la question même
quand la réponse est lente.
La réponse elle-même est un POST vers Providence à http://127.0.0.1:8931 sur
/speech/deepthink/, transportant le message, tout le contexte du club, et le nom
d'utilisateur Discord comme identité de l'appelant. Il attend jusqu'à 200
secondes. La réponse est tronquée à 1990 octets sur une limite de caractère
UTF-8 afin qu'une coupure ne tombe jamais au milieu d'un point de code, puis
l'embed de remplacement est modifié sur place. Un délai dépassé, un refus ou un
corps non analysable se terminent tous en texte dans le même embed plutôt qu'en
silence.
Providence est un service séparé et n'est pas dans ce dépôt. Sans lui sur ce
port, le bot démarre quand même, répond toujours aux commandes slash, et
continue de scraper le club ; il cesse seulement de penser.
Ce que Providence ajoute
Alisa envoie light true, ce qui est le chemin économique : un nœud de
raisonnement et aucune ramification. Retirez ce drapeau et le même point de
terminaison exécute à la place un arbre de pensées borné, profondeur deux, au
moins deux branches étiquetées par nœud, chacune notée pour sa probabilité de
succès et pour le potentiel qu'elle ajoute ou détruit, et chaque nœud généré par
un penseur natif lancé comme sous-processus. Cette machinerie reste là, inutilisée,
à chaque message qu'elle envoie.
Il décide aussi lui-même si la question nécessite plus que de la conversation.
Si c'est le cas, un classificateur mappe le message vers une commande et son
argument, l'exécute, et intègre le résultat dans la réponse finale. Ce qui est
sur cette liste actuellement :
- tracé, une courbe 2D ou une surface 3D à partir d'une fonction que vous
décrivez en mots - algèbre, simplifier, développer, factoriser, résoudre pour une variable
- calcul, dérivées, intégrales définies et indéfinies, limites
- matrices, déterminant, inverse, valeurs propres
- rendu de toute expression en LaTeX
- le portail SIGAA de l'UFFS, disciplines actuelles, emploi du temps, devoirs à venir
- le restaurant de l'UFFS, quels repas sont ouverts à la réservation et comment
les précédents se sont passés, piloté par un vrai navigateur sans tête avec ses
propres identifiants
Chacune de ces réponses porte des champs structurés à côté de la prose. Un tracé
ou un rendu LaTeX revient comme PNG base64 sous image, une lecture du portail
revient comme JSON sous data, et le commentaire du modèle lui-même se trouve à
côté sous response. Alisa lit response et jette le reste, donc aujourd'hui une
question qui produit un graphique atteint Discord comme une phrase à propos d'un
graphique que personne ne peut voir. Envoyer l'image comme pièce jointe est la
prochaine chose évidente que ce bot devrait apprendre.
L'accès est par appelant, pas par bot. Elle s'identifie comme discord et le nom
d'utilisateur de l'auteur, et Providence vérifie cette paire et refuse quiconque
qu'il ne connaît pas, ce qui est le refus qu'elle imprime textuellement. Ajouter
un membre du club signifie l'ajouter là-bas, pas ici.
Construction
Nécessite un compilateur C++20, CMake 3.16 ou plus récent, et trois
bibliothèques : DPP pour la passerelle, cpr pour HTTP, lexbor pour HTML. Sur
Arch, le Makefile installe celles qui manquent via yay ou paru. Ailleurs,
installez-les vous-même d'abord.
make deps récupère DPP, cpr et lexbor s'ils sont absents
make configure et construit dans build/
make run charge .env, puis exécute le binaire
make rebuild efface build/ et recommence
Deux choses dans la construction sont délibérées. Le type de construction par
défaut est RelWithDebInfo, et les travaux de compilation parallèles sont plafonnés
à deux. Les en-têtes de DPP sont assez lourds en templates pour qu'une
construction non optimisée coûte plusieurs gigaoctets par processus compilateur,
et un processus par cœur fera tomber la machine avec lui. Donnez-lui plus quand
vous avez la mémoire, make JOBS=8.
Les sources sont collectées avec CONFIGURE_DEPENDS, donc un nouveau fichier sous
src/ est pris en compte à la prochaine construction sans toucher à CMakeLists.
Configuration
Le bot lit DISCORD_TOKEN depuis l'environnement et rien d'autre. Mettez-le dans
.env à la racine du dépôt et make run l'exportera pour vous, ou exportez-le
vous-même et exécutez build/alisa-v-zadzerkalli_core directement. Elle se connecte
avec les intents par défaut plus le contenu des messages, qui est un intent
privilégié, donc activez-le sur l'application dans le portail développeur Discord
ou le gestionnaire de messages ne verra jamais que des chaînes vides.
Les clés de Providence vivent à côté dans .env pour le service à l'autre bout de
la prise. Ce binaire ne les lit jamais.
