django-lucy-assist 1.2.1__py3-none-any.whl → 1.2.3__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,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: django-lucy-assist
3
- Version: 1.2.1
3
+ Version: 1.2.3
4
4
  Summary: Assistant IA intelligent Revolucy pour outil métier
5
5
  Author-email: Revolucy <hello@revolucy.fr>
6
6
  Maintainer-email: Maxence <hello@revolucy.fr>
@@ -1,19 +1,21 @@
1
- lucy_assist/__init__.py,sha256=8pYJE9xYXxtj5QgLOKK_d9V4N5kcXO69UzGHVcUxDFs,325
2
- lucy_assist/admin.py,sha256=DHdcvkCYNkVBZoWrZ58AQxOEN2EmsN4E09qRnqYyARI,2919
1
+ lucy_assist/__init__.py,sha256=9NTQKOljcruDMZjj1WQhcSRRjLbrx61jyaTuhXpk9ds,325
2
+ lucy_assist/admin.py,sha256=CFVBPmuFRIJzxc2pZ9s3LK1kdxMhSbLVA022VgbH89Y,4734
3
3
  lucy_assist/apps.py,sha256=zHZtlBXs5ML4CKtGg7xDyptSWzLfB1ks2VvbXF50hdo,264
4
4
  lucy_assist/conf.py,sha256=RgtZSrUwHZjjbEGZqQvifvC4GNdICmhty2XetfvAbls,3992
5
- lucy_assist/constantes.py,sha256=9cdU5aipmKxvhR-eY-5ktXQM43ccRjlwOLnA_HFFTHk,3969
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=u32Y2MDjE8rEgwS9VD_3fCbZT_NUjmemAUuREnTb-IU,1500
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
12
  lucy_assist/migrations/0004_configurationlucyassist_system_prompt.py,sha256=0a78xO15oiLcCSlO8BicMac_QE8IfiNSt9WlGptVNNo,568
13
+ lucy_assist/migrations/0005_configurationlucyassist_project_context.py,sha256=6eZCssiWylS_9pg9wDExbUZWEDwk2zaVu_f3pqMzuz8,564
14
+ lucy_assist/migrations/0006_remove_configurationlucyassist_prompt_complementaire.py,sha256=AwTzbmZWfWJ7Q_kcbSspSOiVJgHzGLLeMupeRSSVuI4,359
13
15
  lucy_assist/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
16
  lucy_assist/models/__init__.py,sha256=JQMr50P94sBrKwwcNArRE_qnk7dLnknMKCabeRLskJc,415
15
17
  lucy_assist/models/base.py,sha256=Ql2AY7bzvcxZhxsPdCpbVEKvtWD-NBkHTLYZX4TjT3s,1532
16
- lucy_assist/models/configuration.py,sha256=8_DboZJUsg6grL9CIRM3sR2WKhyc_SVVsHG9_kPihuA,12085
18
+ lucy_assist/models/configuration.py,sha256=GHmgkVZk3m01vlDwT-YEn4UG4za8e3Qr7xK00vsd_Qc,17095
17
19
  lucy_assist/models/conversation.py,sha256=psx2AQtQ5SFP-AJD7wbGabpXXLIGYngdVZfeoTlgKtQ,1849
18
20
  lucy_assist/models/message.py,sha256=kf-ffMtLYNFhXYUrB3QSL97KKDJUOMrKaPjKeOcJa_o,1492
19
21
  lucy_assist/models/project_context_cache.py,sha256=Bnb0VU7pv7QEvjOI6JSLEPvL4BxskCQ0ojWGxO7YDSM,6530
@@ -42,7 +44,7 @@ lucy_assist/utils/message_utils.py,sha256=YzcLHnl1ig4d5_utHCJwgxS7tKmd49Q-tuo78e
42
44
  lucy_assist/utils/token_utils.py,sha256=aBzyKVqpU67rAetO_Ee3QIfPtbNyjyWSe6qPfzIRJF8,2608
43
45
  lucy_assist/views/__init__.py,sha256=uUPYpuHlBC8j7zKS_DDoWjwpCpRnOIXETY-S2-Ss0cY,288
