BryanBradfo commited on
Commit
549e88f
·
verified ·
1 Parent(s): 9021690

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +40 -61
app.py CHANGED
@@ -1,57 +1,38 @@
1
- import os
2
  import sys
3
- import shutil
4
  from types import ModuleType
 
5
 
6
  # ==========================================
7
- # 🔧 PATCH CHIRURGICAL AUTOMATIQUE
8
  # ==========================================
9
- # Ce bloc répare les incompatibilités entre Gradio 4 et gradio_chessboard
10
- def patch_libraries():
11
- print("🔧 Application des patchs de compatibilité...")
12
-
13
- # 1. Patch pour gradio.i18n (Manquant dans Gradio 4)
14
- import gradio as gr
15
- if not hasattr(gr, "i18n"):
16
- mock_i18n = ModuleType("gradio.i18n")
17
- mock_i18n.I18nData = str
18
- sys.modules["gradio.i18n"] = mock_i18n
19
- gr.i18n = mock_i18n
20
- print("✅ Patch i18n appliqué.")
21
-
22
- # 2. Patch pour preserved_by_key (Argument inconnu dans Gradio 4)
23
- # On va lire le fichier source de la librairie et supprimer l'argument fautif
24
- try:
25
- import site
26
- packages_dirs = site.getsitepackages()
27
- for dir_path in packages_dirs:
28
- lib_path = os.path.join(dir_path, "gradio_chessboard", "chessboard.py")
29
- if os.path.exists(lib_path):
30
- with open(lib_path, 'r') as f:
31
- content = f.read()
32
-
33
- # Si le fichier contient l'argument problématique, on le nettoie
34
- if "preserved_by_key" in content:
35
- # On supprime l'argument de l'appel super().__init__
36
- new_content = content.replace(", preserved_by_key=preserved_by_key", "")
37
- # On supprime l'argument de la définition __init__ (plus délicat, on le fait bourrin mais sûr)
38
- # On ne touche pas à la définition, car Python acceptera l'argument inutilisé,
39
- # l'important est de ne pas le passer au super().
40
-
41
- with open(lib_path, 'w') as f:
42
- f.write(new_content)
43
- print(f"✅ Patch preserved_by_key appliqué sur {lib_path}")
44
- break
45
- except Exception as e:
46
- print(f"⚠️ Attention: Impossible de patcher le fichier source: {e}")
47
 
48
- # Exécuter le patch AVANT d'importer Chessboard
49
- patch_libraries()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
 
51
  # ==========================================
52
- # 🚀 DÉBUT DE L'APPLICATION
53
  # ==========================================
54
- import gradio as gr
55
  from gradio_chessboard import Chessboard
56
  import chess
57
  from openai import OpenAI
@@ -67,20 +48,18 @@ eleven_client = ElevenLabs(api_key=ELEVEN_API_KEY) if ELEVEN_API_KEY else None
67
 
68
  # --- Persona du Coach ---
69
  SYSTEM_PROMPT = """
70
- Tu es Garry, un Grand Maître d'échecs légendaire et un peu arrogant mais pédagogique.
71
  Tu commentes la partie en direct pour un débutant.
72
- Reçois l'analyse JSON de la position.
73
  1. Analyse le déséquilibre matériel et l'ouverture.
74
- 2. Si le joueur est en échec ou fait une erreur, sois critique (humour cinglant).
75
  3. Si le coup est bon, sois impressionné.
76
- 4. Reste très court (2 phrases max) pour un commentaire audio fluide.
77
  """
78
 
79
  def generate_voice(text):
80
  """Génère l'audio via ElevenLabs"""
81
  if not eleven_client or not text: return None
82
  try:
83
- # Utilisation de 'Brian' pour un ton sérieux/anglais ou une voix FR si dispo
84
  audio_stream = eleven_client.generate(
85
  text=text,
86
  voice="Rachel",
@@ -91,18 +70,19 @@ def generate_voice(text):
91
  for chunk in audio_stream:
92
  f.write(chunk)
93
  return path
94
- except:
 
95
  return None
96
 
97
  def process_move(fen):
98
  """Cerveau de l'agent"""
99
  if not fen: return "", None
100
 
101
- # 1. Analyse Technique (MCP Local)
102
  analysis = analyze_position(fen)
103
 
104
- # 2. Génération du Commentaire (LLM)
105
- commentary = "En attente de l'IA..."
106
  if openai_client:
107
  try:
108
  response = openai_client.chat.completions.create(
@@ -116,7 +96,7 @@ def process_move(fen):
116
  except Exception as e:
117
  commentary = f"Erreur IA: {e}"
118
  else:
119
- commentary = "Clés API manquantes. Configurez les secrets."
120
 
121
  # 3. Génération Audio
122
  audio_path = generate_voice(commentary)
@@ -129,7 +109,7 @@ with gr.Blocks(title="ChessCoach AI") as demo:
129
  """
130
  # ♟️ ChessCoach AI
131
  ### Votre Grand Maître Personnel (Powered by MCP)
132
- Jouez contre vous-même ou analysez une partie. Garry vous regarde et vous juge en direct !
133
  """
134
  )
135
 
@@ -144,14 +124,13 @@ with gr.Blocks(title="ChessCoach AI") as demo:
144
  )
