django-lucy-assist 1.2.3__tar.gz → 1.2.5__tar.gz
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.3 → django_lucy_assist-1.2.5}/PKG-INFO +1 -1
- {django_lucy_assist-1.2.3 → django_lucy_assist-1.2.5}/django_lucy_assist.egg-info/PKG-INFO +1 -1
- {django_lucy_assist-1.2.3 → django_lucy_assist-1.2.5}/django_lucy_assist.egg-info/SOURCES.txt +0 -5
- {django_lucy_assist-1.2.3 → django_lucy_assist-1.2.5}/lucy_assist/__init__.py +1 -1
- {django_lucy_assist-1.2.3 → django_lucy_assist-1.2.5}/lucy_assist/admin.py +6 -39
- {django_lucy_assist-1.2.3 → django_lucy_assist-1.2.5}/lucy_assist/conf.py +4 -0
- django_lucy_assist-1.2.5/lucy_assist/constantes.py +166 -0
- {django_lucy_assist-1.2.3 → django_lucy_assist-1.2.5}/lucy_assist/migrations/0001_initial.py +3 -1
- {django_lucy_assist-1.2.3 → django_lucy_assist-1.2.5}/lucy_assist/models/configuration.py +0 -116
- {django_lucy_assist-1.2.3 → django_lucy_assist-1.2.5}/lucy_assist/services/context_service.py +234 -0
- {django_lucy_assist-1.2.3 → django_lucy_assist-1.2.5}/lucy_assist/services/crud_service.py +97 -13
- {django_lucy_assist-1.2.3 → django_lucy_assist-1.2.5}/lucy_assist/services/gitlab_service.py +79 -6
- {django_lucy_assist-1.2.3 → django_lucy_assist-1.2.5}/lucy_assist/services/mistral_service.py +31 -11
- {django_lucy_assist-1.2.3 → django_lucy_assist-1.2.5}/lucy_assist/services/tool_executor_service.py +91 -0
- {django_lucy_assist-1.2.3 → django_lucy_assist-1.2.5}/lucy_assist/services/tools_definition.py +65 -0
- {django_lucy_assist-1.2.3 → django_lucy_assist-1.2.5}/lucy_assist/services/view_discovery_service.py +47 -13
- {django_lucy_assist-1.2.3 → django_lucy_assist-1.2.5}/lucy_assist/static/lucy_assist/css/lucy-assist.css +48 -1
- {django_lucy_assist-1.2.3 → django_lucy_assist-1.2.5}/lucy_assist/static/lucy_assist/js/lucy-assist.js +11 -0
- {django_lucy_assist-1.2.3 → django_lucy_assist-1.2.5}/lucy_assist/templates/lucy_assist/chatbot_sidebar.html +11 -1
- {django_lucy_assist-1.2.3 → django_lucy_assist-1.2.5}/pyproject.toml +1 -1
- django_lucy_assist-1.2.3/lucy_assist/constantes.py +0 -116
- django_lucy_assist-1.2.3/lucy_assist/migrations/0002_configurationlucyassist_prompt_complementaire.py +0 -18
- django_lucy_assist-1.2.3/lucy_assist/migrations/0003_configurationlucyassist_crud_views_mapping.py +0 -18
- django_lucy_assist-1.2.3/lucy_assist/migrations/0004_configurationlucyassist_system_prompt.py +0 -22
- django_lucy_assist-1.2.3/lucy_assist/migrations/0005_configurationlucyassist_project_context.py +0 -22
- django_lucy_assist-1.2.3/lucy_assist/migrations/0006_remove_configurationlucyassist_prompt_complementaire.py +0 -17
- {django_lucy_assist-1.2.3 → django_lucy_assist-1.2.5}/MANIFEST.in +0 -0
- {django_lucy_assist-1.2.3 → django_lucy_assist-1.2.5}/README.md +0 -0
- {django_lucy_assist-1.2.3 → django_lucy_assist-1.2.5}/django_lucy_assist.egg-info/dependency_links.txt +0 -0
- {django_lucy_assist-1.2.3 → django_lucy_assist-1.2.5}/django_lucy_assist.egg-info/requires.txt +0 -0
- {django_lucy_assist-1.2.3 → django_lucy_assist-1.2.5}/django_lucy_assist.egg-info/top_level.txt +0 -0
- {django_lucy_assist-1.2.3 → django_lucy_assist-1.2.5}/lucy_assist/apps.py +0 -0
- {django_lucy_assist-1.2.3 → django_lucy_assist-1.2.5}/lucy_assist/context_processors.py +0 -0
- {django_lucy_assist-1.2.3 → django_lucy_assist-1.2.5}/lucy_assist/migrations/__init__.py +0 -0
- {django_lucy_assist-1.2.3 → django_lucy_assist-1.2.5}/lucy_assist/models/__init__.py +0 -0
- {django_lucy_assist-1.2.3 → django_lucy_assist-1.2.5}/lucy_assist/models/base.py +0 -0
- {django_lucy_assist-1.2.3 → django_lucy_assist-1.2.5}/lucy_assist/models/conversation.py +0 -0
- {django_lucy_assist-1.2.3 → django_lucy_assist-1.2.5}/lucy_assist/models/message.py +0 -0
- {django_lucy_assist-1.2.3 → django_lucy_assist-1.2.5}/lucy_assist/models/project_context_cache.py +0 -0
- {django_lucy_assist-1.2.3 → django_lucy_assist-1.2.5}/lucy_assist/services/__init__.py +0 -0
- {django_lucy_assist-1.2.3 → django_lucy_assist-1.2.5}/lucy_assist/services/bug_notification_service.py +0 -0
- {django_lucy_assist-1.2.3 → django_lucy_assist-1.2.5}/lucy_assist/services/project_context_service.py +0 -0
- {django_lucy_assist-1.2.3 → django_lucy_assist-1.2.5}/lucy_assist/signals.py +0 -0
- {django_lucy_assist-1.2.3 → django_lucy_assist-1.2.5}/lucy_assist/static/lucy_assist/image/icon-lucy.png +0 -0
- {django_lucy_assist-1.2.3 → django_lucy_assist-1.2.5}/lucy_assist/templates/lucy_assist/partials/documentation_content.html +0 -0
- {django_lucy_assist-1.2.3 → django_lucy_assist-1.2.5}/lucy_assist/tests/__init__.py +0 -0
- {django_lucy_assist-1.2.3 → django_lucy_assist-1.2.5}/lucy_assist/tests/factories/__init__.py +0 -0
- {django_lucy_assist-1.2.3 → django_lucy_assist-1.2.5}/lucy_assist/tests/factories/lucy_assist_factories.py +0 -0
- {django_lucy_assist-1.2.3 → django_lucy_assist-1.2.5}/lucy_assist/tests/test_lucy_assist.py +0 -0
- {django_lucy_assist-1.2.3 → django_lucy_assist-1.2.5}/lucy_assist/urls.py +0 -0
- {django_lucy_assist-1.2.3 → django_lucy_assist-1.2.5}/lucy_assist/utils/__init__.py +0 -0
- {django_lucy_assist-1.2.3 → django_lucy_assist-1.2.5}/lucy_assist/utils/log_utils.py +0 -0
- {django_lucy_assist-1.2.3 → django_lucy_assist-1.2.5}/lucy_assist/utils/message_utils.py +0 -0
- {django_lucy_assist-1.2.3 → django_lucy_assist-1.2.5}/lucy_assist/utils/token_utils.py +0 -0
- {django_lucy_assist-1.2.3 → django_lucy_assist-1.2.5}/lucy_assist/views/__init__.py +0 -0
- {django_lucy_assist-1.2.3 → django_lucy_assist-1.2.5}/lucy_assist/views/api_views.py +0 -0
- {django_lucy_assist-1.2.3 → django_lucy_assist-1.2.5}/setup.cfg +0 -0
{django_lucy_assist-1.2.3 → django_lucy_assist-1.2.5}/django_lucy_assist.egg-info/SOURCES.txt
RENAMED
|
@@ -15,11 +15,6 @@ lucy_assist/context_processors.py
|
|
|
15
15
|
lucy_assist/signals.py
|
|
16
16
|
lucy_assist/urls.py
|
|
17
17
|
lucy_assist/migrations/0001_initial.py
|
|
18
|
-
lucy_assist/migrations/0002_configurationlucyassist_prompt_complementaire.py
|
|
19
|
-
lucy_assist/migrations/0003_configurationlucyassist_crud_views_mapping.py
|
|
20
|
-
lucy_assist/migrations/0004_configurationlucyassist_system_prompt.py
|
|
21
|
-
lucy_assist/migrations/0005_configurationlucyassist_project_context.py
|
|
22
|
-
lucy_assist/migrations/0006_remove_configurationlucyassist_prompt_complementaire.py
|
|
23
18
|
lucy_assist/migrations/__init__.py
|
|
24
19
|
lucy_assist/models/__init__.py
|
|
25
20
|
lucy_assist/models/base.py
|
|
@@ -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.5'
|
|
9
9
|
__author__ = 'Revolucy'
|
|
10
10
|
|
|
11
11
|
default_app_config = 'lucy_assist.apps.LucyAssistConfig'
|
|
@@ -19,8 +19,8 @@ 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', '
|
|
23
|
-
readonly_fields = ('crud_views_mapping_display', 'model_app_mapping_display'
|
|
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')
|
|
24
24
|
fieldsets = (
|
|
25
25
|
('Configuration Tokens', {
|
|
26
26
|
'fields': ('tokens_disponibles', 'prix_par_million_tokens', 'actif')
|
|
@@ -33,17 +33,12 @@ class ConfigurationLucyAssistAdmin(admin.ModelAdmin):
|
|
|
33
33
|
'classes': ('collapse',),
|
|
34
34
|
'description': 'Le prompt systeme est initialise automatiquement si vide.'
|
|
35
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.'
|
|
40
|
-
}),
|
|
41
36
|
('Mapping Automatique (lecture seule)', {
|
|
42
37
|
'fields': ('crud_views_mapping_display', 'model_app_mapping_display'),
|
|
43
38
|
'classes': ('collapse',)
|
|
44
39
|
}),
|
|
45
40
|
)
|
|
46
|
-
actions = ['refresh_crud_views'
|
|
41
|
+
actions = ['refresh_crud_views']
|
|
47
42
|
|
|
48
43
|
def nb_vues_crud(self, obj):
|
|
49
44
|
"""Affiche le nombre de modeles avec des vues CRUD decouvertes."""
|
|
@@ -52,19 +47,13 @@ class ConfigurationLucyAssistAdmin(admin.ModelAdmin):
|
|
|
52
47
|
return 0
|
|
53
48
|
nb_vues_crud.short_description = "Modeles CRUD"
|
|
54
49
|
|
|
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
|
|
60
|
-
|
|
61
50
|
def crud_views_mapping_display(self, obj):
|
|
62
|
-
"""Affiche le mapping des vues CRUD de
|
|
51
|
+
"""Affiche le mapping des vues CRUD de maniere lisible."""
|
|
63
52
|
import json
|
|
64
53
|
if obj.crud_views_mapping:
|
|
65
54
|
return json.dumps(obj.crud_views_mapping, indent=2, ensure_ascii=False)
|
|
66
|
-
return "Aucune vue
|
|
67
|
-
crud_views_mapping_display.short_description = "Vues CRUD
|
|
55
|
+
return "Aucune vue decouverte. Utilisez l'action 'Rafraichir les vues CRUD'."
|
|
56
|
+
crud_views_mapping_display.short_description = "Vues CRUD decouvertes"
|
|
68
57
|
|
|
69
58
|
def model_app_mapping_display(self, obj):
|
|
70
59
|
"""Affiche le mapping modele -> app de maniere lisible."""
|
|
@@ -74,13 +63,6 @@ class ConfigurationLucyAssistAdmin(admin.ModelAdmin):
|
|
|
74
63
|
return "Aucun mapping. Sera construit automatiquement."
|
|
75
64
|
model_app_mapping_display.short_description = "Mapping Modele -> App"
|
|
76
65
|
|
|
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
66
|
@admin.action(description="Rafraichir les vues CRUD decouvertes")
|
|
85
67
|
def refresh_crud_views(self, request, queryset):
|
|
86
68
|
"""Action admin pour rafraichir le mapping des vues CRUD."""
|
|
@@ -92,18 +74,3 @@ class ConfigurationLucyAssistAdmin(admin.ModelAdmin):
|
|
|
92
74
|
request,
|
|
93
75
|
f"Mapping rafraichi: {nb_models} modeles, {nb_views} vues decouvertes."
|
|
94
76
|
)
|
|
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
|
-
)
|
|
@@ -67,6 +67,10 @@ class LucyAssistSettings:
|
|
|
67
67
|
# Attributs de l'utilisateur a copier vers la requete
|
|
68
68
|
# Ex: ['franchise', 'tenant', 'organization']
|
|
69
69
|
'REQUEST_USER_ATTRS': [],
|
|
70
|
+
|
|
71
|
+
# Forcer l'utilisation des vues CRUD (pas de fallback ORM direct)
|
|
72
|
+
# Si True, Lucy refusera de creer/modifier/supprimer si aucune vue n'est trouvee
|
|
73
|
+
'CRUD_VIEWS_ONLY': True,
|
|
70
74
|
}
|
|
71
75
|
|
|
72
76
|
def __init__(self):
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Constantes pour Lucy Assist
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class LucyAssistConstantes:
|
|
7
|
+
"""Constantes générales de Lucy Assist"""
|
|
8
|
+
|
|
9
|
+
# Prix par million de tokens (en euros)
|
|
10
|
+
PRIX_PAR_MILLION_TOKENS = 50.0
|
|
11
|
+
|
|
12
|
+
# Nombre moyen de tokens par conversation
|
|
13
|
+
TOKENS_MOYENS_PAR_CONVERSATION = 2000
|
|
14
|
+
|
|
15
|
+
# Nombre de conversations estimées pour 1 million de tokens
|
|
16
|
+
CONVERSATIONS_PAR_MILLION = 500 # 1_000_000 / 2000
|
|
17
|
+
|
|
18
|
+
class Repondant:
|
|
19
|
+
"""Types de répondants dans une conversation"""
|
|
20
|
+
UTILISATEUR = 'UTILISATEUR'
|
|
21
|
+
CHATBOT = 'CHATBOT'
|
|
22
|
+
|
|
23
|
+
tuples = [
|
|
24
|
+
(UTILISATEUR, 'Utilisateur'),
|
|
25
|
+
(CHATBOT, 'Lucy Assist'),
|
|
26
|
+
]
|
|
27
|
+
|
|
28
|
+
class TypeAction:
|
|
29
|
+
"""Types d'actions que Lucy Assist peut effectuer"""
|
|
30
|
+
AIDE_NAVIGATION = 'AIDE_NAVIGATION'
|
|
31
|
+
RECHERCHE = 'RECHERCHE'
|
|
32
|
+
CRUD = 'CRUD'
|
|
33
|
+
ANALYSE_BUG = 'ANALYSE_BUG'
|
|
34
|
+
EXPLICATION = 'EXPLICATION'
|
|
35
|
+
|
|
36
|
+
tuples = [
|
|
37
|
+
(AIDE_NAVIGATION, 'Aide à la navigation'),
|
|
38
|
+
(RECHERCHE, 'Recherche d\'objets'),
|
|
39
|
+
(CRUD, 'Création/Modification/Suppresion d\'objets'),
|
|
40
|
+
(ANALYSE_BUG, 'Analyse de bug'),
|
|
41
|
+
(EXPLICATION, 'Explication de fonctionnalité'),
|
|
42
|
+
]
|
|
43
|
+
|
|
44
|
+
class StatutConversation:
|
|
45
|
+
"""Statuts possibles d'une conversation"""
|
|
46
|
+
ACTIVE = 'ACTIVE'
|
|
47
|
+
ARCHIVEE = 'ARCHIVEE'
|
|
48
|
+
|
|
49
|
+
tuples = [
|
|
50
|
+
(ACTIVE, 'Active'),
|
|
51
|
+
(ARCHIVEE, 'Archivée'),
|
|
52
|
+
]
|
|
53
|
+
|
|
54
|
+
# Prompts systeme pour Mistral
|
|
55
|
+
SYSTEM_PROMPTS = {
|
|
56
|
+
'default': """Tu es Lucy, une assistante IA sympathique et efficace integree dans {application_name}.
|
|
57
|
+
Tu aides les utilisateurs a naviguer et effectuer des actions dans l'application.
|
|
58
|
+
|
|
59
|
+
## TES CAPACITES
|
|
60
|
+
|
|
61
|
+
1. **Aide contextuelle** : Tu vois la page ou se trouve l'utilisateur et tu proposes une aide adaptee
|
|
62
|
+
2. **Recherche intelligente** : Tu peux chercher n'importe quel objet de base de données, suivant les permissions de l'utilisateur connectés
|
|
63
|
+
3. **Creation assistee** : Tu peux creer des elements directement via la conversation, suivant les CRUD disponibles et les permissions de l'utilisateur connectés
|
|
64
|
+
4. **Analyse de bugs** : Tu peux analyser les problemes signales par l'utilisateur en inspectant le projet GIT
|
|
65
|
+
|
|
66
|
+
## COMPORTEMENT - ACTION FIRST
|
|
67
|
+
|
|
68
|
+
Quand l'utilisateur demande une action (creer, modifier, chercher, supprimer) :
|
|
69
|
+
-> EXECUTE L'ACTION IMMEDIATEMENT avec les tools disponibles, UNIQUEMENT si les vues de CRUD sont disponibles dans le projet
|
|
70
|
+
-> Passe par les vues CRUD pour qu'on puisse avoir les logs, et que si il y a des services connecté aux vues, ceux soit appelés.
|
|
71
|
+
-> Ne te contente pas d'expliquer comment faire
|
|
72
|
+
|
|
73
|
+
Quand l'utilisateur pose une question ou demande de l'aide :
|
|
74
|
+
-> Reponds de maniere claire et concise
|
|
75
|
+
-> Propose des actions concretes avec des liens
|
|
76
|
+
|
|
77
|
+
## LIMITES STRICTES
|
|
78
|
+
|
|
79
|
+
Tu es EXCLUSIVEMENT dediee a l'aide sur {application_name}.
|
|
80
|
+
|
|
81
|
+
### Regle absolue sur les modeles
|
|
82
|
+
Tu ne peux travailler QU'AVEC les modeles listes dans "MODELES DISPONIBLES" ci-dessous.
|
|
83
|
+
- Si un modele n'est PAS dans la liste -> il N'EXISTE PAS dans cette application
|
|
84
|
+
- Ne JAMAIS inventer, supposer ou suggerer des modeles/fonctionnalites absents de la liste
|
|
85
|
+
- Ne JAMAIS parler de "logements", "produits", "commandes" etc. si ces modeles ne sont pas listes
|
|
86
|
+
|
|
87
|
+
Avant toute action CRUD, VERIFIE que le modele demande est dans la liste.
|
|
88
|
+
Si le modele n'existe pas, reponds :
|
|
89
|
+
"Cette fonctionnalite n'est pas disponible dans {application_name}. Voici ce que je peux faire : [lister les modeles disponibles]"
|
|
90
|
+
|
|
91
|
+
### Demandes hors sujet
|
|
92
|
+
Tu REFUSES POLIMENT :
|
|
93
|
+
- Questions sans rapport avec l'application
|
|
94
|
+
- Demandes de redaction, traduction, culture generale, recettes, etc.
|
|
95
|
+
|
|
96
|
+
Reponse type :
|
|
97
|
+
"Je suis Lucy, l'assistante de {application_name}. Je ne peux repondre qu'aux questions concernant l'application."
|
|
98
|
+
|
|
99
|
+
IMPORTANT : Ne donne JAMAIS la reponse meme partiellement. Refuse et redirige vers l'application.
|
|
100
|
+
|
|
101
|
+
## COMMUNICATION
|
|
102
|
+
|
|
103
|
+
Tu parles a un UTILISATEUR FINAL (pas un developpeur) :
|
|
104
|
+
- Langage simple et accessible
|
|
105
|
+
- Reponses courtes et directes
|
|
106
|
+
- Liens cliquables vers les pages (utilise navigate_to_page)
|
|
107
|
+
- Ne JAMAIS mentionner : fichiers, code, GitLab, classes Python, chemins techniques
|
|
108
|
+
|
|
109
|
+
## AIDE CONTEXTUELLE
|
|
110
|
+
|
|
111
|
+
Utilise le contexte de la page pour personnaliser ton aide :
|
|
112
|
+
- Sur une liste : propose de filtrer, chercher, ou creer un nouvel element
|
|
113
|
+
- Sur un formulaire : aide a remplir les champs ou explique leur utilite
|
|
114
|
+
- Sur un detail : propose de modifier, supprimer, ou voir les elements lies
|
|
115
|
+
|
|
116
|
+
## EXEMPLES DE BONNES REPONSES
|
|
117
|
+
|
|
118
|
+
Recherche :
|
|
119
|
+
"J'ai trouve 3 clients correspondant a 'Dupont' : [Jean Dupont](/client/42/), [Marie Dupont](/client/87/), [Dupont SARL](/client/156/)"
|
|
120
|
+
|
|
121
|
+
Creation :
|
|
122
|
+
"J'ai cree le membre Jean Martin (ID: 234). [Voir sa fiche](/membre/234/)"
|
|
123
|
+
|
|
124
|
+
Aide :
|
|
125
|
+
"Sur cette page, vous pouvez :
|
|
126
|
+
- Modifier les informations en cliquant sur les champs
|
|
127
|
+
- [Voir l'historique](/client/42/historique/)
|
|
128
|
+
- [Supprimer ce client](/client/42/delete/)"
|
|
129
|
+
|
|
130
|
+
## PROCEDURE DE SUPPRESSION
|
|
131
|
+
|
|
132
|
+
OBLIGATOIRE avant toute suppression :
|
|
133
|
+
1. Utilise `get_deletion_impact` pour analyser les consequences
|
|
134
|
+
2. Montre clairement ce qui sera supprime (objets en cascade, etc.)
|
|
135
|
+
3. Demande confirmation explicite
|
|
136
|
+
4. Supprime SEULEMENT apres confirmation avec `confirmed: true`
|
|
137
|
+
|
|
138
|
+
## CONTEXTE ACTUEL
|
|
139
|
+
|
|
140
|
+
Page : {page_context}
|
|
141
|
+
Permissions : {user_permissions}
|
|
142
|
+
|
|
143
|
+
## MODELES DISPONIBLES (LISTE EXHAUSTIVE)
|
|
144
|
+
Voici les SEULS modeles existants dans cette application. Tout autre modele N'EXISTE PAS.
|
|
145
|
+
{available_models}
|
|
146
|
+
|
|
147
|
+
Si "Aucun modele" est affiche, tu ne peux effectuer AUCUNE operation CRUD.
|
|
148
|
+
""",
|
|
149
|
+
'crud': """Tu dois aider l'utilisateur à créer ou modifier un objet.
|
|
150
|
+
Formulaire disponible : {form_info}
|
|
151
|
+
Champs requis : {required_fields}
|
|
152
|
+
""",
|
|
153
|
+
'bug_analysis': """Analyse le problème signalé par l'utilisateur.
|
|
154
|
+
Code source pertinent : {code_context}
|
|
155
|
+
Erreur rapportée : {error_message}
|
|
156
|
+
""",
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
# Questions fréquentes par défaut (utilisées si non configurées dans le modèle)
|
|
160
|
+
QUESTIONS_FREQUENTES_DEFAULT = [
|
|
161
|
+
"Comment créer un nouvel enregistrement ?",
|
|
162
|
+
"Comment effectuer une recherche ?",
|
|
163
|
+
"Comment exporter des données ?",
|
|
164
|
+
"Comment modifier mon profil ?",
|
|
165
|
+
"Quelles sont les fonctionnalités disponibles ?",
|
|
166
|
+
]
|
{django_lucy_assist-1.2.3 → django_lucy_assist-1.2.5}/lucy_assist/migrations/0001_initial.py
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Generated by Django 6.0.
|
|
1
|
+
# Generated by Django 6.0.2 on 2026-02-04 14:09
|
|
2
2
|
|
|
3
3
|
import django.db.models.deletion
|
|
4
4
|
from django.conf import settings
|
|
@@ -26,7 +26,9 @@ class Migration(migrations.Migration):
|
|
|
26
26
|
('questions_frequentes', models.JSONField(blank=True, default=list)),
|
|
27
27
|
('actif', models.BooleanField(default=True)),
|
|
28
28
|
('avatar', models.ImageField(blank=True, null=True, upload_to='')),
|
|
29
|
+
('system_prompt', models.TextField(blank=True, default='')),
|
|
29
30
|
('model_app_mapping', models.JSONField(blank=True, default=dict)),
|
|
31
|
+
('crud_views_mapping', models.JSONField(blank=True, default=dict)),
|
|
30
32
|
],
|
|
31
33
|
options={
|
|
32
34
|
'verbose_name': 'Configuration Lucy Assist',
|
|
@@ -41,13 +41,6 @@ class ConfigurationLucyAssist(LucyAssistBaseModel):
|
|
|
41
41
|
# }
|
|
42
42
|
crud_views_mapping = models.JSONField(blank=True, default=dict)
|
|
43
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
|
-
|
|
51
44
|
class Meta:
|
|
52
45
|
verbose_name = "Configuration Lucy Assist"
|
|
53
46
|
verbose_name_plural = "Configuration Lucy Assist"
|
|
@@ -268,10 +261,6 @@ class ConfigurationLucyAssist(LucyAssistBaseModel):
|
|
|
268
261
|
available_models=available_models
|
|
269
262
|
)
|
|
270
263
|
|
|
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}"
|
|
274
|
-
|
|
275
264
|
return prompt
|
|
276
265
|
|
|
277
266
|
def _get_application_name(self) -> str:
|
|
@@ -324,111 +313,6 @@ class ConfigurationLucyAssist(LucyAssistBaseModel):
|
|
|
324
313
|
|
|
325
314
|
return "\n".join(descriptions) if descriptions else "Aucun modele configure"
|
|
326
315
|
|
|
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
|
|
431
|
-
|
|
432
316
|
|
|
433
317
|
def get_default_model_app_mapping() -> dict:
|
|
434
318
|
"""
|