44
46
  lucy_assist/views/api_views.py,sha256=sJwKNC9-mi1zMbgyKZTVvT3pz4hMmw4jR0rrS7iJR-g,23619
45
- django_lucy_assist-1.2.1.dist-info/METADATA,sha256=hF6NzwK8_D6oJERSyFzFV-yKreFJj8RzZHgxbdd98Zc,5899
46
- django_lucy_assist-1.2.1.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
47
- django_lucy_assist-1.2.1.dist-info/top_level.txt,sha256=T-UCiwpn5yF3Oem3234TUpSVnEgbkrM2rGz9Tz5N-QA,12
48
- django_lucy_assist-1.2.1.dist-info/RECORD,,
47
+ django_lucy_assist-1.2.3.dist-info/METADATA,sha256=JDd1H3wg2RpwLmeVdA-Ednz73-6-St1r3oSHWu3ztdQ,5899
48
+ django_lucy_assist-1.2.3.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
49
+ django_lucy_assist-1.2.3.dist-info/top_level.txt,sha256=T-UCiwpn5yF3Oem3234TUpSVnEgbkrM2rGz9Tz5N-QA,12
50
+ django_lucy_assist-1.2.3.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.1'
8
+ __version__ = '1.2.3'
9
9
  __author__ = 'Revolucy'
10
10
 
11
11
  default_app_config = 'lucy_assist.apps.LucyAssistConfig'
lucy_assist/admin.py CHANGED
@@ -19,28 +19,44 @@ class ConversationAdmin(admin.ModelAdmin):
19
19
 
20
20
  @admin.register(ConfigurationLucyAssist)
21
21
  class ConfigurationLucyAssistAdmin(admin.ModelAdmin):
22
- list_display = ('id', 'tokens_disponibles', 'prix_par_million_tokens', 'nb_vues_crud', 'updated_date')
23
- readonly_fields = ('crud_views_mapping_display', 'model_app_mapping_display')
22
+ list_display = ('id', 'tokens_disponibles', 'prix_par_million_tokens', 'nb_vues_crud', 'has_project_context', 'updated_date')
23
+ readonly_fields = ('crud_views_mapping_display', 'model_app_mapping_display', 'project_context_display')
24
24
  fieldsets = (
25
25
  ('Configuration Tokens', {
26
26
  'fields': ('tokens_disponibles', 'prix_par_million_tokens', 'actif')
27
27
  }),
28
28
  ('Personnalisation', {
29
- 'fields': ('avatar', 'questions_frequentes', 'prompt_complementaire')
29
+ 'fields': ('avatar', 'questions_frequentes')
30
+ }),
31
+ ('Prompt Systeme', {
32
+ 'fields': ('system_prompt',),
33
+ 'classes': ('collapse',),
34
+ 'description': 'Le prompt systeme est initialise automatiquement si vide.'
35
+ }),
36
+ ('Contexte Projet GitLab', {
37
+ 'fields': ('project_context_display',),
38
+ 'classes': ('collapse',),
39
+ 'description': 'Analyse du projet depuis GitLab. Utilisez l\'action "Rafraichir le contexte projet" pour mettre a jour.'
30
40
  }),
31
41
  ('Mapping Automatique (lecture seule)', {
32
42
  'fields': ('crud_views_mapping_display', 'model_app_mapping_display'),
33
43
  'classes': ('collapse',)
34
44
  }),
35
45
  )
36
- actions = ['refresh_crud_views']
46
+ actions = ['refresh_crud_views', 'refresh_project_context']
37
47
 
38
48
  def nb_vues_crud(self, obj):
39
- """Affiche le nombre de modèles avec des vues CRUD découvertes."""
49
+ """Affiche le nombre de modeles avec des vues CRUD decouvertes."""
40
50
  if obj.crud_views_mapping:
41
51
  return len(obj.crud_views_mapping)
42
52
  return 0
