#!/usr/bin/env python3 """ VORTEX – Noyau d'ingénierie autonome Point d'entrée pour Hugging Face Space (Gradio) Version auto‑contenue – tous les modules sont remplacés par des stubs. """ import os import sys import json import tempfile import asyncio from pathlib import Path import gradio as gr # Création du dossier de données persistant os.makedirs("/app/data", exist_ok=True) # ------------------------------------------------------------ # 1. STUBS pour tous les modules importés (core, agents, sandbox) # ------------------------------------------------------------ class Kernel: """Stub pour core.kernel.KERNEL""" def __init__(self): self.safe_functions = {"print", "len", "range", "int", "str", "float", "list", "dict", "tuple"} self.modification_attempts = 0 self.energy_ratio = 0.9 self.uptime = 42 self.cpu_percent = 5.0 self.memory_percent = 20.0 self.status = "ok" self.degraded_config = {"mode": "normal"} def run_code(self, code: str, timeout: float = 10.0) -> dict: try: # Simuler une exécution sécurisée exec_globals = {"__builtins__": {fn: __builtins__[fn] for fn in self.safe_functions if fn in __builtins__}} exec(code, exec_globals) return {"success": True, "result": "Exécution simulée (stub)"} except Exception as e: return {"success": False, "error": str(e)} def get_health(self) -> dict: return { "status": self.status, "cpu_percent": self.cpu_percent, "memory_percent": self.memory_percent, "energy_ratio": self.energy_ratio, "uptime": self.uptime, "modification_attempts": self.modification_attempts } def get_degraded_mode_config(self) -> dict: return self.degraded_config def verify_integrity(self) -> bool: return True KERNEL = Kernel() class MemoryTier: """Énumération simplifiée pour les niveaux de mémoire""" CACHE = "cache" SHORT = "short" MEDIUM = "medium" LONG = "long" EPISODIC = "episodic" SEMANTIC = "semantic" META = "meta" class HierarchicalMemory: """Stub pour core.memory.HierarchicalMemory""" def __init__(self): self.storage = [] def ingest(self, content: str, tier: str, source: str, importance: float = 0.5): self.storage.append({"content": content, "tier": tier, "source": source, "importance": importance}) def retrieve(self, query: str, tier: str, top_k: int = 3): return [type('Entry', (), {'content': e['content'], 'tier': e['tier'], 'importance': e['importance']})() for e in self.storage[:top_k]] class CausalGraph: """Stub pour core.causal_graph.CausalGraph""" def __init__(self): self.edges = [] def add_edge(self, source, target, relation, weight=1.0): self.edges.append((source, target, relation, weight)) def causal_query(self, source, target=None, max_depth=3): return [[(source, target, relation)] for _,_,_ in self.edges[:3]] class TransferEngine: """Stub pour core.transfer_engine.TransferEngine""" def __init__(self): self.experiences = [] def add_experience(self, problem, solution): self.experiences.append((problem, solution)) def find_analogy(self, problem, top_k=2): return [f"Analogie pour '{problem}' (stub)" for _ in range(min(top_k, len(self.experiences)))] class MultiLLMEngine: """Stub pour agents.cognitive_engine.MultiLLMEngine""" def __init__(self, memory=None): self.memory = memory def generate(self, prompt: str, system: str = "", max_tokens: int = 512) -> str: return f"[STUB LLM] Réponse à : {prompt[:50]}..." class ResearchLoop: """Stub pour core.research_loop.ResearchLoop""" def __init__(self, llm, memory, executor): self.llm = llm self.memory = memory self.executor = executor async def run_one_cycle(self, domain: str) -> dict: return {"hypothesis": f"Hypothèse sur {domain} (stub)", "score": 0.75} class ProofSystem: """Stub pour core.proof_system.ProofSystem""" def __init__(self): self.proofs = [] def add_proof(self, claim, evidence): self.proofs.append({"claim": claim, "evidence": evidence}) def get_proofs(self, limit=10): return self.proofs[-limit:] class MetaMetaOptimizer: """Stub pour core.meta_meta_optimizer.MetaMetaOptimizer""" def __init__(self, kernel, llm, current_optimizer_path): self.kernel = kernel self.llm = llm self.path = current_optimizer_path def get_status(self) -> dict: return {"optimizer": self.path, "score": 0.9} def rollback(self) -> bool: return True class CEOAgent: async def execute_task(self, task: dict) -> dict: return {"decision": f"Plan stratégique pour {task.get('strategy', '')}", "status": "ok"} ceo = CEOAgent() cfo = CFOAgent = type('', (), {}) # placeholder cto = CFOAgent ops = CFOAgent def execute_safe(code: str, timeout: float = 10.0) -> dict: """Stub pour sandbox.secure_executor.execute_safe""" try: exec(code, {}) return {"success": True, "result": "Exécution sécurisée (stub)"} except Exception as e: return {"success": False, "error": str(e)} # ------------------------------------------------------------------- # Fin des stubs # ------------------------------------------------------------------- memory = HierarchicalMemory() causal_graph = CausalGraph() transfer_engine = TransferEngine() llm_engine = MultiLLMEngine(memory) if (os.getenv("HF_TOKEN") or os.getenv("OPENAI_API_KEY")) else None research_loop = ResearchLoop(llm_engine, memory, execute_safe) proof_system = ProofSystem() meta_optimizer = MetaMetaOptimizer(KERNEL, llm_engine, current_optimizer_path="core/optimizer.py") # Ajout d'une mémoire initiale memory.ingest("Noyau VORTEX initialisé", MemoryTier.META, "system", importance=1.0) # ------------------------------------------------------------------- # Fonctions utilitaires pour l'interface # ------------------------------------------------------------------- def run_code_safe(code: str) -> str: if not code.strip(): return "Aucun code à exécuter." result = KERNEL.run_code(code, timeout=10.0) if result.get("success"): return result.get("result", "Succès (pas de sortie)") else: return f"Erreur : {result.get('error', 'Inconnue')}" def get_health_report() -> str: h = KERNEL.get_health() degraded_config = KERNEL.get_degraded_mode_config() return f""" **Santé du système : {h['status'].upper()}** - CPU : {h['cpu_percent']:.1f}% - Mémoire : {h['memory_percent']:.1f}% - Énergie restante : {h['energy_ratio']:.2f} - Uptime : {h['uptime']:.0f} sec - Tentatives de modification : {h['modification_attempts']} **Configuration mode dégradé :** {json.dumps(degraded_config, indent=2)} """ def store_memory(content: str, tier: str, importance: float = 0.5): try: # On accepte n'importe quel tier string memory.ingest(content, tier, "user", importance=importance) return f"Mémorisé dans le niveau {tier}." except Exception as e: return f"Erreur : {e}" def query_memory(query: str, tier: str, top_k: int = 3) -> str: try: entries = memory.retrieve(query, tier, top_k) if not entries: return "Aucune mémoire trouvée." out = [] for e in entries: out.append(f"[{e.tier}] {e.content[:200]}... (imp={e.importance:.2f})") return "\n\n".join(out) except Exception as e: return f"Erreur : {e}" def add_causal_edge(source: str, target: str, relation: str, weight: float = 1.0): causal_graph.add_edge(source, target, relation, weight) return f"Arête ajoutée : {source} -{relation}-> {target} (poids={weight})" def query_causal(source: str, target: str = "", max_depth: int = 3) -> str: paths = causal_graph.causal_query(source, target if target else None, max_depth) if not paths: return "Aucun chemin causal trouvé." return "\n".join([str(p) for p in paths[:10]]) def transfer_analogy(problem: str) -> str: analogues = transfer_engine.find_analogy(problem, top_k=2) if not analogues: return "Aucune analogie trouvée." return "\n\n---\n\n".join([f"Analogie {i+1}:\n{a}" for i, a in enumerate(analogues)]) def add_experience(problem: str, solution: str): transfer_engine.add_experience(problem, solution) return "Expérience ajoutée au moteur de transfert." async def run_research_cycle(domain: str) -> str: if not llm_engine: return "La boucle de recherche nécessite un moteur LLM (définissez HF_TOKEN, OPENAI_API_KEY ou ANTHROPIC_API_KEY)." result = await research_loop.run_one_cycle(domain) return f"**Hypothèse :** {result['hypothesis']}\n**Score :** {result['score']:.3f}" # Le callback Gradio peut être async directement async def sync_run_research(domain: str): return await run_research_cycle(domain) def show_proofs() -> str: proofs = proof_system.get_proofs(10) if not proofs: return "Aucune preuve enregistrée." return json.dumps(proofs, indent=2) async def meta_status(): return json.dumps(await asyncio.to_thread(meta_optimizer.get_status), indent=2) def rollback_optimizer(): success = meta_optimizer.rollback() return "Restitution effectuée." if success else "Échec de la restitution – aucune sauvegarde." async def executive_decision(question: str) -> str: # Appel asynchrone direct result = await ceo.execute_task({"strategy": question}) return f"Décision du CEO : {json.dumps(result, indent=2)}" def check_token_status() -> str: token = os.getenv("HF_TOKEN") if token: masked = token[:4] + "..." + token[-4:] if len(token) > 8 else "***" return f"✅ Token HF présent : {masked}" else: return "❌ Token HF absent. Définissez HF_TOKEN dans les secrets du Space." # ------------------------------------------------------------------- # Interface Gradio # ------------------------------------------------------------------- with gr.Blocks(title="VORTEX – Noyau d'ingénierie autonome") as demo: gr.Markdown(""" # 🌀 Noyau VORTEX **Optimisation de code autonome & recherche** *Noyau immuable · Bac à sable sécurisé · Mémoire hiérarchique · Raisonnement causal · Méta-méta apprentissage* """) with gr.Tabs(): with gr.TabItem("💻 Bac à sable"): gr.Markdown("Exécutez du code Python sécurisé. **Les imports dangereux (os, sys, etc.) sont bloqués.**") code_input = gr.Code(label="Code Python", language="python", lines=10) run_btn = gr.Button("Exécuter", variant="primary") output_sandbox = gr.Textbox(label="Sortie", lines=10) run_btn.click(run_code_safe, inputs=code_input, outputs=output_sandbox) with gr.TabItem("📊 Santé système"): health_btn = gr.Button("Actualiser") health_display = gr.Markdown() health_btn.click(get_health_report, outputs=health_display) demo.load(get_health_report, outputs=health_display) with gr.TabItem("🧠 Mémoire"): with gr.Row(): mem_content = gr.Textbox(label="Contenu", lines=3, scale=3) mem_tier = gr.Dropdown(choices=["cache","short","medium","long","episodic","semantic","meta"], label="Niveau", value="semantic") mem_imp = gr.Slider(0.0, 1.0, value=0.5, label="Importance") mem_store_btn = gr.Button("Mémoriser") mem_store_out = gr.Textbox(label="Résultat") mem_store_btn.click(store_memory, inputs=[mem_content, mem_tier, mem_imp], outputs=mem_store_out) with gr.Row(): query_text = gr.Textbox(label="Recherche", lines=2, scale=3) query_tier = gr.Dropdown(choices=["cache","short","medium","long","episodic","semantic","meta"], label="Niveau", value="semantic") query_k = gr.Number(value=3, label="Top K", precision=0) query_btn = gr.Button("Interroger") query_out = gr.Textbox(label="Résultats", lines=8) query_btn.click(query_memory, inputs=[query_text, query_tier, query_k], outputs=query_out) with gr.TabItem("🔗 Graphe causal"): with gr.Row(): src = gr.Textbox(label="Nœud source", scale=2) tgt = gr.Textbox(label="Nœud cible (optionnel)", scale=2) rel = gr.Textbox(label="Relation", scale=2) weight = gr.Number(value=1.0, label="Poids", scale=1) add_edge_btn = gr.Button("Ajouter une arête") add_edge_out = gr.Textbox(label="Statut") add_edge_btn.click(add_causal_edge, inputs=[src, tgt, rel, weight], outputs=add_edge_out) with gr.Row(): query_src = gr.Textbox(label="Depuis", scale=2) query_tgt = gr.Textbox(label="Vers (optionnel)", scale=2) maxd = gr.Number(value=3, label="Profondeur max", precision=0, scale=1) query_path_btn = gr.Button("Trouver chemins") paths_out = gr.Textbox(label="Chemins causaux", lines=8) query_path_btn.click(query_causal, inputs=[query_src, query_tgt, maxd], outputs=paths_out) with gr.TabItem("🔄 Apprentissage par transfert"): with gr.Row(): prob = gr.Textbox(label="Problème", lines=3, scale=3) sol = gr.Textbox(label="Solution", lines=3, scale=3) add_exp_btn = gr.Button("Ajouter expérience") add_exp_out = gr.Textbox(label="Statut") add_exp_btn.click(add_experience, inputs=[prob, sol], outputs=add_exp_out) with gr.Row(): new_prob = gr.Textbox(label="Nouveau problème", lines=3, scale=4) analogy_btn = gr.Button("Trouver analogies") analogy_out = gr.Textbox(label="Solutions analogues", lines=8) analogy_btn.click(transfer_analogy, inputs=new_prob, outputs=analogy_out) with gr.TabItem("🔬 Boucle de recherche"): domain_input = gr.Textbox(label="Domaine de recherche", value="optimisation de code") research_btn = gr.Button("Exécuter un cycle", variant="primary") research_out = gr.Markdown() # Callback async research_btn.click(fn=sync_run_research, inputs=domain_input, outputs=research_out) with gr.TabItem("📜 Système de preuves"): proofs_btn = gr.Button("Afficher les preuves récentes") proofs_out = gr.Code(language="json") proofs_btn.click(show_proofs, outputs=proofs_out) with gr.TabItem("⚙️ Méta-méta optimiseur"): meta_status_btn = gr.Button("Obtenir le statut") meta_status_out = gr.Code() meta_status_btn.click(fn=meta_status, outputs=meta_status_out) rollback_btn = gr.Button("Restaurer l'optimiseur", variant="stop") rollback_out = gr.Textbox() rollback_btn.click(rollback_optimizer, outputs=rollback_out) with gr.TabItem("👔 Agents exécutifs"): question = gr.Textbox(label="Votre question", lines=2) exec_btn = gr.Button("Demander au CEO") exec_out = gr.Markdown() exec_btn.click(fn=executive_decision, inputs=question, outputs=exec_out) with gr.TabItem("🔐 Sécurité"): gr.Markdown("Vérification des variables d'environnement (hors bac à sable).") token_status = gr.Textbox(label="Statut HF_TOKEN") refresh_token_btn = gr.Button("Vérifier le token") refresh_token_btn.click(check_token_status, outputs=token_status) gr.Markdown(""" **Modules automatiquement disponibles dans le bac à sable (sans `import`) :** - `time`, `math`, `random`, `statistics`, `itertools`, `collections`, `string`, `re`, `datetime`, `fractions`, `decimal` **Les imports de modules non autorisés sont bloqués.** """) # Optionnel : on peut ajouter un onglet benchmark si désiré, mais on le laisse. gr.Markdown("---\n**Noyau VORTEX v3.0** – Noyau immuable avec signature cryptographique. Intégrité vérifiée au démarrage.") # ------------------------------------------------------------------- # Lancement avec recherche de port libre (optionnel) # ------------------------------------------------------------------- if __name__ == "__main__": if KERNEL.verify_integrity(): print("[✓] Signature du noyau valide") else: print("[!] Signature du noyau invalide – modification possible") print(f"[INFO] HF_TOKEN présent : {bool(os.getenv('HF_TOKEN'))}") # Configuration recommandée pour Hugging Face Spaces demo.launch( server_name="0.0.0.0", server_port=7860, theme=gr.themes.Soft(), share=False, debug=False, )