feat: Intégration d'un assistant IA logisticien basé sur Gemini

- Ajout d'une Cloud Function `aiEquipmentProposal` utilisant le modèle Gemini avec function calling pour suggérer du matériel et des containers.
- Implémentation de plusieurs outils (tools) côté serveur pour permettre à l'IA d'interagir avec Firestore : `search_equipment`, `check_availability_batch`, `get_past_events`, `search_event_reference` et `search_containers`.
- Ajout de la dépendance `@google/generative-ai` dans le backend.
- Création d'un service Flutter `AiEquipmentAssistantService` pour communiquer avec la nouvelle Cloud Function.
- Ajout d'une interface de dialogue `AiEquipmentAssistantDialog` permettant aux utilisateurs de discuter avec l'IA pour affiner les propositions de matériel.
- Intégration de l'assistant IA dans la section de gestion du matériel des événements (`EventAssignedEquipmentSection`).
- Mise à jour de `DataService` avec de nouvelles méthodes de recherche et de vérification de disponibilité optimisées pour l'assistant.
- Activation du mode développement et configuration des identifiants de test dans `env.dart`.
- Optimisation des paramètres de la Cloud Function (timeout de 300s et 1GiB de RAM) pour supporter les traitements IA.
This commit is contained in:
ElPoyo
2026-03-24 12:00:30 +01:00
parent ecf4a5cede
commit 84c882ac0b
12 changed files with 2193 additions and 107 deletions

View File

@@ -7,3 +7,4 @@ SMTP_PASS="aL8@Rx8xqFrNij$a"
# URL de l'application
APP_URL="https://app.em2events.fr"
GEMINI_API_KEY="AIzaSyBdBdjFLma2pLenmFBlqZHArS4GVF-mclo"

File diff suppressed because it is too large Load Diff

View File

@@ -17,6 +17,7 @@ const { Storage } = require('@google-cloud/storage');
const auth = require('./utils/auth');
const helpers = require('./utils/helpers');
const { generateTTS } = require('./generateTTS');
const { handleAiEquipmentProposal } = require('./aiEquipmentProposal');
// Initialisation sécurisée
if (!admin.apps.length) {
@@ -33,6 +34,13 @@ const httpOptions = {
// Version: 2.0 - Ajout de l'invoker public pour résoudre les problèmes CORS
};
// Options dédiées pour les traitements IA potentiellement longs.
const aiHttpOptions = {
...httpOptions,
timeoutSeconds: 300,
memory: '1GiB',
};
// ============================================================================
// CORS Middleware
// ============================================================================
@@ -4263,3 +4271,20 @@ exports.generateTTSV2 = onRequest(ttsHttpOptions, async (req, res) => {
}
});
// ============================================================================
// AI - Assistant Logisticien (Gemini avec function calling côté serveur)
// ============================================================================
exports.aiEquipmentProposal = onRequest(aiHttpOptions, withCors(async (req, res) => {
try {
// Authentification Firebase obligatoire (pas de clé API côté client)
await auth.authenticateUser(req);
await handleAiEquipmentProposal(req, res);
} catch (error) {
logger.error('[aiEquipmentProposal] Error:', error);
if (!res.headersSent) {
res.status(500).json({ error: error.message });
}
}
}));

View File

@@ -8,6 +8,7 @@
"dependencies": {
"@google-cloud/storage": "^7.18.0",
"@google-cloud/text-to-speech": "^5.4.0",
"@google/generative-ai": "^0.21.0",
"axios": "^1.13.2",
"dotenv": "^17.2.3",
"envdot": "^0.0.3",
@@ -785,6 +786,15 @@
"node": ">=14.0.0"
}
},
"node_modules/@google/generative-ai": {
"version": "0.21.0",
"resolved": "https://registry.npmjs.org/@google/generative-ai/-/generative-ai-0.21.0.tgz",
"integrity": "sha512-7XhUbtnlkSEZK15kN3t+tzIMxsbKm/dSkKBFalj+20NvPKe1kBY7mR2P7vuijEn+f06z5+A8bVGKO0v39cr6Wg==",
"license": "Apache-2.0",
"engines": {
"node": ">=18.0.0"
}
},
"node_modules/@grpc/grpc-js": {
"version": "1.13.4",
"resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.13.4.tgz",

View File

@@ -16,6 +16,7 @@
"dependencies": {
"@google-cloud/storage": "^7.18.0",
"@google-cloud/text-to-speech": "^5.4.0",
"@google/generative-ai": "^0.21.0",
"axios": "^1.13.2",
"dotenv": "^17.2.3",
"envdot": "^0.0.3",