43
- nb_vues_crud.short_description = "Modèles CRUD"
53
+ nb_vues_crud.short_description = "Modeles CRUD"
54
+
55
+ def has_project_context(self, obj):
56
+ """Indique si le contexte projet est configure."""
57
+ return bool(obj.project_context)
58
+ has_project_context.short_description = "Contexte GitLab"
59
+ has_project_context.boolean = True
44
60
 
45
61
  def crud_views_mapping_display(self, obj):
46
62
  """Affiche le mapping des vues CRUD de manière lisible."""
@@ -51,21 +67,43 @@ class ConfigurationLucyAssistAdmin(admin.ModelAdmin):
51
67
  crud_views_mapping_display.short_description = "Vues CRUD découvertes"
52
68
 
53
69
  def model_app_mapping_display(self, obj):
54
- """Affiche le mapping modèle -> app de manière lisible."""
70
+ """Affiche le mapping modele -> app de maniere lisible."""
55
71
  import json
56
72
  if obj.model_app_mapping:
57
73
  return json.dumps(obj.model_app_mapping, indent=2, ensure_ascii=False)
58
74
  return "Aucun mapping. Sera construit automatiquement."
59
- model_app_mapping_display.short_description = "Mapping Modèle -> App"
75
+ model_app_mapping_display.short_description = "Mapping Modele -> App"
60
76
 
61
- @admin.action(description="Rafraîchir les vues CRUD découvertes")
77
+ def project_context_display(self, obj):
78
+ """Affiche le contexte projet analyse depuis GitLab."""
79
+ if obj.project_context:
80
+ return obj.project_context
81
+ return "Aucun contexte. Utilisez l'action 'Rafraichir le contexte projet' ou configurez GitLab."
82
+ project_context_display.short_description = "Contexte Projet"
83
+
84
+ @admin.action(description="Rafraichir les vues CRUD decouvertes")
62
85
  def refresh_crud_views(self, request, queryset):
63
- """Action admin pour rafraîchir le mapping des vues CRUD."""
86
+ """Action admin pour rafraichir le mapping des vues CRUD."""
64
87
  for config in queryset:
65
88
  mapping = config.refresh_crud_views_mapping()
66
89
  nb_models = len(mapping)
67
90
  nb_views = sum(len(actions) for actions in mapping.values())
68
91
  self.message_user(
69
92
  request,
70
- f"Mapping rafraîchi: {nb_models} modèles, {nb_views} vues découvertes."
93
+ f"Mapping rafraichi: {nb_models} modeles, {nb_views} vues decouvertes."
71
94
  )
95
+
96
+ @admin.action(description="Rafraichir le contexte projet (GitLab)")
97
+ def refresh_project_context(self, request, queryset):
98
+ """Action admin pour analyser le projet depuis GitLab."""
99
+ for config in queryset:
100
+ result = config.refresh_project_context()
101
+ if "non configure" in result.lower():
102
+ self.message_user(request, result, level='warning')
103
+ else:
104
+ # Compter les lignes pour donner une idee de la taille
105
+ nb_lines = len(result.split('\n'))
106
+ self.message_user(
107
+ request,
108
+ f"Contexte projet rafraichi: {nb_lines} lignes d'analyse."
109
+ )
lucy_assist/constantes.py CHANGED
@@ -58,11 +58,11 @@ Tu as la capacité d'EXÉCUTER des actions directement dans l'application grâce
58
58
 
59
59
  ## COMPORTEMENT PRIORITAIRE - ACTION FIRST
60
60
 
61
- RÈGLE FONDAMENTALE : Quand l'utilisateur te demande de faire quelque chose (créer, modifier, rechercher, supprimer),
62
- tu dois EXÉCUTER L'ACTION IMMÉDIATEMENT en utilisant les tools disponibles.
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
- NE FAIS PAS : Expliquer comment faire, rediriger vers une page, dire que tu ne peux pas
65
- FAIS : Utiliser le tool approprié pour exécuter l'action demandée
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
66
66
 
67
67
  ## Quand NE PAS agir directement
68
68
 
@@ -91,10 +91,10 @@ Pour TOUTE demande de suppression, tu DOIS suivre cette procédure :
91
91
  ## Modèles disponibles dans l'application
92
92
  {available_models}
93
93
 
