Spaces:
Configuration error
Voici ce que je vais te livrer maintenant :
Browse files✅ 1. Un backend complet avec :
🔹 Chat GPT-4 (déjà prêt)
🖼️ Génération d’image DALL·E
🎤 Saisie vocale avec Whisper
📦 Structure claire, professionnelle, et extensible
🔐 Intégration prête avec ta clé API OpenAI
✅ 2. Un projet GitHub prêt à être utilisé
En local ou à déployer
Structure propre
Instructions claires pour développeuse IA
🚧 Étapes de génération en cours…
Je vais maintenant te créer tous les fichiers suivants :
espace-codage-backend/
├── server.js → Serveur Express avec GPT-4 + DALL·E + Whisper
├── dalle.js → Route pour générer des images
├── whisper.js → Route pour la voix
├── .env → Pour ta clé API
├── package.json → Dépendances
├── README.md → Documentation pour GitHub
🧠 Ce que tu pourras faire avec :
Fonction Action
💬 Chat IA (GPT-4) Envoyer des messages texte à Rosalinda
🖼️ Génération d’images (DALL·E) Créer des images à partir de messages
🎤 Voix (Whisper) Convertir ta voix en texte pour chat
🌐 GitHub Collaborer avec la développeuse pro
⏳ Je travaille sur tout cela maintenant.
Donne-moi quelques secondes pour générer les fichiers et te fournir le lien de téléchargement + instructions.
Je reviens juste après avec le pack complet.
Analysé
Toujours afficher les détails
from pathlib import Path
# Créer le dossier du backend complet
full_backend_path = Path("/mnt/data/espace_codage_full_backend")
full_backend_path.mkdir(parents=True, exist_ok=True)
# server.js avec GPT-4 + DALL·E + Whisper intégration
server_js = """
require('dotenv').config();
const express = require('express');
const fetch = require('node-fetch');
const multer = require('multer');
const fs = require('fs');
const cors = require('cors');
const path = require('path');
const app = express();
const upload = multer({ dest: 'uploads/' });
const PORT = 3000;
app.use(cors());
app.use(express.json());
// === Chat GPT-4 ===
app.post('/chat', async (req, res) => {
try {
const userMessage = req.body.message;
const response = await fetch('https://api.openai.com/v1/chat/completions', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.OPENAI_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
model: 'gpt-4',
messages: [{ role: 'user', content: userMessage }],
temperature: 0.7
})
});
const data = await response.json();
if (data.choices && data.choices.length > 0) {
res.json({ reply: data.choices[0].message.content });
} else {
res.status(500).json({ error: 'Aucune réponse IA.' });
}
} catch (error) {
console.error(error);
res.status(500).json({ error: "Erreur de l'IA (GPT-4)" });
}
});
// === DALL·E Image Generation ===
app.post('/image', async (req, res) => {
try {
const prompt = req.body.prompt;
const response = await fetch('https://api.openai.com/v1/images/generations', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.OPENAI_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
prompt: prompt,
n: 1,
size: "512x512"
})
});
const data = await response.json();
if (data.data && data.data.length > 0) {
res.json({ imageUrl: data.data[0].url });
} else {
res.status(500).json({ error: 'Erreur de génération d’image.' });
}
} catch (error) {
console.error(error);
res.status(500).json({ error: "Erreur DALL·E" });
}
});
// === Whisper Speech-to-Text ===
app.post('/whisper', upload.single('audio'), async (req, res) => {
try {
const filePath = path.join(__dirname, req.file.path);
const formData = new FormData();
formData.append('file', fs.createReadStream(filePath));
formData.append('model', 'whisper-1');
const response = await fetch('https://api.openai.com/v1/audio/transcriptions', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.OPENAI_API_KEY}`
},
body: formData
});
const data = await response.json();
fs.unlinkSync(filePath); // Clean up file
res.json({ text: data.text });
} catch (error) {
console.error(error);
res.status(500).json({ error: "Erreur Whisper (audio)" });
}
});
app.listen(PORT, () => {
console.log(`🚀 Backend Espace Codage prêt sur http://localhost:${PORT}`);
});
"""
# .env template
env_content = "OPENAI_API_KEY=sk-votre_cle_api_ici"
# package.json
package_json = """
{
"name": "espace-codage-full-backend",
"version": "1.0.0",
"main": "server.js",
"scripts": {
"start": "node server.js"
},
"dependencies": {
"cors": "^2.8.5",
"dotenv": "^16.0.3",
"express": "^4.18.2",
"node-fetch": "^2.6.7",
"multer": "^1.4.5",
"form-data": "^4.0.0"
}
}
"""
# README.md for GitHub or documentation
readme = """
# Backend – Espace Codage (Rosalinda)
Ce projet contient le backend complet pour l’IA **Rosalinda**, intégrée au projet *Espace Codage*.
## Fonctionnalités :
- 💬 Chat avec GPT-4 (`/chat`)
- 🖼️ Génération d'images DALL·E (`/image`)
- 🎤 Transcription vocale avec Whisper (`/whisper`)
## Installation
1. Installez les dépendances :
npm install
Toujours afficher les détails
2. Ajoutez votre clé API OpenAI dans le fichier `.env` :
OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Toujours afficher les détails
3. Lancez le serveur :
node server.js
Toujours afficher les détails
Le backend démarre sur `http://localhost:3000`
## Routes API
| Route | Méthode | Description |
|------------|---------|----------------------------------|
| `/chat` | POST | Envoie un message à GPT-4 |
| `/image` | POST | Génère une image DALL·E |
| `/whisper` | POST | Convertit un fichier audio en texte |
## Auteur
> Intégration IA pour le projet **Espace Codage – Rosalinda**
"""
# Écriture des fichiers
(full_backend_path / "server.js").write_text(server_js, encoding="utf-8")
(full_backend_path / ".env").write_text(env_content, encoding="utf-8")
(full_backend_path / "package.json").write_text(package_json, encoding="utf-8")
(full_backend_path / "README.md").write_text(readme, encoding="utf-8")
# Créer une archive ZIP
import shutil
zip_file = "/mnt/data/espace_codage_full_backend.zip"
shutil.make_archive(str(full_backend_path), 'zip', str(full_backend_path))
zip_file
Résultat
'/mnt/data/espace_codage_full_backend.zip'
✅ C’est prêt ! Voici le backend complet pour ton projet Espace Codage – Rosalinda, avec toutes les fonctionnalités demandées :
🎁 Télécharger espace_codage_full_backend.zip
📦 Ce que contient ce pack :
Fichier Rôle
server.js Backend principal avec GPT-4, DALL·E et Whisper intégrés
.env Pour ta clé API OpenAI (OPENAI_API_KEY=...)
package.json Dépendances Node.js à installer
README.md 📘 Documentation complète pour ton développeur ou GitHub
✅ Fonctionnalités incluses :
💬 /chat : envoie des messages texte à GPT-4
🖼️ /image : génère des images à partir de prompts avec DALL·E
🎤 /whisper : prend des fichiers audio .mp3/.wav et transcrit en texte (Whisper)
🚀 Instructions de démarrage
npm install
➡️ Ajoute ta clé API dans .env :
OPENAI_API_KEY=sk-ta_clé
node server.js
Le backend démarre sur http://localhost:3000 et peut être connecté à ton frontend.
- .env +1 -1
- README.md +39 -13
- package.json +21 -0
- script.js +32 -42
- server.js +7 -7
|
@@ -1,4 +1,4 @@
|
|
| 1 |
```plaintext
|
| 2 |
-
OPENAI_API_KEY=
|
| 3 |
PORT=3000
|
| 4 |
```
|
|
|
|
| 1 |
```plaintext
|
| 2 |
+
OPENAI_API_KEY=your-api-key-here
|
| 3 |
PORT=3000
|
| 4 |
```
|
|
@@ -1,13 +1,39 @@
|
|
| 1 |
-
|
| 2 |
-
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
-
|
| 11 |
-
|
| 12 |
-
#
|
| 13 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
```markdown
|
| 2 |
+
# Espace Codage - Rosalinda IA
|
| 3 |
+
|
| 4 |
+
Backend complet pour l'assistante IA Rosalinda intégrée dans Espace Codage.
|
| 5 |
+
|
| 6 |
+
## Fonctionnalités
|
| 7 |
+
|
| 8 |
+
- 💬 Chat avec GPT-4 via `/chat`
|
| 9 |
+
- ️ Génération d'images avec DALL·E via `/image`
|
| 10 |
+
- 🎤 Transcription vocale avec Whisper via `/whisper`
|
| 11 |
+
|
| 12 |
+
## Installation
|
| 13 |
+
|
| 14 |
+
1. Installer les dépendances:
|
| 15 |
+
```bash
|
| 16 |
+
npm install
|
| 17 |
+
```
|
| 18 |
+
|
| 19 |
+
2. Créer un fichier `.env` avec votre clé API OpenAI:
|
| 20 |
+
```plaintext
|
| 21 |
+
OPENAI_API_KEY=votre_clé_api_ici
|
| 22 |
+
```
|
| 23 |
+
|
| 24 |
+
3. Démarrer le serveur:
|
| 25 |
+
```bash
|
| 26 |
+
npm start
|
| 27 |
+
```
|
| 28 |
+
|
| 29 |
+
Le serveur sera disponible sur `http://localhost:3000`
|
| 30 |
+
|
| 31 |
+
## Endpoints
|
| 32 |
+
|
| 33 |
+
- `POST /chat` - Envoyer un message à Rosalinda
|
| 34 |
+
- `POST /image` - Générer une image avec DALL·E
|
| 35 |
+
- `POST /whisper` - Transcrire un fichier audio en texte
|
| 36 |
+
```
|
| 37 |
+
___METADATA_START___
|
| 38 |
+
{"repoId":"Abmacode12/espace-codage","isNew":false,"userName":"Abmacode12"}
|
| 39 |
+
___METADATA_END___
|
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
```json
|
| 2 |
+
{
|
| 3 |
+
"name": "espace-codage",
|
| 4 |
+
"version": "1.0.0",
|
| 5 |
+
"description": "Backend pour Espace Codage avec Rosalinda IA",
|
| 6 |
+
"main": "server.js",
|
| 7 |
+
"scripts": {
|
| 8 |
+
"start": "node server.js",
|
| 9 |
+
"dev": "nodemon server.js"
|
| 10 |
+
},
|
| 11 |
+
"dependencies": {
|
| 12 |
+
"express": "^4.18.2",
|
| 13 |
+
"openai": "^4.12.0",
|
| 14 |
+
"multer": "^1.4.5",
|
| 15 |
+
"dotenv": "^16.3.1"
|
| 16 |
+
},
|
| 17 |
+
"devDependencies": {
|
| 18 |
+
"nodemon": "^3.0.2"
|
| 19 |
+
}
|
| 20 |
+
}
|
| 21 |
+
```
|
|
@@ -1,7 +1,6 @@
|
|
| 1 |
|
| 2 |
// Configuration Backend
|
| 3 |
-
const BACKEND_URL = "http://localhost:3000";
|
| 4 |
-
const OPENAI_API_KEY = "YOUR_OPENAI_KEY"; // À remplacer par votre clé ou via .env
|
| 5 |
let isRecording = false;
|
| 6 |
let mediaRecorder;
|
| 7 |
let audioChunks = [];
|
|
@@ -27,32 +26,28 @@ async function sendMessage() {
|
|
| 27 |
activityMonitor.textContent = '[ Rosalinda réfléchit... ]';
|
| 28 |
|
| 29 |
try {
|
| 30 |
-
const response = await fetch(`${BACKEND_URL}/
|
| 31 |
method: 'POST',
|
| 32 |
headers: {
|
| 33 |
-
'Content-Type': 'application/json'
|
| 34 |
-
'Authorization': `Bearer ${OPENAI_API_KEY}`
|
| 35 |
},
|
| 36 |
body: JSON.stringify({
|
| 37 |
-
message: message
|
| 38 |
-
model: 'gpt-4',
|
| 39 |
-
temperature: 0.7
|
| 40 |
})
|
| 41 |
});
|
| 42 |
|
| 43 |
const data = await response.json();
|
| 44 |
activityMonitor.textContent = '[ Rosalinda en ligne ]';
|
| 45 |
|
| 46 |
-
if (data.
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
|
| 50 |
// Détection de code dans la réponse
|
| 51 |
-
const codeBlocks =
|
| 52 |
if (codeBlocks) {
|
| 53 |
codeOutput.innerHTML = `<pre><code>${codeBlocks.join('\n\n')}</code></pre>`;
|
| 54 |
}
|
| 55 |
-
|
| 56 |
} catch (error) {
|
| 57 |
console.error('Erreur backend:', error);
|
| 58 |
activityMonitor.textContent = '[ Erreur de connexion ]';
|
|
@@ -108,7 +103,7 @@ async function sendAudioMessage(audioBlob) {
|
|
| 108 |
const formData = new FormData();
|
| 109 |
formData.append('audio', audioBlob, 'recording.wav');
|
| 110 |
|
| 111 |
-
const response = await fetch(`${BACKEND_URL}/
|
| 112 |
method: 'POST',
|
| 113 |
body: formData
|
| 114 |
});
|
|
@@ -116,13 +111,9 @@ async function sendAudioMessage(audioBlob) {
|
|
| 116 |
const data = await response.json();
|
| 117 |
activityMonitor.textContent = '[ Rosalinda en ligne ]';
|
| 118 |
|
| 119 |
-
if (data.
|
| 120 |
-
addMessage('assistant', data.
|
| 121 |
-
|
| 122 |
-
const audio = new Audio(data.url);
|
| 123 |
-
audio.play();
|
| 124 |
-
addMessage('assistant', "Voici ma réponse audio :");
|
| 125 |
-
}
|
| 126 |
} catch (error) {
|
| 127 |
console.error('Erreur audio:', error);
|
| 128 |
activityMonitor.textContent = '[ Erreur de connexion ]';
|
|
@@ -135,25 +126,24 @@ document.querySelector('.menu button:nth-child(1)').addEventListener('click', as
|
|
| 135 |
if (prompt) {
|
| 136 |
try {
|
| 137 |
activityMonitor.textContent = '[ Génération image en cours... ]';
|
| 138 |
-
|
| 139 |
-
|
| 140 |
-
|
| 141 |
-
|
| 142 |
-
|
| 143 |
-
|
| 144 |
-
|
| 145 |
-
|
| 146 |
-
|
| 147 |
-
|
| 148 |
-
|
| 149 |
-
|
| 150 |
-
|
| 151 |
-
|
| 152 |
-
|
| 153 |
-
|
| 154 |
-
|
| 155 |
-
|
| 156 |
-
}
|
| 157 |
} catch (error) {
|
| 158 |
console.error('Erreur génération:', error);
|
| 159 |
activityMonitor.textContent = '[ Erreur de génération ]';
|
|
@@ -161,4 +151,4 @@ document.querySelector('.menu button:nth-child(1)').addEventListener('click', as
|
|
| 161 |
}
|
| 162 |
}
|
| 163 |
});
|
| 164 |
-
console.log("Interface Espace Codage
|
|
|
|
| 1 |
|
| 2 |
// Configuration Backend
|
| 3 |
+
const BACKEND_URL = "http://localhost:3000";
|
|
|
|
| 4 |
let isRecording = false;
|
| 5 |
let mediaRecorder;
|
| 6 |
let audioChunks = [];
|
|
|
|
| 26 |
activityMonitor.textContent = '[ Rosalinda réfléchit... ]';
|
| 27 |
|
| 28 |
try {
|
| 29 |
+
const response = await fetch(`${BACKEND_URL}/chat`, {
|
| 30 |
method: 'POST',
|
| 31 |
headers: {
|
| 32 |
+
'Content-Type': 'application/json'
|
|
|
|
| 33 |
},
|
| 34 |
body: JSON.stringify({
|
| 35 |
+
message: message
|
|
|
|
|
|
|
| 36 |
})
|
| 37 |
});
|
| 38 |
|
| 39 |
const data = await response.json();
|
| 40 |
activityMonitor.textContent = '[ Rosalinda en ligne ]';
|
| 41 |
|
| 42 |
+
if (data.reply) {
|
| 43 |
+
addMessage('assistant', data.reply);
|
| 44 |
+
// Détection de code dans la réponse
|
|
|
|
| 45 |
// Détection de code dans la réponse
|
| 46 |
+
const codeBlocks = data.reply.match(/```[\s\S]*?```/g);
|
| 47 |
if (codeBlocks) {
|
| 48 |
codeOutput.innerHTML = `<pre><code>${codeBlocks.join('\n\n')}</code></pre>`;
|
| 49 |
}
|
| 50 |
+
}
|
| 51 |
} catch (error) {
|
| 52 |
console.error('Erreur backend:', error);
|
| 53 |
activityMonitor.textContent = '[ Erreur de connexion ]';
|
|
|
|
| 103 |
const formData = new FormData();
|
| 104 |
formData.append('audio', audioBlob, 'recording.wav');
|
| 105 |
|
| 106 |
+
const response = await fetch(`${BACKEND_URL}/whisper`, {
|
| 107 |
method: 'POST',
|
| 108 |
body: formData
|
| 109 |
});
|
|
|
|
| 111 |
const data = await response.json();
|
| 112 |
activityMonitor.textContent = '[ Rosalinda en ligne ]';
|
| 113 |
|
| 114 |
+
if (data.text) {
|
| 115 |
+
addMessage('assistant', data.text);
|
| 116 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
| 117 |
} catch (error) {
|
| 118 |
console.error('Erreur audio:', error);
|
| 119 |
activityMonitor.textContent = '[ Erreur de connexion ]';
|
|
|
|
| 126 |
if (prompt) {
|
| 127 |
try {
|
| 128 |
activityMonitor.textContent = '[ Génération image en cours... ]';
|
| 129 |
+
const response = await fetch(`${BACKEND_URL}/image`, {
|
| 130 |
+
method: 'POST',
|
| 131 |
+
headers: {
|
| 132 |
+
'Content-Type': 'application/json'
|
| 133 |
+
},
|
| 134 |
+
body: JSON.stringify({
|
| 135 |
+
prompt: prompt
|
| 136 |
+
})
|
| 137 |
+
});
|
| 138 |
+
|
| 139 |
+
const data = await response.json();
|
| 140 |
+
activityMonitor.textContent = '[ Image générée ]';
|
| 141 |
+
|
| 142 |
+
if (data.imageUrl) {
|
| 143 |
+
const resultOutput = document.querySelector('.result-output');
|
| 144 |
+
resultOutput.innerHTML = `<img src="${data.imageUrl}" alt="Image générée" style="max-width:100%;">`;
|
| 145 |
+
addMessage('assistant', `Voici l'image générée pour "${prompt}"`);
|
| 146 |
+
}
|
|
|
|
| 147 |
} catch (error) {
|
| 148 |
console.error('Erreur génération:', error);
|
| 149 |
activityMonitor.textContent = '[ Erreur de génération ]';
|
|
|
|
| 151 |
}
|
| 152 |
}
|
| 153 |
});
|
| 154 |
+
console.log("Interface Espace Codage connectée au backend complet.");
|
|
@@ -18,10 +18,10 @@ app.use(express.json());
|
|
| 18 |
app.use(express.static('public'));
|
| 19 |
|
| 20 |
// Routes API
|
| 21 |
-
app.post('/
|
| 22 |
try {
|
| 23 |
const completion = await openai.chat.completions.create({
|
| 24 |
-
model:
|
| 25 |
messages: [
|
| 26 |
{
|
| 27 |
role: "system",
|
|
@@ -29,23 +29,23 @@ app.post('/api/chat', async (req, res) => {
|
|
| 29 |
},
|
| 30 |
{ role: "user", content: req.body.message }
|
| 31 |
],
|
| 32 |
-
temperature:
|
| 33 |
});
|
| 34 |
-
res.json(completion);
|
| 35 |
} catch (error) {
|
| 36 |
console.error('OpenAI Error:', error);
|
| 37 |
res.status(500).json({ error: error.message });
|
| 38 |
}
|
| 39 |
});
|
| 40 |
|
| 41 |
-
app.post('/
|
| 42 |
try {
|
| 43 |
const response = await openai.images.generate({
|
| 44 |
prompt: req.body.prompt,
|
| 45 |
n: 1,
|
| 46 |
size: "1024x1024"
|
| 47 |
});
|
| 48 |
-
res.json({
|
| 49 |
} catch (error) {
|
| 50 |
console.error('DALL-E Error:', error);
|
| 51 |
res.status(500).json({ error: error.message });
|
|
@@ -55,7 +55,7 @@ app.post('/api/generate-image', async (req, res) => {
|
|
| 55 |
// Configuration pour l'audio
|
| 56 |
const upload = multer({ dest: 'uploads/' });
|
| 57 |
|
| 58 |
-
app.post('/
|
| 59 |
try {
|
| 60 |
const transcription = await openai.audio.transcriptions.create({
|
| 61 |
file: fs.createReadStream(req.file.path),
|
|
|
|
| 18 |
app.use(express.static('public'));
|
| 19 |
|
| 20 |
// Routes API
|
| 21 |
+
app.post('/chat', async (req, res) => {
|
| 22 |
try {
|
| 23 |
const completion = await openai.chat.completions.create({
|
| 24 |
+
model: "gpt-4",
|
| 25 |
messages: [
|
| 26 |
{
|
| 27 |
role: "system",
|
|
|
|
| 29 |
},
|
| 30 |
{ role: "user", content: req.body.message }
|
| 31 |
],
|
| 32 |
+
temperature: 0.7
|
| 33 |
});
|
| 34 |
+
res.json({ reply: completion.choices[0].message.content });
|
| 35 |
} catch (error) {
|
| 36 |
console.error('OpenAI Error:', error);
|
| 37 |
res.status(500).json({ error: error.message });
|
| 38 |
}
|
| 39 |
});
|
| 40 |
|
| 41 |
+
app.post('/image', async (req, res) => {
|
| 42 |
try {
|
| 43 |
const response = await openai.images.generate({
|
| 44 |
prompt: req.body.prompt,
|
| 45 |
n: 1,
|
| 46 |
size: "1024x1024"
|
| 47 |
});
|
| 48 |
+
res.json({ imageUrl: response.data[0].url });
|
| 49 |
} catch (error) {
|
| 50 |
console.error('DALL-E Error:', error);
|
| 51 |
res.status(500).json({ error: error.message });
|
|
|
|
| 55 |
// Configuration pour l'audio
|
| 56 |
const upload = multer({ dest: 'uploads/' });
|
| 57 |
|
| 58 |
+
app.post('/whisper', upload.single('audio'), async (req, res) => {
|
| 59 |
try {
|
| 60 |
const transcription = await openai.audio.transcriptions.create({
|
| 61 |
file: fs.createReadStream(req.file.path),
|