145
 
146
  with gr.Column(scale=1):
147
- gr.Markdown("### 🎙️ Commentaires en Direct")
148
- coach_output = gr.Textbox(label="Garry dit :", interactive=False, lines=3)
149
  audio_output = gr.Audio(label="Voix", autoplay=True, interactive=False)
150
 
151
- with gr.Accordion("🔍 Analyse Technique (Debug)", open=False):
152
- debug_json = gr.JSON(label="Données MCP")
153
 
154
- # Logique
155
  def game_loop(fen):
156
  text, audio = process_move(fen)
157
  debug = analyze_position(fen)
 
 
1
  import sys
 
2
  from types import ModuleType
3
+ import os
4
 
5
  # ==========================================
6
+ # 🛡️ ZONE DE PATCH (NE PAS TOUCHER)
7
  # ==========================================
8
+ import gradio as gr
9
+ from gradio.components.base import Component
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
 
11
+ # 1. Patch i18n (Le module manquant)
12
+ if not hasattr(gr, "i18n"):
13
+ mock_i18n = ModuleType("gradio.i18n")
14
+ mock_i18n.I18nData = str
15
+ sys.modules["gradio.i18n"] = mock_i18n
16
+ gr.i18n = mock_i18n
17
+
18
+ # 2. Patch Component.__init__ (L'argument inconnu)
19
+ # On sauvegarde l'initialisation originale de Gradio
20
+ original_init = Component.__init__
21
+
22
+ def patched_init(self, *args, **kwargs):
23
+ # Si on trouve l'argument fautif 'preserved_by_key', on le retire (pop)
24
+ # avant de passer la main au vrai Gradio.
25
+ kwargs.pop("preserved_by_key", None)
26
+ original_init(self, *args, **kwargs)
27
+
28
+ # On remplace l'init officiel par notre version tolérante
29
+ Component.__init__ = patched_init
30
+ print("✅ Patchs de compatibilité appliqués avec succès.")
31
 
32
  # ==========================================
33
+ # ♟️ DÉBUT DE L'APPLICATION
34
  # ==========================================
35
+
36
  from gradio_chessboard import Chessboard
37
  import chess
38
  from openai import OpenAI
 
48
 
49
  # --- Persona du Coach ---
50
  SYSTEM_PROMPT = """
51
+ Tu es Garry, un Grand Maître d'échecs légendaire.
52
  Tu commentes la partie en direct pour un débutant.
 
53
  1. Analyse le déséquilibre matériel et l'ouverture.
54
+ 2. Si le joueur est en échec ou fait une erreur, sois critique avec humour.
55
  3. Si le coup est bon, sois impressionné.
56
+ 4. Reste très court (2 phrases max) pour l'audio.
57
  """
58
 
59
  def generate_voice(text):
60
  """Génère l'audio via ElevenLabs"""
61
  if not eleven_client or not text: return None
62
  try:
 
63
  audio_stream = eleven_client.generate(
64
  text=text,
65
  voice="Rachel",
 
70
  for chunk in audio_stream:
71
  f.write(chunk)
72
  return path
73
+ except Exception as e:
74
+ print(f"Erreur ElevenLabs: {e}")
75
  return None
76
 
77
  def process_move(fen):
78
  """Cerveau de l'agent"""
79
  if not fen: return "", None
80
 
81
+ # 1. Analyse Technique
82
  analysis = analyze_position(fen)
83
 
84
+ # 2. Génération du Commentaire
85
+ commentary = "Analyse en cours..."
86
  if openai_client:
87
  try:
88
  response = openai_client.chat.completions.create(
 
96
  except Exception as e:
97
  commentary = f"Erreur IA: {e}"
98
  else:
99
+ commentary = "Veuillez configurer les clés API (OpenAI/ElevenLabs)."
100
 
101
  # 3. Génération Audio
102
  audio_path = generate_voice(commentary)
 
109
  """
110
  # ♟️ ChessCoach AI
111
  ### Votre Grand Maître Personnel (Powered by MCP)
112
+ Jouez les Blancs. L'IA analyse votre position et vous coache vocalement.
113
  """
114
  )
115
 
 
124
  )
125
 
126
  with gr.Column(scale=1):
127
+ gr.Markdown("### 🎙️ Coach Garry")
128
+ coach_output = gr.Textbox(label="Analyse", interactive=False, lines=3)
129
  audio_output = gr.Audio(label="Voix", autoplay=True, interactive=False)
130
 
131
+ with gr.Accordion("🔍 Données MCP", open=False):
132
+ debug_json = gr.JSON(label="État Technique")
133
 
 
134
  def game_loop(fen):
135
  text, audio = process_move(fen)
136
  debug = analyze_position(fen)