94
- ## Format de réponse après action
94
+ ## Format de reponse apres action
95
95
 
96
- Après avoir exécuté une action, confirme brièvement :
97
- " [Action effectuée] - [Détail bref]"
96
+ Apres avoir execute une action, confirme brievement :
97
+ "[OK] [Action effectuee] - [Detail bref]"
98
98
  """,
99
99
  'crud': """Tu dois aider l'utilisateur à créer ou modifier un objet.
100
100
  Formulaire disponible : {form_info}
@@ -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', '0004_configurationlucyassist_system_prompt'),
10
+ ]
11
+
12
+ operations = [
13
+ migrations.AddField(
14
+ model_name='configurationlucyassist',
15
+ name='project_context',
16
+ field=models.TextField(
17
+ blank=True,
18
+ default='',
19
+ help_text="Contexte du projet analyse depuis GitLab. Rafraichir via l'action admin."
20
+ ),
21
+ ),
22
+ ]
@@ -0,0 +1,17 @@
1
+ # Generated by Django
2
+
3
+ from django.db import migrations
4
+
5
+
6
+ class Migration(migrations.Migration):
7
+
8
+ dependencies = [
9
+ ('lucy_assist', '0005_configurationlucyassist_project_context'),
10
+ ]
11
+
12
+ operations = [
13
+ migrations.RemoveField(
14
+ model_name='configurationlucyassist',
15
+ name='prompt_complementaire',
16
+ ),
17
+ ]
@@ -21,16 +21,12 @@ class ConfigurationLucyAssist(LucyAssistBaseModel):
21
21
  avatar = models.ImageField(null=True, blank=True)
22
22
 
23
23
  # Prompt système principal pour l'assistant
24
- # Initialisé automatiquement via signal si vide
24
+ # Initialisé automatiquement si vide
25
25
  system_prompt = models.TextField(
26
26
  blank=True,
27
27
  default='',
28
- help_text="Prompt système pour l'assistant IA. Initialisé automatiquement si vide."
29
28
  )
30
29
 
31
- # Instructions complémentaires pour le prompt (ajoutées après le system_prompt)
32
- prompt_complementaire = models.TextField(blank=True, default='')
33
-
34
30
  # Mapping des modèles vers leurs applications Django
35
31
  model_app_mapping = models.JSONField(blank=True, default=dict)
36
32
 
@@ -45,6 +41,13 @@ class ConfigurationLucyAssist(LucyAssistBaseModel):
45
41
  # }
46
42
  crud_views_mapping = models.JSONField(blank=True, default=dict)
47
43
 
44
+ # Contexte du projet analyse depuis GitLab
45
+ # Contient une description detaillee du projet, ses fonctionnalites, modeles, etc.
46
+ project_context = models.TextField(
47
+ blank=True,
48
+ default='',
49
+ )
50
+
48
51
  class Meta:
49
52
  verbose_name = "Configuration Lucy Assist"
50
53
  verbose_name_plural = "Configuration Lucy Assist"
@@ -57,12 +60,20 @@ class ConfigurationLucyAssist(LucyAssistBaseModel):
57
60
  """
58
61
  Retourne la configuration singleton.
59
62
  Utilise le cache pour optimiser les performances.
63
+ Initialise le system_prompt si vide.
60
64
  """
61
65
  cache_key = 'lucy_assist_config'
62
66
  config = cache.get(cache_key)
63
67
 
64
68
  if config is None:
65
- config, _ = cls.objects.get_or_create(pk=1)
69
+ config, created = cls.objects.get_or_create(pk=1)
70
+
71
+ # Initialiser le system_prompt si vide (première utilisation ou reset)
72
+ if not config.system_prompt:
73
+ from lucy_assist.constantes import LucyAssistConstantes
74
+ config.system_prompt = LucyAssistConstantes.SYSTEM_PROMPTS['default']
75
+ config.save(update_fields=['system_prompt'])
76
+
66
77
  cache.set(cache_key, config, timeout=300) # Cache 5 minutes
67
78
 
68
79
  return config
