django-lucy-assist 1.1.0__py3-none-any.whl → 1.2.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,258 +1,288 @@
1
1
  """
2
- Définition des tools pour l'API Claude.
2
+ Definition des tools pour l'API Mistral.
3
3
 
4
- Ces tools permettent à Lucy Assist d'exécuter des actions CRUD
4
+ Ces tools permettent a Lucy Assist d'executer des actions CRUD
5
5
  directement dans l'application.
6
+
7
+ Format: Compatible OpenAI/Mistral (type: function)
6
8
  """
7
9
 
8
- # Tools disponibles pour Claude
10
+ # Tools disponibles pour Mistral (format OpenAI)
9
11
  LUCY_ASSIST_TOOLS = [
10
12
  {
11
- "name": "create_object",
12
- "description": """Crée un nouvel objet dans la base de données.
13
- Utilise ce tool quand l'utilisateur demande de créer un objet métier (client, facture, etc.).
14
- IMPORTANT: Utilise ce tool en priorité quand l'utilisateur demande une création.
15
- Ne demande pas de confirmation, exécute directement l'action.""",
16
- "input_schema": {
17
- "type": "object",
18
- "properties": {
19
- "app_name": {
20
- "type": "string",
21
- "description": "Nom de l'application Django (ex: client, facture)"
22
- },
23
- "model_name": {
24
- "type": "string",
25
- "description": "Nom du modèle Django (ex: Client, Facture)"
13
+ "type": "function",
14
+ "function": {
15
+ "name": "create_object",
16
+ "description": """Cree un nouvel objet dans la base de donnees.
17
+ Utilise ce tool quand l'utilisateur demande de creer un objet metier (client, facture, etc.).
18
+ IMPORTANT: Utilise ce tool en priorite quand l'utilisateur demande une creation.
19
+ Ne demande pas de confirmation, execute directement l'action.""",
20
+ "parameters": {
21
+ "type": "object",
22
+ "properties": {
23
+ "app_name": {
24
+ "type": "string",
25
+ "description": "Nom de l'application Django (ex: client, facture)"
26
+ },
27
+ "model_name": {
28
+ "type": "string",
29
+ "description": "Nom du modele Django (ex: Client, Facture)"
30
+ },
31
+ "data": {
32
+ "type": "object",
33
+ "description": "Donnees pour creer l'objet. Les cles sont les noms des champs du modele.",
34
+ "additionalProperties": True
35
+ }
26
36
  },
27
- "data": {
28
- "type": "object",
29
- "description": "Données pour créer l'objet. Les clés sont les noms des champs du modèle.",
30
- "additionalProperties": True
31
- }
32
- },
33
- "required": ["app_name", "model_name", "data"]
37
+ "required": ["app_name", "model_name", "data"]
38
+ }
34
39
  }
35
40
  },
36
41
  {
37
- "name": "update_object",
38
- "description": """Met à jour un objet existant dans la base de données.
39
- Utilise ce tool quand l'utilisateur demande de modifier un objet existant.
40
- IMPORTANT: Exécute directement l'action sans demander de confirmation.""",
41
- "input_schema": {
42
- "type": "object",
43
- "properties": {
44
- "app_name": {
45
- "type": "string",
46
- "description": "Nom de l'application Django"
47
- },
48
- "model_name": {
49
- "type": "string",
50
- "description": "Nom du modèle Django"
51
- },
52
- "object_id": {
53
- "type": "integer",
54
- "description": "ID de l'objet à modifier"
42
+ "type": "function",
43
+ "function": {
44
+ "name": "update_object",
45
+ "description": """Met a jour un objet existant dans la base de donnees.
46
+ Utilise ce tool quand l'utilisateur demande de modifier un objet existant.
47
+ IMPORTANT: Execute directement l'action sans demander de confirmation.""",
48
+ "parameters": {
49
+ "type": "object",
50
+ "properties": {
51
+ "app_name": {
52
+ "type": "string",
53
+ "description": "Nom de l'application Django"
54
+ },
55
+ "model_name": {
56
+ "type": "string",
57
+ "description": "Nom du modele Django"
58
+ },
59
+ "object_id": {
60
+ "type": "integer",
61
+ "description": "ID de l'objet a modifier"
62
+ },
63
+ "data": {
64
+ "type": "object",
65
+ "description": "Donnees a mettre a jour",
66
+ "additionalProperties": True
67
+ }
55
68
  },
56
- "data": {
57
- "type": "object",
58
- "description": "Données à mettre à jour",
59
- "additionalProperties": True
60
- }
61
- },
62
- "required": ["app_name", "model_name", "object_id", "data"]
69
+ "required": ["app_name", "model_name", "object_id", "data"]
70
+ }
63
71
  }
64
72
  },
65
73
  {
66
- "name": "get_deletion_impact",
67
- "description": """Analyse l'impact d'une suppression AVANT de supprimer.
68
- OBLIGATOIRE: Utilise TOUJOURS ce tool AVANT delete_object pour montrer à l'utilisateur
69
- toutes les conséquences de la suppression (objets supprimés en cascade, champs mis à NULL, etc.)
70
- Affiche le résultat à l'utilisateur et demande sa confirmation explicite avant de supprimer.""",
71
- "input_schema": {
72
- "type": "object",
73
- "properties": {
74
- "app_name": {
75
- "type": "string",
76
- "description": "Nom de l'application Django"
74
+ "type": "function",
75
+ "function": {
76
+ "name": "get_deletion_impact",
77
+ "description": """Analyse l'impact d'une suppression AVANT de supprimer.
78
+ OBLIGATOIRE: Utilise TOUJOURS ce tool AVANT delete_object pour montrer a l'utilisateur
79
+ toutes les consequences de la suppression (objets supprimes en cascade, champs mis a NULL, etc.)
80
+ Affiche le resultat a l'utilisateur et demande sa confirmation explicite avant de supprimer.""",
81
+ "parameters": {
82
+ "type": "object",
83
+ "properties": {
84
+ "app_name": {
85
+ "type": "string",
86
+ "description": "Nom de l'application Django"
87
+ },
88
+ "model_name": {
89
+ "type": "string",
90
+ "description": "Nom du modele Django"
91
+ },
92
+ "object_id": {
93
+ "type": "integer",
94
+ "description": "ID de l'objet a analyser"
95
+ }
77
96
  },
78
- "model_name": {
79
- "type": "string",
80
- "description": "Nom du modèle Django"
81
- },
82
- "object_id": {
83
- "type": "integer",
84
- "description": "ID de l'objet à analyser"
85
- }
86
- },
87
- "required": ["app_name", "model_name", "object_id"]
97
+ "required": ["app_name", "model_name", "object_id"]
98
+ }
88
99
  }
89
100
  },
90
101
  {
91
- "name": "delete_object",
92
- "description": """Supprime un objet de la base de données.
93
- IMPORTANT: Tu DOIS d'abord utiliser get_deletion_impact pour analyser les conséquences,
94
- puis afficher le résultat à l'utilisateur, et obtenir sa CONFIRMATION EXPLICITE avant d'exécuter ce tool.
95
- Ne JAMAIS supprimer sans avoir montré l'impact et obtenu confirmation.""",
96
- "input_schema": {
97
- "type": "object",
98
- "properties": {
99
- "app_name": {
100
- "type": "string",
101
- "description": "Nom de l'application Django"
102
- },
103
- "model_name": {
104
- "type": "string",
105
- "description": "Nom du modèle Django"
102
+ "type": "function",
103
+ "function": {
104
+ "name": "delete_object",
105
+ "description": """Supprime un objet de la base de donnees.
106
+ IMPORTANT: Tu DOIS d'abord utiliser get_deletion_impact pour analyser les consequences,
107
+ puis afficher le resultat a l'utilisateur, et obtenir sa CONFIRMATION EXPLICITE avant d'executer ce tool.
108
+ Ne JAMAIS supprimer sans avoir montre l'impact et obtenu confirmation.""",
109
+ "parameters": {
110
+ "type": "object",
111
+ "properties": {
112
+ "app_name": {
113
+ "type": "string",
114
+ "description": "Nom de l'application Django"
115
+ },
116
+ "model_name": {
117
+ "type": "string",
118
+ "description": "Nom du modele Django"
119
+ },
120
+ "object_id": {
121
+ "type": "integer",
122
+ "description": "ID de l'objet a supprimer"
123
+ },
124
+ "confirmed": {
125
+ "type": "boolean",
126
+ "description": "OBLIGATOIRE: true si l'utilisateur a explicitement confirme la suppression apres avoir vu l'impact"
127
+ }
106
128
  },
107
- "object_id": {
108
- "type": "integer",
109
- "description": "ID de l'objet à supprimer"
110
- },
111
- "confirmed": {
112
- "type": "boolean",
113
- "description": "OBLIGATOIRE: true si l'utilisateur a explicitement confirmé la suppression après avoir vu l'impact"
114
- }
115
- },
116
- "required": ["app_name", "model_name", "object_id", "confirmed"]
129
+ "required": ["app_name", "model_name", "object_id", "confirmed"]
130
+ }
117
131
  }
118
132
  },
119
133
  {
120
- "name": "search_objects",
121
- "description": """Recherche des objets dans la base de données.
122
- Utilise ce tool pour trouver des clients, réservations, ou tout autre objet métier.""",
123
- "input_schema": {
124
- "type": "object",
125
- "properties": {
126
- "query": {
127
- "type": "string",
128
- "description": "Terme de recherche"
129
- },
130
- "model_name": {
131
- "type": "string",
132
- "description": "Nom du modèle à rechercher (optionnel, cherche dans tous si non spécifié)"
134
+ "type": "function",
135
+ "function": {
136
+ "name": "search_objects",
137
+ "description": """Recherche des objets dans la base de donnees.
138
+ Utilise ce tool pour trouver des clients, reservations, ou tout autre objet metier.""",
139
+ "parameters": {
140
+ "type": "object",
141
+ "properties": {
142
+ "query": {
143
+ "type": "string",
144
+ "description": "Terme de recherche"
145
+ },
146
+ "model_name": {
147
+ "type": "string",
148
+ "description": "Nom du modele a rechercher (optionnel, cherche dans tous si non specifie)"
149
+ },
150
+ "limit": {
151
+ "type": "integer",
152
+ "description": "Nombre maximum de resultats (defaut: 10)",
153
+ "default": 10
154
+ }
133
155
  },
134
- "limit": {
135
- "type": "integer",
136
- "description": "Nombre maximum de résultats (défaut: 10)",
137
- "default": 10
138
- }
139
- },
140
- "required": ["query"]
156
+ "required": ["query"]
157
+ }
141
158
  }
142
159
  },
143
160
  {
144
- "name": "get_object_details",
145
- "description": """Récupère les détails d'un objet spécifique.""",
146
- "input_schema": {
147
- "type": "object",
148
- "properties": {
149
- "app_name": {
150
- "type": "string",
151
- "description": "Nom de l'application Django"
161
+ "type": "function",
162
+ "function": {
163
+ "name": "get_object_details",
164
+ "description": """Recupere les details d'un objet specifique.""",
165
+ "parameters": {
166
+ "type": "object",
167
+ "properties": {
168
+ "app_name": {
169
+ "type": "string",
170
+ "description": "Nom de l'application Django"
171
+ },
172
+ "model_name": {
173
+ "type": "string",
174
+ "description": "Nom du modele Django"
175
+ },
176
+ "object_id": {
177
+ "type": "integer",
178
+ "description": "ID de l'objet"
179
+ }
152
180
  },
153
- "model_name": {
154
- "type": "string",
155
- "description": "Nom du modèle Django"
156
- },
157
- "object_id": {
158
- "type": "integer",
159
- "description": "ID de l'objet"
160
- }
161
- },
162
- "required": ["app_name", "model_name", "object_id"]
181
+ "required": ["app_name", "model_name", "object_id"]
182
+ }
163
183
  }
164
184
  },
165
185
  {
166
- "name": "get_form_fields",
167
- "description": """Récupère les champs requis et optionnels d'un formulaire.
168
- Utilise ce tool uniquement si tu as besoin de connaître les champs avant de créer un objet,
169
- ou si l'utilisateur demande explicitement quels champs sont disponibles.""",
170
- "input_schema": {
171
- "type": "object",
172
- "properties": {
173
- "app_name": {
174
- "type": "string",
175
- "description": "Nom de l'application Django"
186
+ "type": "function",
187
+ "function": {
188
+ "name": "get_form_fields",
189
+ "description": """Recupere les champs requis et optionnels d'un formulaire.
190
+ Utilise ce tool uniquement si tu as besoin de connaitre les champs avant de creer un objet,
191
+ ou si l'utilisateur demande explicitement quels champs sont disponibles.""",
192
+ "parameters": {
193
+ "type": "object",
194
+ "properties": {
195
+ "app_name": {
196
+ "type": "string",
197
+ "description": "Nom de l'application Django"
198
+ },
199
+ "model_name": {
200
+ "type": "string",
201
+ "description": "Nom du modele Django"
202
+ }
176
203
  },
177
- "model_name": {
178
- "type": "string",
179
- "description": "Nom du modèle Django"
180
- }
181
- },
182
- "required": ["app_name", "model_name"]
204
+ "required": ["app_name", "model_name"]
205
+ }
183
206
  }
184
207
  },
185
208
  {
186
- "name": "navigate_to_page",
187
- "description": """Génère une URL pour naviguer vers une page spécifique.
188
- Utilise ce tool uniquement si l'utilisateur demande explicitement d'aller quelque part
189
- ou si tu as besoin de lui montrer aller.""",
190
- "input_schema": {
191
- "type": "object",
192
- "properties": {
193
- "page_type": {
194
- "type": "string",
195
- "enum": ["list", "create", "detail", "edit"],
196
- "description": "Type de page"
197
- },
198
- "app_name": {
199
- "type": "string",
200
- "description": "Nom de l'application"
209
+ "type": "function",
210
+ "function": {
211
+ "name": "navigate_to_page",
212
+ "description": """Genere une URL pour naviguer vers une page specifique.
213
+ Utilise ce tool uniquement si l'utilisateur demande explicitement d'aller quelque part
214
+ ou si tu as besoin de lui montrer ou aller.""",
215
+ "parameters": {
216
+ "type": "object",
217
+ "properties": {
218
+ "page_type": {
219
+ "type": "string",
220
+ "enum": ["list", "create", "detail", "edit"],
221
+ "description": "Type de page"
222
+ },
223
+ "app_name": {
224
+ "type": "string",
225
+ "description": "Nom de l'application"
226
+ },
227
+ "model_name": {
228
+ "type": "string",
229
+ "description": "Nom du modele"
230
+ },
231
+ "object_id": {
232
+ "type": "integer",
233
+ "description": "ID de l'objet (pour detail/edit)"
234
+ }
201
235
  },
202
- "model_name": {
203
- "type": "string",
204
- "description": "Nom du modèle"
205
- },
206
- "object_id": {
207
- "type": "integer",
208
- "description": "ID de l'objet (pour detail/edit)"
209
- }
210
- },
211
- "required": ["page_type", "app_name", "model_name"]
236
+ "required": ["page_type", "app_name", "model_name"]
237
+ }
212
238
  }
213
239
  },
214
240
  {
215
- "name": "analyze_bug",
216
- "description": """Analyse un bug potentiel en se connectant à GitLab pour examiner le code source.
217
- Utilise ce tool quand l'utilisateur signale un problème technique, une erreur, ou un comportement inattendu.
218
- Ce tool analyse le code via GitLab et si un bug est détecté, envoie automatiquement une notification
219
- à l'équipe Revolucy pour correction.
220
- IMPORTANT: Utilise ce tool dès qu'un utilisateur signale un message d'erreur ou un dysfonctionnement.""",
221
- "input_schema": {
222
- "type": "object",
223
- "properties": {
224
- "user_description": {
225
- "type": "string",
226
- "description": "Description du problème par l'utilisateur (obligatoire)"
227
- },
228
- "error_message": {
229
- "type": "string",
230
- "description": "Message d'erreur exact (si disponible)"
241
+ "type": "function",
242
+ "function": {
243
+ "name": "analyze_bug",
244
+ "description": """Analyse un bug potentiel en se connectant a GitLab pour examiner le code source.
245
+ Utilise ce tool quand l'utilisateur signale un probleme technique, une erreur, ou un comportement inattendu.
246
+ Ce tool analyse le code via GitLab et si un bug est detecte, envoie automatiquement une notification
247
+ a l'equipe Revolucy pour correction.
248
+ IMPORTANT: Utilise ce tool des qu'un utilisateur signale un message d'erreur ou un dysfonctionnement.""",
249
+ "parameters": {
250
+ "type": "object",
251
+ "properties": {
252
+ "user_description": {
253
+ "type": "string",
254
+ "description": "Description du probleme par l'utilisateur (obligatoire)"
255
+ },
256
+ "error_message": {
257
+ "type": "string",
258
+ "description": "Message d'erreur exact (si disponible)"
259
+ },
260
+ "page_url": {
261
+ "type": "string",
262
+ "description": "URL de la page ou le probleme se produit"
263
+ },
264
+ "model_name": {
265
+ "type": "string",
266
+ "description": "Nom du modele Django concerne (si identifiable, ex: Client, Reservation)"
267
+ },
268
+ "action_type": {
269
+ "type": "string",
270
+ "enum": ["create", "update", "delete", "list", "search", "other"],
271
+ "description": "Type d'action qui a cause le probleme"
272
+ }
231
273
  },
232
- "page_url": {
233
- "type": "string",
234
- "description": "URL de la page où le problème se produit"
235
- },
236
- "model_name": {
237
- "type": "string",
238
- "description": "Nom du modèle Django concerné (si identifiable, ex: Client, Reservation)"
239
- },
240
- "action_type": {
241
- "type": "string",
242
- "enum": ["create", "update", "delete", "list", "search", "other"],
243
- "description": "Type d'action qui a causé le problème"
244
- }
245
- },
246
- "required": ["user_description"]
274
+ "required": ["user_description"]
275
+ }
247
276
  }
248
277
  }
249
278
  ]
250
279
 
280
+
251
281
  def get_app_for_model(model_name: str) -> str:
252
282
  """
253
- Retourne le nom de l'app Django pour un modèle donné.
283
+ Retourne le nom de l'app Django pour un modele donne.
254
284
 
255
- Utilise la configuration stockée en base de données.
285
+ Utilise la configuration stockee en base de donnees.
256
286
  """
257
287
  from lucy_assist.models import ConfigurationLucyAssist
258
288
  return ConfigurationLucyAssist.get_app_for_model_static(model_name)
@@ -918,6 +918,10 @@
918
918
  overflow: hidden;
919
919
  }
920
920
 
921
+ .lucy-doc .collapse:not(.show) {
922
+ display: block;
923
+ }
924
+
921
925
  .lucy-doc .collapse-arrow {
922
926
  position: relative;
923
927
  }
@@ -87,14 +87,14 @@
87
87
  <div class="stats stats-vertical shadow w-full bg-base-200">
88
88
  <div class="stat">
89
89
  <div class="stat-title">Prix par million de tokens</div>
90
- <div class="stat-value text-primary">10 EUR</div>
90
+ <div class="stat-value text-primary">50 EUR</div>
91
91
  </div>
92
92
  <div class="stat">
93
93
  <div class="stat-title">Tokens moyens par conversation</div>
94
94
  <div class="stat-value text-secondary">2 000</div>
95
95
  </div>
96
96
  <div class="stat">
97
- <div class="stat-title">Conversations pour 10 EUR</div>
97
+ <div class="stat-title">Conversations pour 50 EUR</div>
98
98
  <div class="stat-value text-accent">~500</div>
99
99
  <div class="stat-desc">Estimation basée sur l'usage moyen</div>
100
100
  </div>
@@ -17,7 +17,7 @@ class TokenUtils:
17
17
 
18
18
  Args:
19
19
  montant_euros: Montant en euros
20
- prix_par_million: Prix par million de tokens (défaut: 10€)
20
+ prix_par_million: Prix par million de tokens (défaut: 50€)
21
21
 
22
22
  Returns:
23
23
  Nombre de tokens
@@ -32,7 +32,7 @@ class TokenUtils:
32
32
 
33
33
  Args:
34
34
  tokens: Nombre de tokens
35
- prix_par_million: Prix par million de tokens (défaut: 10€)
35
+ prix_par_million: Prix par million de tokens (défaut: 50€)
36
36
 
37
37
  Returns:
38
38
  Montant en euros
@@ -12,7 +12,7 @@ from lucy_assist.utils.log_utils import LogUtils
12
12
  from lucy_assist.utils.message_utils import MessageUtils
13
13
  from lucy_assist.models import Conversation, Message, ConfigurationLucyAssist
14
14
  from lucy_assist.constantes import LucyAssistConstantes
15
- from lucy_assist.services.claude_service import ClaudeService
15
+ from lucy_assist.services.mistral_service import MistralService
16
16
  from lucy_assist.services.context_service import ContextService
17
17
  from lucy_assist.services.tool_executor_service import create_tool_executor
18
18
 
@@ -162,10 +162,10 @@ class MessageCreateView(LucyAssistAPIView):
162
162
 
163
163
  @method_decorator(csrf_exempt, name='dispatch')
164
164
  class ChatCompletionView(LucyAssistAPIView):
165
- """Génération de réponse via Claude API avec streaming."""
165
+ """Generation de reponse via Mistral API avec streaming."""
166
166
 
167
167
  def post(self, request, conversation_id):
168
- """Génère une réponse Claude pour la conversation."""
168
+ """Genere une reponse Mistral pour la conversation."""
169
169
  try:
170
170
  conversation = Conversation.objects.get(
171
171
  pk=conversation_id,
@@ -197,8 +197,8 @@ class ChatCompletionView(LucyAssistAPIView):
197
197
  context_service = ContextService(request.user)
198
198
  contexte_page = context_service.get_page_context(page_contexte)
199
199
 
200
- # Appeler Claude avec le tool executor
201
- claude_service = ClaudeService()
200
+ # Appeler Mistral avec le tool executor
201
+ mistral_service = MistralService()
202
202
  tool_executor = create_tool_executor(request.user)
203
203
 
204
204
  try:
@@ -208,7 +208,7 @@ class ChatCompletionView(LucyAssistAPIView):
208
208
  total_tokens = 0
209
209
  tool_actions = [] # Pour tracker les actions effectuées
210
210
 
211
- for chunk in claude_service.chat_completion_stream(
211
+ for chunk in mistral_service.chat_completion_stream(
212
212
  messages=messages_historique,
213
213
  page_context=contexte_page,
214
214
  user=request.user,
@@ -288,7 +288,7 @@ class ChatCompletionView(LucyAssistAPIView):
288
288
  return response
289
289
 
290
290
  except Exception as e:
291
- LogUtils.error("Erreur lors de l'appel à Claude")
291
+ LogUtils.error("Erreur lors de l'appel a Mistral")
292
292
  return self.error_response(f'Erreur lors de la génération: {str(e)}', 500)
293
293
 
294
294