django-lucy-assist 1.2.0__py3-none-any.whl → 1.2.2__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.
- {django_lucy_assist-1.2.0.dist-info → django_lucy_assist-1.2.2.dist-info}/METADATA +1 -1
- {django_lucy_assist-1.2.0.dist-info → django_lucy_assist-1.2.2.dist-info}/RECORD +13 -12
- lucy_assist/__init__.py +1 -1
- lucy_assist/admin.py +6 -1
- lucy_assist/conf.py +4 -0
- lucy_assist/constantes.py +13 -37
- lucy_assist/migrations/0004_configurationlucyassist_system_prompt.py +22 -0
- lucy_assist/models/configuration.py +102 -3
- lucy_assist/services/mistral_service.py +13 -11
- lucy_assist/services/project_context_service.py +32 -15
- lucy_assist/signals.py +2 -0
- {django_lucy_assist-1.2.0.dist-info → django_lucy_assist-1.2.2.dist-info}/WHEEL +0 -0
- {django_lucy_assist-1.2.0.dist-info → django_lucy_assist-1.2.2.dist-info}/top_level.txt +0 -0
|
@@ -1,18 +1,19 @@
|
|
|
1
|
-
lucy_assist/__init__.py,sha256=
|
|
2
|
-
lucy_assist/admin.py,sha256=
|
|
1
|
+
lucy_assist/__init__.py,sha256=eg52UR1U2IqaSiZSe-_3OPuY4KhzK-eBk5NuZDboUtU,325
|
|
2
|
+
lucy_assist/admin.py,sha256=pDpxwrrSh-bY7vQhf5ZA3HKIugjP1OdthGDI-y5AVsk,3178
|
|
3
3
|
lucy_assist/apps.py,sha256=zHZtlBXs5ML4CKtGg7xDyptSWzLfB1ks2VvbXF50hdo,264
|
|
4
|
-
lucy_assist/conf.py,sha256=
|
|
5
|
-
lucy_assist/constantes.py,sha256=
|
|
4
|
+
lucy_assist/conf.py,sha256=RgtZSrUwHZjjbEGZqQvifvC4GNdICmhty2XetfvAbls,3992
|
|
5
|
+
lucy_assist/constantes.py,sha256=9L2VGBK0HorJoNDGdwQlhEfT75W-xNPAhtS0-qgawBs,3947
|
|
6
6
|
lucy_assist/context_processors.py,sha256=tnzil4CEJwtExuQGLyRzIEuwpQfnwJ-eMgkkR6zNgSg,2200
|
|
7
|
-
lucy_assist/signals.py,sha256=
|
|
7
|
+
lucy_assist/signals.py,sha256=i3Uj9v-0zyAIROFl86fLlwaqRqQizL9_CpWmVjJbk8g,863
|
|
8
8
|
lucy_assist/urls.py,sha256=Qr8jJjEyC_EFGAeiZnjhgTc-9P4Y-TqKDaYicWRp_GQ,1451
|
|
9
9
|
lucy_assist/migrations/0001_initial.py,sha256=quQUw6is5clu3Q4B3P_0mUZVE33lSvdimH_OTCY3ycE,4977
|
|
10
10
|
lucy_assist/migrations/0002_configurationlucyassist_prompt_complementaire.py,sha256=yWE4-RPHQtPAqYHlAhr4EsXgk35kI8zRQArlAP_JwDc,418
|
|
11
11
|
lucy_assist/migrations/0003_configurationlucyassist_crud_views_mapping.py,sha256=1vnu1VwVBouskhQBgLz-Lp71p4a9Cb9PjrT-RLVGY7s,429
|
|
12
|
+
lucy_assist/migrations/0004_configurationlucyassist_system_prompt.py,sha256=0a78xO15oiLcCSlO8BicMac_QE8IfiNSt9WlGptVNNo,568
|
|
12
13
|
lucy_assist/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
13
14
|
lucy_assist/models/__init__.py,sha256=JQMr50P94sBrKwwcNArRE_qnk7dLnknMKCabeRLskJc,415
|
|
14
15
|
lucy_assist/models/base.py,sha256=Ql2AY7bzvcxZhxsPdCpbVEKvtWD-NBkHTLYZX4TjT3s,1532
|
|
15
|
-
lucy_assist/models/configuration.py,sha256=
|
|
16
|
+
lucy_assist/models/configuration.py,sha256=EdCulH59rnjHM-c307a9dyjiRCEwdyN64Vwa8Vb6tuQ,12487
|
|
16
17
|
lucy_assist/models/conversation.py,sha256=psx2AQtQ5SFP-AJD7wbGabpXXLIGYngdVZfeoTlgKtQ,1849
|
|
17
18
|
lucy_assist/models/message.py,sha256=kf-ffMtLYNFhXYUrB3QSL97KKDJUOMrKaPjKeOcJa_o,1492
|
|
18
19
|
lucy_assist/models/project_context_cache.py,sha256=Bnb0VU7pv7QEvjOI6JSLEPvL4BxskCQ0ojWGxO7YDSM,6530
|
|
@@ -21,8 +22,8 @@ lucy_assist/services/bug_notification_service.py,sha256=OyowCvAs-QDlsGQ_WTFoc4lR
|
|
|
21
22
|
lucy_assist/services/context_service.py,sha256=Vx2tR6W1jmqr06pGn924uzWTF2SV7RAO_JIScxYbCy0,17087
|
|
22
23
|
lucy_assist/services/crud_service.py,sha256=W50K02ZkaScyzO-yRaBd9Cjva9PGH7OjNTipSruErcA,41495
|
|
23
24
|
lucy_assist/services/gitlab_service.py,sha256=uH83fwRSCwiRItznENpYQG4aPckjafYIV9z6OChUrZg,8056
|
|
24
|
-
lucy_assist/services/mistral_service.py,sha256=
|
|
25
|
-
lucy_assist/services/project_context_service.py,sha256=
|
|
25
|
+
lucy_assist/services/mistral_service.py,sha256=mmoI2ixBFTeKFOId-2goe-NGpvjd_cMW9PMuV2C-P2k,18624
|
|
26
|
+
lucy_assist/services/project_context_service.py,sha256=6QNVL-K2D-8whIPfyAJhi_xAifqTXxR09461YNBwg4o,14826
|
|
26
27
|
lucy_assist/services/tool_executor_service.py,sha256=nTeJbj2JUDMk_bmLVgGxtWqFbSgywq-tNRBK-_3Yayw,15155
|
|
27
28
|
lucy_assist/services/tools_definition.py,sha256=qIiIoB5_QMqmkD03OOEk_3A5Nc0g0avAjDCj3Uq3_r8,11735
|
|
28
29
|
lucy_assist/services/view_discovery_service.py,sha256=J9LkHXUOzlGS3cyft2_jA1X27TWOd3xViN4M7GOROVw,11872
|
|
@@ -41,7 +42,7 @@ lucy_assist/utils/message_utils.py,sha256=YzcLHnl1ig4d5_utHCJwgxS7tKmd49Q-tuo78e
|
|
|
41
42
|
lucy_assist/utils/token_utils.py,sha256=aBzyKVqpU67rAetO_Ee3QIfPtbNyjyWSe6qPfzIRJF8,2608
|
|
42
43
|
lucy_assist/views/__init__.py,sha256=uUPYpuHlBC8j7zKS_DDoWjwpCpRnOIXETY-S2-Ss0cY,288
|
|
43
44
|
lucy_assist/views/api_views.py,sha256=sJwKNC9-mi1zMbgyKZTVvT3pz4hMmw4jR0rrS7iJR-g,23619
|
|
44
|
-
django_lucy_assist-1.2.
|
|
45
|
-
django_lucy_assist-1.2.
|
|
46
|
-
django_lucy_assist-1.2.
|
|
47
|
-
django_lucy_assist-1.2.
|
|
45
|
+
django_lucy_assist-1.2.2.dist-info/METADATA,sha256=t_hJ2rRU16S5X_o_Mj66IwNG4Nl8PQjrJi837ZGSjjs,5899
|
|
46
|
+
django_lucy_assist-1.2.2.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
47
|
+
django_lucy_assist-1.2.2.dist-info/top_level.txt,sha256=T-UCiwpn5yF3Oem3234TUpSVnEgbkrM2rGz9Tz5N-QA,12
|
|
48
|
+
django_lucy_assist-1.2.2.dist-info/RECORD,,
|
lucy_assist/__init__.py
CHANGED
|
@@ -5,7 +5,7 @@ Un chatbot IA base sur Mistral AI, integrable dans n'importe quelle
|
|
|
5
5
|
application Django pour fournir une assistance contextuelle aux utilisateurs.
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
|
-
__version__ = '1.2.
|
|
8
|
+
__version__ = '1.2.2'
|
|
9
9
|
__author__ = 'Revolucy'
|
|
10
10
|
|
|
11
11
|
default_app_config = 'lucy_assist.apps.LucyAssistConfig'
|
lucy_assist/admin.py
CHANGED
|
@@ -26,7 +26,12 @@ class ConfigurationLucyAssistAdmin(admin.ModelAdmin):
|
|
|
26
26
|
'fields': ('tokens_disponibles', 'prix_par_million_tokens', 'actif')
|
|
27
27
|
}),
|
|
28
28
|
('Personnalisation', {
|
|
29
|
-
'fields': ('avatar', 'questions_frequentes'
|
|
29
|
+
'fields': ('avatar', 'questions_frequentes')
|
|
30
|
+
}),
|
|
31
|
+
('Prompt Système', {
|
|
32
|
+
'fields': ('system_prompt', 'prompt_complementaire'),
|
|
33
|
+
'classes': ('collapse',),
|
|
34
|
+
'description': 'Le prompt système est initialisé automatiquement si vide. Le prompt complémentaire est ajouté à la fin.'
|
|
30
35
|
}),
|
|
31
36
|
('Mapping Automatique (lecture seule)', {
|
|
32
37
|
'fields': ('crud_views_mapping_display', 'model_app_mapping_display'),
|
lucy_assist/conf.py
CHANGED
|
@@ -17,6 +17,10 @@ class LucyAssistSettings:
|
|
|
17
17
|
# Peut etre une string "mon_app.models.MonModele" ou une classe directement
|
|
18
18
|
'BASE_MODEL': None,
|
|
19
19
|
|
|
20
|
+
# Nom de l'application (affiche dans le prompt systeme)
|
|
21
|
+
# Ex: 'Mon Application'
|
|
22
|
+
'APPLICATION_NAME': 'cette application',
|
|
23
|
+
|
|
20
24
|
# Cle API Mistral (peut aussi etre definie via MISTRAL_LUCY_API_KEY)
|
|
21
25
|
'MISTRAL_LUCY_API_KEY': None,
|
|
22
26
|
|
lucy_assist/constantes.py
CHANGED
|
@@ -53,27 +53,16 @@ class LucyAssistConstantes:
|
|
|
53
53
|
|
|
54
54
|
# Prompts systeme pour Mistral
|
|
55
55
|
SYSTEM_PROMPTS = {
|
|
56
|
-
'default': """Tu es Lucy, un assistant IA intégré dans
|
|
56
|
+
'default': """Tu es Lucy, un assistant IA intégré dans l'application {application_name}.
|
|
57
57
|
Tu as la capacité d'EXÉCUTER des actions directement dans l'application grâce aux tools disponibles.
|
|
58
58
|
|
|
59
59
|
## COMPORTEMENT PRIORITAIRE - ACTION FIRST
|
|
60
60
|
|
|
61
|
-
|
|
62
|
-
tu dois
|
|
61
|
+
REGLE FONDAMENTALE : Quand l'utilisateur te demande de faire quelque chose (creer, modifier, rechercher, supprimer),
|
|
62
|
+
tu dois EXECUTER L'ACTION IMMEDIATEMENT en utilisant les tools disponibles.
|
|
63
63
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
## Exemples de comportement attendu
|
|
68
|
-
|
|
69
|
-
Utilisateur : "Crée un membre Maxence Dupont"
|
|
70
|
-
→ Tu utilises le tool create_object avec les données {{"nom": "Dupont", "prenom": "Maxence"}}
|
|
71
|
-
|
|
72
|
-
Utilisateur : "Cherche les membres de Paris"
|
|
73
|
-
→ Tu utilises le tool search_objects avec query="Paris" et model_name="Membre"
|
|
74
|
-
|
|
75
|
-
Utilisateur : "Modifie l'adresse du membre 42"
|
|
76
|
-
→ Tu utilises le tool update_object avec l'object_id et les nouvelles données
|
|
64
|
+
NE FAIS PAS : Expliquer comment faire, rediriger vers une page, dire que tu ne peux pas
|
|
65
|
+
FAIS : Utiliser le tool approprie pour executer l'action demandee
|
|
77
66
|
|
|
78
67
|
## Quand NE PAS agir directement
|
|
79
68
|
|
|
@@ -93,32 +82,19 @@ Pour TOUTE demande de suppression, tu DOIS suivre cette procédure :
|
|
|
93
82
|
3. Demande une confirmation EXPLICITE à l'utilisateur ("Confirmez-vous la suppression ?")
|
|
94
83
|
4. SEULEMENT si l'utilisateur confirme explicitement (oui, ok, confirme, etc.), utilise `delete_object` avec `confirmed: true`
|
|
95
84
|
|
|
96
|
-
Exemple de réponse après get_deletion_impact :
|
|
97
|
-
"Voici les conséquences de la suppression du Client #42 :
|
|
98
|
-
- 5 Réservations seront supprimées en cascade
|
|
99
|
-
- 3 Paiements seront supprimés en cascade
|
|
100
|
-
- 2 Documents auront leur champ 'client' mis à NULL
|
|
101
|
-
|
|
102
|
-
**Confirmez-vous vouloir supprimer ce client et tous les éléments associés ?**"
|
|
103
|
-
|
|
104
85
|
## Contexte de la page actuelle
|
|
105
86
|
{page_context}
|
|
106
87
|
|
|
107
88
|
## Permissions de l'utilisateur
|
|
108
89
|
{user_permissions}
|
|
109
90
|
|
|
110
|
-
## Modèles
|
|
111
|
-
|
|
112
|
-
- Structure (structure) : nom, adresse, type, siret
|
|
113
|
-
- Adhesion (adhesion) : membre, structure, date_debut, date_fin, montant
|
|
114
|
-
- Paiement (paiement) : membre, montant, date, mode_paiement
|
|
115
|
-
|
|
116
|
-
## Format de réponse après action
|
|
91
|
+
## Modèles disponibles dans l'application
|
|
92
|
+
{available_models}
|
|
117
93
|
|
|
118
|
-
|
|
119
|
-
"✅ [Action effectuée] - [Détail bref]"
|
|
94
|
+
## Format de reponse apres action
|
|
120
95
|
|
|
121
|
-
|
|
96
|
+
Apres avoir execute une action, confirme brievement :
|
|
97
|
+
"[OK] [Action effectuee] - [Detail bref]"
|
|
122
98
|
""",
|
|
123
99
|
'crud': """Tu dois aider l'utilisateur à créer ou modifier un objet.
|
|
124
100
|
Formulaire disponible : {form_info}
|
|
@@ -132,9 +108,9 @@ Erreur rapportée : {error_message}
|
|
|
132
108
|
|
|
133
109
|
# Questions fréquentes par défaut (utilisées si non configurées dans le modèle)
|
|
134
110
|
QUESTIONS_FREQUENTES_DEFAULT = [
|
|
135
|
-
"Comment créer un
|
|
136
|
-
"Comment effectuer
|
|
111
|
+
"Comment créer un nouvel enregistrement ?",
|
|
112
|
+
"Comment effectuer une recherche ?",
|
|
137
113
|
"Comment exporter des données ?",
|
|
138
114
|
"Comment modifier mon profil ?",
|
|
139
|
-
"
|
|
115
|
+
"Quelles sont les fonctionnalités disponibles ?",
|
|
140
116
|
]
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Generated by Django
|
|
2
|
+
|
|
3
|
+
from django.db import migrations, models
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Migration(migrations.Migration):
|
|
7
|
+
|
|
8
|
+
dependencies = [
|
|
9
|
+
('lucy_assist', '0003_configurationlucyassist_crud_views_mapping'),
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
operations = [
|
|
13
|
+
migrations.AddField(
|
|
14
|
+
model_name='configurationlucyassist',
|
|
15
|
+
name='system_prompt',
|
|
16
|
+
field=models.TextField(
|
|
17
|
+
blank=True,
|
|
18
|
+
default='',
|
|
19
|
+
help_text="Prompt système pour l'assistant IA. Initialisé automatiquement si vide."
|
|
20
|
+
),
|
|
21
|
+
),
|
|
22
|
+
]
|
|
@@ -20,8 +20,16 @@ class ConfigurationLucyAssist(LucyAssistBaseModel):
|
|
|
20
20
|
actif = models.BooleanField(default=True)
|
|
21
21
|
avatar = models.ImageField(null=True, blank=True)
|
|
22
22
|
|
|
23
|
-
#
|
|
24
|
-
|
|
23
|
+
# Prompt système principal pour l'assistant
|
|
24
|
+
# Initialisé automatiquement via signal si vide
|
|
25
|
+
system_prompt = models.TextField(
|
|
26
|
+
blank=True,
|
|
27
|
+
default='',
|
|
28
|
+
help_text="Prompt système pour l'assistant IA. Initialisé automatiquement si vide."
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
# Instructions complémentaires pour le prompt (ajoutées après le system_prompt)
|
|
32
|
+
prompt_complementaire = models.TextField(blank=True, default='')
|
|
25
33
|
|
|
26
34
|
# Mapping des modèles vers leurs applications Django
|
|
27
35
|
model_app_mapping = models.JSONField(blank=True, default=dict)
|
|
@@ -49,12 +57,20 @@ class ConfigurationLucyAssist(LucyAssistBaseModel):
|
|
|
49
57
|
"""
|
|
50
58
|
Retourne la configuration singleton.
|
|
51
59
|
Utilise le cache pour optimiser les performances.
|
|
60
|
+
Initialise le system_prompt si vide.
|
|
52
61
|
"""
|
|
53
62
|
cache_key = 'lucy_assist_config'
|
|
54
63
|
config = cache.get(cache_key)
|
|
55
64
|
|
|
56
65
|
if config is None:
|
|
57
|
-
config,
|
|
66
|
+
config, created = cls.objects.get_or_create(pk=1)
|
|
67
|
+
|
|
68
|
+
# Initialiser le system_prompt si vide (première utilisation ou reset)
|
|
69
|
+
if not config.system_prompt:
|
|
70
|
+
from lucy_assist.constantes import LucyAssistConstantes
|
|
71
|
+
config.system_prompt = LucyAssistConstantes.SYSTEM_PROMPTS['default']
|
|
72
|
+
config.save(update_fields=['system_prompt'])
|
|
73
|
+
|
|
58
74
|
cache.set(cache_key, config, timeout=300) # Cache 5 minutes
|
|
59
75
|
|
|
60
76
|
return config
|
|
@@ -222,6 +238,89 @@ class ConfigurationLucyAssist(LucyAssistBaseModel):
|
|
|
222
238
|
config = cls.get_config()
|
|
223
239
|
return config.get_app_for_model(model_name)
|
|
224
240
|
|
|
241
|
+
def get_system_prompt(
|
|
242
|
+
self,
|
|
243
|
+
page_context: str = "",
|
|
244
|
+
user_permissions: str = "",
|
|
245
|
+
available_models: str = ""
|
|
246
|
+
) -> str:
|
|
247
|
+
"""
|
|
248
|
+
Retourne le prompt système formaté avec les variables de contexte.
|
|
249
|
+
|
|
250
|
+
Args:
|
|
251
|
+
page_context: Contexte JSON de la page actuelle
|
|
252
|
+
user_permissions: Liste des permissions de l'utilisateur
|
|
253
|
+
available_models: Liste des modèles disponibles
|
|
254
|
+
|
|
255
|
+
Returns:
|
|
256
|
+
Prompt système complet avec le prompt_complementaire ajouté
|
|
257
|
+
"""
|
|
258
|
+
prompt = self.system_prompt
|
|
259
|
+
|
|
260
|
+
# Remplacer les placeholders
|
|
261
|
+
prompt = prompt.format(
|
|
262
|
+
application_name=self._get_application_name(),
|
|
263
|
+
page_context=page_context,
|
|
264
|
+
user_permissions=user_permissions,
|
|
265
|
+
available_models=available_models
|
|
266
|
+
)
|
|
267
|
+
|
|
268
|
+
# Ajouter les instructions complémentaires si configurées
|
|
269
|
+
if self.prompt_complementaire:
|
|
270
|
+
prompt += f"\n\n## Instructions complémentaires\n{self.prompt_complementaire}"
|
|
271
|
+
|
|
272
|
+
return prompt
|
|
273
|
+
|
|
274
|
+
def _get_application_name(self) -> str:
|
|
275
|
+
"""
|
|
276
|
+
Retourne le nom de l'application depuis les settings.
|
|
277
|
+
"""
|
|
278
|
+
return getattr(lucy_assist_settings, 'APPLICATION_NAME', 'cette application')
|
|
279
|
+
|
|
280
|
+
def get_available_models_description(self) -> str:
|
|
281
|
+
"""
|
|
282
|
+
Génère dynamiquement la description des modèles disponibles
|
|
283
|
+
à partir des modèles Django enregistrés.
|
|
284
|
+
|
|
285
|
+
Returns:
|
|
286
|
+
Description formatée des modèles avec leurs champs principaux
|
|
287
|
+
"""
|
|
288
|
+
from django.apps import apps
|
|
289
|
+
|
|
290
|
+
descriptions = []
|
|
291
|
+
apps_prefix = lucy_assist_settings.PROJECT_APPS_PREFIX
|
|
292
|
+
|
|
293
|
+
for app_config in apps.get_app_configs():
|
|
294
|
+
# Filtrer les apps si un préfixe est configuré
|
|
295
|
+
if apps_prefix and not app_config.name.startswith(apps_prefix):
|
|
296
|
+
continue
|
|
297
|
+
|
|
298
|
+
# Ignorer les apps Django internes et lucy_assist
|
|
299
|
+
if app_config.name.startswith('django.') or app_config.name == 'lucy_assist':
|
|
300
|
+
continue
|
|
301
|
+
|
|
302
|
+
for model in app_config.get_models():
|
|
303
|
+
model_name = model.__name__
|
|
304
|
+
model_name_lower = model_name.lower()
|
|
305
|
+
|
|
306
|
+
# Récupérer les champs principaux (exclure les champs auto)
|
|
307
|
+
fields = []
|
|
308
|
+
for field in model._meta.get_fields():
|
|
309
|
+
if hasattr(field, 'name') and not field.name.startswith('_'):
|
|
310
|
+
if hasattr(field, 'auto_created') and field.auto_created:
|
|
311
|
+
continue
|
|
312
|
+
if field.name in ('id', 'pk', 'created_at', 'updated_at'):
|
|
313
|
+
continue
|
|
314
|
+
fields.append(field.name)
|
|
315
|
+
|
|
316
|
+
if fields:
|
|
317
|
+
fields_str = ", ".join(fields[:8]) # Limiter à 8 champs
|
|
318
|
+
if len(fields) > 8:
|
|
319
|
+
fields_str += ", ..."
|
|
320
|
+
descriptions.append(f"- {model_name} ({model_name_lower}) : {fields_str}")
|
|
321
|
+
|
|
322
|
+
return "\n".join(descriptions) if descriptions else "Aucun modèle configuré"
|
|
323
|
+
|
|
225
324
|
|
|
226
325
|
def get_default_model_app_mapping() -> dict:
|
|
227
326
|
"""
|
|
@@ -57,8 +57,8 @@ class MistralService:
|
|
|
57
57
|
"""
|
|
58
58
|
Construit le prompt systeme avec le contexte optimise.
|
|
59
59
|
|
|
60
|
-
Utilise le
|
|
61
|
-
sur le projet.
|
|
60
|
+
Utilise le prompt stocke en base de donnees et le cache
|
|
61
|
+
pour reduire la redondance des informations sur le projet.
|
|
62
62
|
"""
|
|
63
63
|
# Recuperer les permissions utilisateur (compressees)
|
|
64
64
|
user_permissions = []
|
|
@@ -81,17 +81,19 @@ class MistralService:
|
|
|
81
81
|
'cache_stats': optimized_context.get('stats', {})
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
-
#
|
|
85
|
-
prompt = LucyAssistConstantes.SYSTEM_PROMPTS['default'].format(
|
|
86
|
-
page_context=json.dumps(enriched_context, ensure_ascii=False, indent=2),
|
|
87
|
-
user_permissions=', '.join(user_permissions)
|
|
88
|
-
)
|
|
89
|
-
|
|
90
|
-
# Ajouter les instructions complementaires si configurees
|
|
84
|
+
# Recuperer la configuration avec le prompt systeme
|
|
91
85
|
from lucy_assist.models import ConfigurationLucyAssist
|
|
92
86
|
config = ConfigurationLucyAssist.get_config()
|
|
93
|
-
|
|
94
|
-
|
|
87
|
+
|
|
88
|
+
# Generer la description des modeles disponibles
|
|
89
|
+
available_models = config.get_available_models_description()
|
|
90
|
+
|
|
91
|
+
# Construire le prompt depuis la configuration
|
|
92
|
+
prompt = config.get_system_prompt(
|
|
93
|
+
page_context=json.dumps(enriched_context, ensure_ascii=False, indent=2),
|
|
94
|
+
user_permissions=', '.join(user_permissions),
|
|
95
|
+
available_models=available_models
|
|
96
|
+
)
|
|
95
97
|
|
|
96
98
|
return prompt
|
|
97
99
|
|
|
@@ -332,23 +332,40 @@ class ProjectContextService:
|
|
|
332
332
|
return None
|
|
333
333
|
|
|
334
334
|
def _detect_model_from_question(self, question: str) -> Optional[str]:
|
|
335
|
-
"""
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
'paiement': 'Paiement',
|
|
344
|
-
'facture': 'Facture',
|
|
345
|
-
'structure': 'Structure',
|
|
346
|
-
}
|
|
335
|
+
"""
|
|
336
|
+
Détecte si la question mentionne un modèle.
|
|
337
|
+
|
|
338
|
+
Utilise la liste dynamique des modèles Django enregistrés
|
|
339
|
+
au lieu d'une liste hardcodée.
|
|
340
|
+
"""
|
|
341
|
+
from django.apps import apps
|
|
342
|
+
from lucy_assist.conf import lucy_assist_settings
|
|
347
343
|
|
|
348
344
|
question_lower = question.lower()
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
345
|
+
apps_prefix = lucy_assist_settings.PROJECT_APPS_PREFIX
|
|
346
|
+
|
|
347
|
+
for app_config in apps.get_app_configs():
|
|
348
|
+
# Filtrer les apps si un préfixe est configuré
|
|
349
|
+
if apps_prefix and not app_config.name.startswith(apps_prefix):
|
|
350
|
+
continue
|
|
351
|
+
|
|
352
|
+
# Ignorer les apps Django internes et lucy_assist
|
|
353
|
+
if app_config.name.startswith('django.') or app_config.name == 'lucy_assist':
|
|
354
|
+
continue
|
|
355
|
+
|
|
356
|
+
for model in app_config.get_models():
|
|
357
|
+
model_name = model.__name__
|
|
358
|
+
model_name_lower = model_name.lower()
|
|
359
|
+
|
|
360
|
+
# Vérifier si le nom du modèle apparaît dans la question
|
|
361
|
+
if model_name_lower in question_lower:
|
|
362
|
+
return model_name
|
|
363
|
+
|
|
364
|
+
# Vérifier aussi le verbose_name si disponible
|
|
365
|
+
if hasattr(model._meta, 'verbose_name'):
|
|
366
|
+
verbose_name = str(model._meta.verbose_name).lower()
|
|
367
|
+
if verbose_name in question_lower:
|
|
368
|
+
return model_name
|
|
352
369
|
|
|
353
370
|
return None
|
|
354
371
|
|
lucy_assist/signals.py
CHANGED
|
File without changes
|
|
File without changes
|