@@ -237,15 +248,15 @@ class ConfigurationLucyAssist(LucyAssistBaseModel):
237
248
  available_models: str = ""
238
249
  ) -> str:
239
250
  """
240
- Retourne le prompt système formaté avec les variables de contexte.
251
+ Retourne le prompt systeme formate avec les variables de contexte.
241
252
 
242
253
  Args:
243
254
  page_context: Contexte JSON de la page actuelle
244
255
  user_permissions: Liste des permissions de l'utilisateur
245
- available_models: Liste des modèles disponibles
256
+ available_models: Liste des modeles disponibles
246
257
 
247
258
  Returns:
248
- Prompt système complet avec le prompt_complementaire ajouté
259
+ Prompt systeme complet avec le project_context
249
260
  """
250
261
  prompt = self.system_prompt
251
262
 
@@ -257,9 +268,9 @@ class ConfigurationLucyAssist(LucyAssistBaseModel):
257
268
  available_models=available_models
258
269
  )
259
270
 
260
- # Ajouter les instructions complémentaires si configurées
261
- if self.prompt_complementaire:
262
- prompt += f"\n\n## Instructions complémentaires\n{self.prompt_complementaire}"
271
+ # Ajouter le contexte du projet (analyse GitLab) si disponible
272
+ if self.project_context:
273
+ prompt += f"\n\n## Contexte du projet (analyse du code source)\n{self.project_context}"
263
274
 
264
275
  return prompt
265
276
 
@@ -267,7 +278,7 @@ class ConfigurationLucyAssist(LucyAssistBaseModel):
267
278
  """
268
279
  Retourne le nom de l'application depuis les settings.
269
280
  """
270
- return lucy_assist_settings.get('APPLICATION_NAME', 'cette application')
281
+ return getattr(lucy_assist_settings, 'APPLICATION_NAME', 'cette application')
271
282
 
272
283
  def get_available_models_description(self) -> str:
