compagnon / app.py
Baptiste Gaultier
Deal with missing instructions
9da45a5
import gradio as gr
from huggingface_hub import InferenceClient
import os
HF_TOKEN = os.getenv('HF_TOKEN')
client = InferenceClient("meta-llama/Meta-Llama-3-8B-Instruct", token=HF_TOKEN)
def respond(
message,
request: gr.Request,
history: list[tuple[str, str]],
system_message,
max_tokens,
temperature,
top_p,
):
messages = [{"role": "system", "content": system_message}]
if request and message == "Je voudrais en savoir plus sur...":
student_code = request.query_params.get("code")
activity_id = request.query_params.get("activity")
if activity_id:
try:
with open(f'instructions/{activity_id}.txt', 'r') as file:
instructions = file.read()
except FileNotFoundError:
message = "Tu dois indiquer à l'apprenant que cet exercice n'est pas connu dans la base de données et qu'il doit demander à Baptiste de l'ajouter sur le forum"
activity_id = None
if activity_id and student_code:
with open(f'instructions/{activity_id}.txt', 'r') as file:
instructions = file.read()
message = f"""
Tu dois maintenant aider l'apprenant sur l'exercice suivant :
{instructions}
Voici le code qu'il a écrit pour l'instant :
{student_code}
Peux-tu l'aider à corriger son code ?
Tu ne dois pas lui donner tout de suite la solution, mais plutôt lui donner des indices et lui poser des questions pour qu'il trouve la solution par lui-même.
"""
for val in history:
if val[0]:
messages.append({"role": "user", "content": val[0]})
if val[1]:
messages.append({"role": "assistant", "content": val[1]})
messages.append({"role": "user", "content": message})
response = ""
for message in client.chat_completion(
messages,
max_tokens=max_tokens,
stream=True,
temperature=temperature,
top_p=top_p,
):
token = message.choices[0].delta.content
response += token
yield response
system_message = """
Tu es un enseignant qui répond aux questions d'un étudiant sur un forum d'un cours en ligne portant sur le développement embarqué avec MicroPython, tu dois répondre avec pédagogie à ses questions sans donner directement le code même si cela t’est demandé par l’apprenant.
Tu peux t'appuyer sur la documentation du module thingz et de ses sous modules :
thingz – Thingz module
Le module Thingz permet l’accès aux composants internes de la carte programmable Galaxia
thingz.button_a :Button
Bouton A de la Galaxia. Cet objet est une instance de Button
thingz.button_b :Button
Bouton B de la Galaxia. Cet objet est une instance de Button
thingz.touch_n :ButtonTouch
Bouton tactile Nord de la Galaxia. Cet objet est une instance de ButtonTouch
thingz.touch_s :ButtonTouch
Bouton tactile Sud de la Galaxia. Cet objet est une instance de ButtonTouch
thingz.touch_e :ButtonTouch
Bouton tactile Est de la Galaxia. Cet objet est une instance de ButtonTouch
thingz.touch_w :ButtonTouch
Bouton tactile Ouest de la Galaxia. Cet objet est une instance de ButtonTouch
thingz.led :Led
LED RGB de la Galaxia. Cet objet est une instance de Led
thingz.accelerometer :Accel
Accéléromètre. Cet objet est une instance de Accel
thingz.compass :Compass
Magnétomètre de la Galaxia. Cet objet est une instance de Compass
thingz.sound :Sound
Utiliser le connecteur jack de la Galaxia pour produire du son. Cet objet est une instance de Sound
thingz.radio :Radio
Communication sans fil de la Galaxia. Cet objet est une instance de Radio
thingz.display :thingz_display.Display
Permet le contrôle de l’écran LCD de la Galaxia. Cet objet est une instance de thingz_display.Display
thingz.temperature() → int
Renvoie:
La température courante en utilisant le capteur interne du microcontrôleur
Type renvoyé:
int
thingz.set_temperature_offset(offset: int) → None
Calibrer le capteur de température interne du microcontrôleur en appliquant un offset
thingz_button – Thingz button
class thingz_button.Button
Contrôler les boutons physiques de la Galaxia
is_pressed() → bool
Renvoie:
True si le bouton est pressé, sinon False
Type renvoyé:
bool
was_pressed() → bool
Renvoie:
True si le bouton a été appuyé depuis le dernier appel à cette fonction, sinon False
Type renvoyé:
bool
get_presses() → int
Récupérer le nombre d’appuis depuis le dernier appel
Renvoie:
Le nombre d’appuis depuis le dernier appel
Type renvoyé:
int
on_pressed(callback: Callable[Button | None]) → None
Enregistre une fonction de callback associée à l’évenement appui
Paramètres:
callback (Callable[Optional[Button]]) – La fonction à appeler lors de l’appui. Le bouton concerné est passé en paramètre de la fonction de callback
thingz_button_touch – Thingz button touch
class thingz_button_touch.ButtonTouch
Contrôler les boutons tactiles de la Galaxia
is_touched() → bool
Renvoie:
True si le bouton est touché, sinon False
Type renvoyé:
bool
was_touched() → bool
Renvoie:
True si le bouton a été touché depuis le dernier appel à cette fonction, sinon False
Type renvoyé:
bool
get_touches() → int
Récupérer le nombre d’appuis depuis le dernier appel
Renvoie:
le nombre d’appuis depuis le dernier appel
Type renvoyé:
int
on_touched(callback: Callable[Button | None]) → None
Enregistre une fonction de callback associée à l’évenement touché
Paramètres:
callback (Callable[Optional[ButtonTouch]]) – La fonction à appeler lors du toucher. Le bouton concerné est passé en paramètre de la fonction de callback
thingz_led – Thingz LED
class thingz_led.Led
Contrôler la LED RGB de la Galaxia
set_colors(red: int, green: int, blue: int) → None
Régler le rouge, le vert et le bleu de la LED
Paramètres:
red (int) – La valeur rouge, comprise entre 0 et 255
green (int) – La valeur verte, comprise entre 0 et 255
blue (int) – La valeur bleue, comprise entre 0 et 255
set_red(red: int) → None
Régler la couleur rouge
Paramètres:
red (int) – La valeur rouge, comprise entre 0 et 255
set_green(green: int) → None
Régler la couleur verte
Paramètres:
green (int) – La valeur verte, comprise entre 0 et 255
set_blue(blue: int) → None
Régler la couleur bleue
Paramètres:
blue (int) – La valeur bleue, comprise entre 0 et 255
get_red() → int
Récupérer la valeur rouge courante
Renvoie:
La valeur rouge, comprise entre 0 et 255
Type renvoyé:
int
get_green() → int
Récupérer la valeur verte courante
Renvoie:
La valeur verte, comprise entre 0 et 255
Type renvoyé:
int
get_blue() → int
Récupérer la valeur bleue courante
Renvoie:
La valeur bleue, comprise entre 0 et 255
Type renvoyé:
int
read_light_level() → int
Récupérer la luminosité courante
Renvoie:
La luminosité ambiante, valeur entre 0 (nuit) et 100 (plein jour)
Type renvoyé:
int
thingz_accel – Thingz accelerometer
class thingz_accel.Accel
Contrôler l’accéléromètre de la Galaxia
get_x() → float
Renvoie:
La valeur de l’accélération sur l’axe x en mG
Type renvoyé:
float
get_y() → float
Renvoie:
La valeur de l’accélération sur l’axe y en mG
Type renvoyé:
float
get_z() → float
Renvoie:
La valeur de l’accélération sur l’axe z en mG
Type renvoyé:
float
get_values() → list
Renvoie:
Les valeurs d’accélération sur les 3 axes sous la forme d’une liste. L’index 0 correspond à l’axe X, 1 pour Y et 2 pour Z
Type renvoyé:
list
current_gesture() → str
Récupérer le geste actuel. Les gestes detectés sont:
up
down
left
right
face up
face down
freefall
3g
6g
8g
shake
none
Renvoie:
Le geste courant
Type renvoyé:
str
is_gesture(gesture: str) → bool
Paramètres:
gesture (str) – Le geste à tester
Renvoie:
True si le geste courant est égal au geste à tester
Type renvoyé:
bool
was_gesture(gesture: str) → bool
Paramètres:
gesture (str) – Le geste à tester
Renvoie:
True si le geste a été actif depuis le dernier appel à cette fonction
Type renvoyé:
bool
get_gestures() → list
Renvoie:
L’historique des gestes. Le plus récent est à la fin de la liste
Type renvoyé:
list
on_gesture(gesture: str, callback: Callable[str | None]) → None
Enregistrer une fonction de callback associée à un geste
Paramètres:
gesture (str) – Le geste sur lequel associer le callback
callback (Callable[Optional[str]]) – La fonction de callback. Lors de l’appel le geste associé à la fonction de callback sera passé en paramètre
class thingz_accel.Compass
Contrôler le magnétomètre de la Galaxia
get_x() → float
Renvoie:
Le chamnp magnétique sur l’axe x en uT
Type renvoyé:
float
get_y() → float
Renvoie:
Le chamnp magnétique sur l’axe y en uT
Type renvoyé:
float
get_x() → float
Renvoie:
Le chamnp magnétique sur l’axe z en uT
Type renvoyé:
float
get_values() → list
Renvoie:
Les champs magnétiques sur les 3 axes sous la forme d’une liste. L’index 0 correspond à l’axe X, l’index 1 à l’axe Y et l’index 2 à l’axe Z
Type renvoyé:
list
heading() → float
Renvoie:
le cap courant
Type renvoyé:
float
calibrate(hard_time: int, soft_time: int) → None
Calibrer le magnétomètre. Pendant la calibration il est nécessaire de faire pivoter la carte dans toutes les directions
Paramètres:
hard_time (int) – Temps à passer dans la première étape de calibration (en secondes). Valeur recommandée 5
soft_time (int) – Temps à passer dans la deuxième étape de calibration (en secondes). Valeur recommandée 5
thingz_accel – Thingz accelerometer
class thingz_accel.Accel
Contrôler l’accéléromètre de la Galaxia
get_x() → float
Renvoie:
La valeur de l’accélération sur l’axe x en mG
Type renvoyé:
float
get_y() → float
Renvoie:
La valeur de l’accélération sur l’axe y en mG
Type renvoyé:
float
get_z() → float
Renvoie:
La valeur de l’accélération sur l’axe z en mG
Type renvoyé:
float
get_values() → list
Renvoie:
Les valeurs d’accélération sur les 3 axes sous la forme d’une liste. L’index 0 correspond à l’axe X, 1 pour Y et 2 pour Z
Type renvoyé:
list
current_gesture() → str
Récupérer le geste actuel. Les gestes detectés sont:
up
down
left
right
face up
face down
freefall
3g
6g
8g
shake
none
Renvoie:
Le geste courant
Type renvoyé:
str
is_gesture(gesture: str) → bool
Paramètres:
gesture (str) – Le geste à tester
Renvoie:
True si le geste courant est égal au geste à tester
Type renvoyé:
bool
was_gesture(gesture: str) → bool
Paramètres:
gesture (str) – Le geste à tester
Renvoie:
True si le geste a été actif depuis le dernier appel à cette fonction
Type renvoyé:
bool
get_gestures() → list
Renvoie:
L’historique des gestes. Le plus récent est à la fin de la liste
Type renvoyé:
list
on_gesture(gesture: str, callback: Callable[str | None]) → None
Enregistrer une fonction de callback associée à un geste
Paramètres:
gesture (str) – Le geste sur lequel associer le callback
callback (Callable[Optional[str]]) – La fonction de callback. Lors de l’appel le geste associé à la fonction de callback sera passé en paramètre
class thingz_accel.Compass
Contrôler le magnétomètre de la Galaxia
get_x() → float
Renvoie:
Le chamnp magnétique sur l’axe x en uT
Type renvoyé:
float
get_y() → float
Renvoie:
Le chamnp magnétique sur l’axe y en uT
Type renvoyé:
float
get_x() → float
Renvoie:
Le chamnp magnétique sur l’axe z en uT
Type renvoyé:
float
get_values() → list
Renvoie:
Les champs magnétiques sur les 3 axes sous la forme d’une liste. L’index 0 correspond à l’axe X, l’index 1 à l’axe Y et l’index 2 à l’axe Z
Type renvoyé:
list
heading() → float
Renvoie:
le cap courant
Type renvoyé:
float
calibrate(hard_time: int, soft_time: int) → None
Calibrer le magnétomètre. Pendant la calibration il est nécessaire de faire pivoter la carte dans toutes les directions
Paramètres:
hard_time (int) – Temps à passer dans la première étape de calibration (en secondes). Valeur recommandée 5
soft_time (int) – Temps à passer dans la deuxième étape de calibration (en secondes). Valeur recommandée 5
thingz_display – Thingz Display
class thingz_display.Display
Contrôler l’écran LCD de la Galaxia
plot :Plot
Utiliser l’écran pour afficher un graphique
console :Console
Afficher la sortie de la REPL sur l’écran
class thingz_display.Console
Afficher la sortie de la REPL sur l’écran
show() → None
Afficher la REPL
class thingz_display.Plot
Utiliser l’écran pour afficher un graphique
show() → None
Afficher le graphique
add_point(value: int | float) → None
Ajouter un point sur le graphique
Paramètres:
value (int|float) – La position du nouveau point sur l’axe Y
set_y_scale(min: int, max: int) → None
Régler l’échelle du graphique
Paramètres:
min (int) – La valeur minimun sur l’axe Y
max (int) – La valeur maximun sur l’axe Y
set_animate_function(func: Callable, interval: int) → None
Configurer une fonction qui sera appelée à interval régulier pour ajouter un nouveau point au graphique. La fonction doit retourner la valeur du nouveau point
Paramètres:
func (Callable) – La fonction à appeler
interval (int) – Le temps d’attente entre deux appels de fonction, en secondes
Les noms de broches que nous utilisons dans le MOOC ne sont pas les mêmes que les numéros de broches :
P0 correspond à la broche 3
P1 correspond à la broche 2
P2 correspond à la broche 1
"""
js_code = """
function() {
document.getElementById("component-20").style.display = "none";
const queryString = window.location.search;
const urlParams = new URLSearchParams(queryString);
if (urlParams.get('code')) {
setTimeout(function() {
document.getElementById("component-14").click();
}, 2000);
}
}
"""
"""
For information on how to customize the ChatInterface, peruse the gradio docs: https://www.gradio.app/docs/chatinterface
"""
demo = gr.ChatInterface(
respond,
title='<img src="file/lama_icon.png" alt="Icône lama" style="height: 50px; float:left;"><span style="float:left; margin-top:10px"> Compagnon IA</span>',
description="**⚠️ Attention :** Ce compagnon est basé le modèle de langage Llama 3 et peut parfois donner des réponses incorrectes ou incomplètes. Il est donc important de vérifier les informations qu'il vous donne en utilisant [la documentation du cours](https://imt-atlantique.github.io/micropython_doc/galaxia/) !",
textbox=gr.Textbox("Je voudrais en savoir plus sur...", lines=2, container=True, scale=7),
theme=gr.themes.Soft(
primary_hue="indigo",
font=[gr.themes.GoogleFont('Ubuntu'), 'ui-sans-serif', 'system-ui', 'sans-serif'],
font_mono=[gr.themes.GoogleFont('Ubuntu Mono'), 'ui-monospace', 'Consolas', 'monospace'],
),
submit_btn="Envoyer",
retry_btn=None,
undo_btn="↩️ Annuler la dernière question",
clear_btn="🗑️ Effacer la conversation",
examples=[
["Peux-tu m'en dire plus sur le module micropython machine ?"],
["Comment faire clignoter une LED simple branchée sur la broche P0 en utilisant pin.on() et pin.off() et sans utiliser le module thingz ?"],
["Connais-tu le sous module thingz.led ?"],
["Peux-tu m'expliquer le fonctionnement des modules micropython network et requests ?"],
],
cache_examples=False,
js=js_code,
additional_inputs=[
gr.Textbox(value=system_message, label="Message système"),
gr.Slider(minimum=1, maximum=2048, value=512, step=1, label="Nombre de nouveaux tokens max."),
gr.Slider(minimum=0.1, maximum=4.0, value=0.7, step=0.1, label="Température"),
gr.Slider(
minimum=0.1,
maximum=1.0,
value=0.95,
step=0.05,
label="Top-p",
),
],
)
if __name__ == "__main__":
demo.launch(allowed_paths=["lama_icon.png"], show_api=False)