File size: 2,834 Bytes
8726a6a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
import os
from dataclasses import dataclass, field
from typing import List, Dict, Optional
from google import genai
from google.genai import types

# ==========================================
# 1. ONTOLOGÍA DEL ENJAMBRE (Modelos de Datos)
# ==========================================
# Aquí definimos la "anatomía" exacta de un Experto. 
# Esto garantiza Fricción Cero: si un experto en tu JSON no tiene estas piezas, el sistema te avisa.

@dataclass
class ExpertoModel:
    role: str
    instructions: List[str]
    objective: str = "Reducir la entropía local y ejecutar la voluntad del Soberano."

    def ensamblar_prompt(self) -> str:
        """Fusiona la identidad del experto en una sola directiva de combate."""
        instrucciones_txt = " | ".join(self.instructions)
        return f"ROL ACTIVO: {self.role}\nOBJETIVO: {self.objective}\nDIRECTIVAS: {instrucciones_txt}"

# ==========================================
# 2. EL MOTOR COGNITIVO (Wrapper del LLM)
# ==========================================
# Encapsulamos la conexión con Google en una sola Clase Maestra.
# Así, tu main.py o tu agent_daemon.py no tienen que lidiar con configuraciones sucias.

class HectronMotor:
    def __init__(self, api_key: Optional[str] = None):
        """Inicializa el núcleo cuántico."""
        self.api_key = api_key or os.getenv("GEMINI_API_KEY")
        if not self.api_key:
            raise ValueError("❌ [ERROR CRÍTICO]: Fricción infinita. No se detectó GEMINI_API_KEY.")
        
        self.client = genai.Client(api_key=self.api_key)
        self.modelo_base = 'gemini-2.5-flash' # El cerebro actual

    def ejecutar_razonamiento(self, 
                              mision: str, 
                              experto: ExpertoModel, 
                              herramientas: list = None, 
                              temperatura: float = 0.3):
        """
        Inyecta la misión y la conciencia del experto en la red neuronal.
        """
        print(f"⚡ [NÚCLEO ENERGIZADO]: Conectando a {self.modelo_base} como {experto.role}...")
        
        # Preparamos la configuración de disparo
        config_disparo = types.GenerateContentConfig(
            system_instruction=experto.ensamblar_prompt(),
            temperature=temperatura
        )
        
        # Si el experto tiene herramientas (como terminal_execute), se las acoplamos
        if herramientas:
            config_disparo.tools = herramientas

        # Disparamos el modelo
        try:
            respuesta = self.client.models.generate_content(
                model=self.modelo_base,
                contents=mision,
                config=config_disparo
            )
            return respuesta
        except Exception as e:
            return f"❌ [FALLO DE CONEXIÓN EN EL NÚCLEO]: {str(e)}"