Spaces:
Sleeping
Sleeping
| # 🚀 Rust Asset Generator - Integration Guide | |
| ## Pour ton Dashboard | |
| ### ✅ Prerequis | |
| Tu as besoin: | |
| 1. **Rust installé** (https://rustup.rs/) | |
| 2. **Smart Router fonctionnel** (http://localhost:8000) | |
| 3. **Variables d'env configurées** | |
| --- | |
| ## 1️⃣ Build le Binary | |
| ```bash | |
| cd Engine | |
| # Build en release (optimisé) | |
| cargo build --release | |
| # Résultat: ./target/release/asset_generator.exe (Windows) | |
| # ou ./target/release/asset_generator (Linux/Mac) | |
| ``` | |
| **Temps:** ~2-3 minutes première fois, <10sec après | |
| --- | |
| ## 2️⃣ Configure tes Variables d'Env | |
| Crée un fichier `.env` à la racine du projet: | |
| ```env | |
| # Requis | |
| AI_SMART_ROUTER_URL=http://localhost:8000 | |
| API_SECRET=ta_clé_secrète | |
| # Optional | |
| OPENROUTER_API_KEY=clé_fallback_optionnelle | |
| IMAGE_GEN_MODE=api | |
| # Logging | |
| RUST_LOG=info | |
| ``` | |
| --- | |
| ## 3️⃣ Utilise avec ton Dashboard | |
| ### Option A: Appel depuis Python | |
| ```python | |
| import subprocess | |
| import json | |
| from pathlib import Path | |
| # Lancer le moteur Rust | |
| result = subprocess.run([ | |
| "./Engine/target/release/asset_generator", | |
| "--story", "rimouski" | |
| ], capture_output=True, text=True) | |
| if result.returncode == 0: | |
| print("✅ Génération réussie!") | |
| else: | |
| print(f"❌ Erreur: {result.stderr}") | |
| # Les fichiers générés sont dans: | |
| # stories/rimouski/assets/images/ | |
| # stories/rimouski/assets/depths/ | |
| # stories/rimouski/assets/scenes/ | |
| ``` | |
| ### Option B: Appel depuis Dashboard Node | |
| ```javascript | |
| const { spawn } = require('child_process'); | |
| function generateAssets(storyId) { | |
| return new Promise((resolve, reject) => { | |
| const process = spawn('./Engine/target/release/asset_generator', | |
| ['--story', storyId] | |
| ); | |
| let output = ''; | |
| process.stdout.on('data', (data) => { | |
| output += data; | |
| console.log(`[Generator] ${data}`); | |
| }); | |
| process.on('close', (code) => { | |
| if (code === 0) { | |
| resolve(output); | |
| } else { | |
| reject(new Error(`Generator failed with code ${code}`)); | |
| } | |
| }); | |
| }); | |
| } | |
| // Utilise | |
| generateAssets('rimouski') | |
| .then(() => console.log('✅ Assets générés')) | |
| .catch(err => console.error('❌', err)); | |
| ``` | |
| --- | |
| ## 4️⃣ Résultats Générés | |
| Après exécution, tu auras: | |
| ``` | |
| stories/[story-id]/assets/ | |
| ├── images/ | |
| │ ├── scene_1.png ✅ Image générée | |
| │ ├── scene_2.png | |
| │ └── ... | |
| ├── depths/ | |
| │ ├── scene_1.png (Depth map) | |
| │ └── ... | |
| ├── scenes/ | |
| │ ├── scene_1.txt (Prompt original) | |
| │ └── ... | |
| ├── on-screen text/ | |
| │ ├── scene_1.txt (Texte overlay) | |
| │ └── ... | |
| └── sounds/ (À remplir manuellement) | |
| ``` | |
| --- | |
| ## 5️⃣ Intégration avec Progress Tracking | |
| Le moteur écrit la progression dans `current_task.json`: | |
| ```python | |
| import json | |
| import time | |
| def monitor_progress(content_root): | |
| """Surveille la génération en temps réel""" | |
| task_file = Path(content_root) / "current_task.json" | |
| while task_file.exists(): | |
| try: | |
| with open(task_file, 'r') as f: | |
| progress = json.load(f) | |
| print(f"📊 {progress['story']}: {progress['step']} ({progress['progress']}%)") | |
| except: | |
| pass | |
| time.sleep(1) | |
| # Utilise dans ton dashboard | |
| monitor_progress('./stories') | |
| ``` | |
| --- | |
| ## 6️⃣ Commandes Disponibles | |
| ```bash | |
| # Générer une seule histoire | |
| ./asset_generator --story rimouski | |
| # Générer TOUTES les histoires | |
| ./asset_generator --all | |
| # Forcer la régénération (ignorer les existants) | |
| ./asset_generator --story rimouski --force | |
| # Voir l'aide | |
| ./asset_generator --help | |
| ``` | |
| --- | |
| ## 7️⃣ Gestion des Erreurs | |
| ### Si ça crash/fail | |
| Le moteur crée `.generation_checkpoint.json` pour reprendre: | |
| ```bash | |
| # Relance = reprend automatiquement du dernier succès | |
| ./asset_generator --story rimouski | |
| ``` | |
| ### Si tu veux forcer un reset | |
| ```bash | |
| rm stories/rimouski/.generation_checkpoint.json | |
| ./asset_generator --story rimouski --force | |
| ``` | |
| --- | |
| ## 8️⃣ Performance Tips | |
| | Situation | Action | | |
| |-----------|--------| | |
| | **Lent sur API** | Use local Smart Router si possible | | |
| | **Crash mémoire** | Baisse `max_cache_mb` dans optimization.rs (ligne ~20) | | |
| | **Images manquantes** | Utilise `--force` pour régénérer | | |
| | **Reprendre après crash** | Relance juste, utilise checkpoint automatiquement | | |
| --- | |
| ## 9️⃣ Dépannage | |
| ### ❌ "Binary not found" | |
| ```bash | |
| cd Engine | |
| cargo build --release | |
| ``` | |
| ### ❌ "Smart Router not responding" | |
| ```bash | |
| # Vérifier Smart Router | |
| curl http://localhost:8000/api/image | |
| # Ou checker variables | |
| echo $AI_SMART_ROUTER_URL | |
| ``` | |
| ### ❌ "API_SECRET missing" | |
| ```bash | |
| # Ajoute au .env | |
| echo "API_SECRET=your_secret" >> .env | |
| ``` | |
| ### ❌ "Out of memory" | |
| → Le moteur nettoie automatiquement | |
| → Attend quelques secondes entre scènes | |
| --- | |
| ## 🔟 Exemple Complet pour Dashboard | |
| ```python | |
| #!/usr/bin/env python3 | |
| """Intégration Rust Generator avec Dashboard""" | |
| import subprocess | |
| import json | |
| from pathlib import Path | |
| import time | |
| class RustAssetGenerator: | |
| def __init__(self, engine_path="./Engine"): | |
| self.binary = Path(engine_path) / "target/release/asset_generator" | |
| self.progress_file = Path("stories/../current_task.json") | |
| def build_if_needed(self): | |
| """Build le binary s'il existe pas""" | |
| if not self.binary.exists(): | |
| print("🔨 Building Rust generator...") | |
| subprocess.run(["cargo", "build", "--release"], cwd="Engine", check=True) | |
| def generate(self, story_id, force=False): | |
| """Générer les assets pour une histoire""" | |
| self.build_if_needed() | |
| cmd = [str(self.binary), "--story", story_id] | |
| if force: | |
| cmd.append("--force") | |
| print(f"🎬 Generating {story_id}...") | |
| # Monitor progress | |
| process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) | |
| while process.poll() is None: | |
| if self.progress_file.exists(): | |
| try: | |
| with open(self.progress_file) as f: | |
| progress = json.load(f) | |
| print(f" 📊 {progress['step']} ({progress['progress']}%)") | |
| except: | |
| pass | |
| time.sleep(1) | |
| if process.returncode == 0: | |
| print(f"✅ {story_id} completed!") | |
| return True | |
| else: | |
| print(f"❌ {story_id} failed!") | |
| print(process.stderr.read()) | |
| return False | |
| # Utilise | |
| if __name__ == "__main__": | |
| gen = RustAssetGenerator() | |
| gen.generate("rimouski", force=False) | |
| ``` | |
| --- | |
| ## 📋 Checklist d'Intégration | |
| - [ ] Rust installé (`rustup --version`) | |
| - [ ] Smart Router fonctionnel sur localhost:8000 | |
| - [ ] Variables d'env configurées (.env créé) | |
| - [ ] Binary buildé (`cargo build --release`) | |
| - [ ] Test manuel (`./target/release/asset_generator --story rimouski`) | |
| - [ ] Intégration au dashboard | |
| - [ ] Test avec vrai story | |
| - [ ] Progress tracking activé | |
| - [ ] Error recovery testé | |
| --- | |
| ## 🎁 C'est Tout! | |
| Le moteur Rust est **prêt à utiliser**. Il faut juste: | |
| 1. Build une fois | |
| 2. Appeler le binary depuis ton dashboard | |
| 3. Attendre les images dans `assets/images/` | |
| Aucun Python à modifier, aucune dépendance supplémentaire. Juste un binary très efficace qui utilise peu de RAM! 🚀 | |