273
284
  """
@@ -311,7 +322,112 @@ class ConfigurationLucyAssist(LucyAssistBaseModel):
311
322
  fields_str += ", ..."
312
323
  descriptions.append(f"- {model_name} ({model_name_lower}) : {fields_str}")
313
324
 
314
- return "\n".join(descriptions) if descriptions else "Aucun modèle configuré"
325
+ return "\n".join(descriptions) if descriptions else "Aucun modele configure"
326
+
327
+ def refresh_project_context(self) -> str:
328
+ """
329
+ Analyse le projet GitLab et genere un contexte detaille.
330
+ Necessite GITLAB_TOKEN, GITLAB_URL et GITLAB_PROJECT_ID configures.
331
+
332
+ Returns:
333
+ Le contexte genere ou un message d'erreur
334
+ """
335
+ from lucy_assist.services.gitlab_service import GitLabService
336
+
337
+ gitlab = GitLabService()
338
+
339
+ # Verifier que GitLab est configure
340
+ if not gitlab.token or not gitlab.project_id:
341
+ return "GitLab non configure. Definissez GITLAB_TOKEN, GITLAB_URL et GITLAB_PROJECT_ID."
342
+
343
+ context_parts = []
344
+ app_name = self._get_application_name()
345
+ context_parts.append(f"# Analyse du projet {app_name}\n")
346
+
347
+ # 1. Analyser la structure du projet (fichiers apps.py)
348
+ apps_search = gitlab.search_code("class.*Config.*AppConfig", per_page=20)
349
+ if apps_search:
350
+ context_parts.append("## Applications Django")
351
+ apps_found = []
352
+ for result in apps_search:
353
+ filename = result.get('filename', '')
354
+ if 'apps.py' in filename:
355
+ # Extraire le nom de l'app
356
+ parts = filename.split('/')
357
+ if len(parts) >= 2:
358
+ apps_found.append(parts[-2])
359
+ if apps_found:
360
+ context_parts.append(f"Applications trouvees: {', '.join(set(apps_found))}\n")
361
+
362
+ # 2. Analyser les modeles principaux
363
+ models_search = gitlab.search_code("class.*models.Model", per_page=30)
364
+ if models_search:
365
+ context_parts.append("## Modeles principaux")
366
+ models_info = {}
367
+ for result in models_search:
368
+ filename = result.get('filename', '')
369
+ data = result.get('data', '')
370
+ if 'models' in filename and 'class ' in data:
371
+ # Extraire le nom du modele
372
+ import re
373
+ match = re.search(r'class\s+(\w+)\s*\(', data)
374
+ if match:
375
+ model_name = match.group(1)
376
+ if model_name not in ('Meta', 'Manager'):
377
+ # Recuperer plus de details sur le modele
378
+ model_detail = gitlab.find_model_and_form(model_name)
379
+ if model_detail.get('model_code'):
380
+ # Extraire les champs
381
+ fields = re.findall(
382
+ r'(\w+)\s*=\s*models\.(\w+)',
383
+ model_detail['model_code']
384
+ )
385
+ if fields:
386
+ models_info[model_name] = [f[0] for f in fields[:10]]
387
+
388
+ for model_name, fields in list(models_info.items())[:15]:
389
+ context_parts.append(f"- {model_name}: {', '.join(fields)}")
390
+ context_parts.append("")
391
+
392
+ # 3. Analyser les vues principales
393
+ views_search = gitlab.search_code("class.*View.*", per_page=20)
394
+ if views_search:
395
+ context_parts.append("## Vues principales")
396
+ views_found = set()
397
+ for result in views_search:
398
+ filename = result.get('filename', '')
399
+ data = result.get('data', '')
400
+ if 'views' in filename and 'class ' in data:
401
+ import re
402
+ match = re.search(r'class\s+(\w+View)\s*\(', data)
403
+ if match:
404
+ views_found.add(match.group(1))
405
+ if views_found:
406
+ context_parts.append(f"Vues: {', '.join(list(views_found)[:20])}\n")
407
+
408
+ # 4. Analyser le README si present
409
+ readme_content = gitlab.get_file_content('README.md')
410
+ if readme_content:
411
+ context_parts.append("## Description du projet (README)")
412
+ # Garder les 500 premiers caracteres du README
413
+ context_parts.append(readme_content[:500])
414
+ if len(readme_content) > 500:
415
+ context_parts.append("...\n")
416
+
417
+ # 5. Recuperer les commits recents pour comprendre l'activite
418
+ commits = gitlab.get_recent_commits(per_page=5)
419
+ if commits:
420
+ context_parts.append("## Commits recents")
421
+ for commit in commits:
422
+ context_parts.append(f"- {commit['message']}")
423
+ context_parts.append("")
424
+
425
+ # Assembler le contexte
426
+ self.project_context = "\n".join(context_parts)
427
+ self.save(update_fields=['project_context'])
428
+ cache.delete('lucy_assist_config')
429
+
430
+ return self.project_context
315
431
 
316
432
 
317
433
  def get_default_model_app_mapping() -> dict:
lucy_assist/signals.py CHANGED
@@ -5,7 +5,6 @@ from django.db.models.signals import post_save, pre_delete
5
5
  from django.dispatch import receiver
6
6
 
7
7
  from lucy_assist.models import Message, ConfigurationLucyAssist
8
- from lucy_assist.constantes import LucyAssistConstantes
9
8
 
10
9
 
11
10
  @receiver(post_save, sender=Message)
@@ -26,17 +25,3 @@ def message_post_save(sender, instance, created, **kwargs):
26
25
  config.save(update_fields=['tokens_disponibles'])
27
26
 
28
27
 
29
- @receiver(post_save, sender=ConfigurationLucyAssist)
30
- def config_post_save(sender, instance, created, **kwargs):
31
- """
32
- Signal déclenché après sauvegarde de la configuration.
33
- Initialise le system_prompt avec le prompt par défaut si vide.
34
- """
35
- if getattr(instance, '_skip_signals', False):
36
- return
37
-
38
- if not instance.system_prompt:
39
- # Initialiser avec le prompt par défaut
40
- instance.system_prompt = LucyAssistConstantes.SYSTEM_PROMPTS['default']
41
- instance._skip_signals = True
42
- instance.save(update_fields=['system_prompt'])