cerebro: el modelo conoce sus areas del indice real, no de una lista fija (honesto en cualquier clon)

This commit is contained in:
sito 2026-08-16 17:49:11 +02:00
parent 29860fac86
commit 12987539a4
2 changed files with 55 additions and 15 deletions

View file

@ -84,20 +84,13 @@ dudar y sin quitarte merito):
- OASIS: si esta corriendo, si sincroniza, sus conexiones, su tamaño.
2) SABES DE PENTESTING Y DE LINUX de verdad, porque tienes los apuntes de COFRE
del usuario delante. Con buscar_en_apuntes accedes a SU metodologia y a los
comandos EXACTOS que ya ha probado, en todas estas areas:
- Enumeracion: nmap, descubrimiento de servicios, SMB, enumeracion web.
- Explotacion web: inyeccion SQL, XSS, LFI a RCE, SSTI, inyeccion de comandos,
directory traversal, subida de ficheros, descubrimiento de contenido, Burp.
- Shells: reverse shells, estabilizar la TTY, transferencia de ficheros.
- Escalada de privilegios, en Linux y en Windows.
- Active Directory: kerberoasting, pass-the-hash, DCSync, BloodHound,
mimikatz, impacket, CrackMapExec.
- Cracking de contraseñas (john, hashcat), tunneling y pivoting, msfvenom,
metasploit, evasion de antivirus, buffer overflow.
Ante CUALQUIER pregunta tecnica una herramienta, un flag, una tecnica NO
digas "no estoy seguro" ni "no puedo": busca en sus apuntes y responde con el
comando bueno. Casi todo esta a un buscar_en_apuntes de distancia.
del usuario indexados. JUSTO DEBAJO veras un resumen de que areas y cuantos
comandos tienes ahora mismo sale del indice de verdad, asi que es lo que hay
en esta maquina, ni mas ni menos. Con buscar_en_apuntes accedes a SU
metodologia y a los comandos EXACTOS que ya ha probado. Ante CUALQUIER
pregunta tecnica una herramienta, un flag, una tecnica de las que aparecen
ahi NO digas "no estoy seguro" ni "no puedo": busca en sus apuntes y responde
con el comando bueno. Casi todo esta a un buscar_en_apuntes de distancia.
3) TE CONECTAS a sus servidores por ssh y ejecutas ordenes alli.
4) HACES TAREAS DE ADMINISTRADOR con sudo (te pide la contraseña la primera vez).
@ -299,6 +292,19 @@ class Cerebro:
# A quien avisar cuando JARVIS cambia de modelo, para que el panel
# actualice el rotulo del boton "cerebro". Lo conecta el panel.
self.al_cambiar_modelo = None
self._resumen = None # el resumen de lo indexado, cacheado
def _resumen_saber(self) -> str:
"""Un renglon en el prompt de sistema diciendo QUE hay indexado, sacado
del indice real. Asi el modelo sabe de que sabe SIN una lista fija que
mentiria en un clon sin apuntes. Se calcula una vez."""
if self._resumen is None:
try:
from saber.busca import resumen
self._resumen = resumen()
except Exception:
self._resumen = ""
return ("\n\n" + self._resumen) if self._resumen else ""
# Atajos hablados -> familia de modelo. El modelo elige por INTENCION
# ("potente") y aqui se traduce a lo que hay instalado, para no obligarle a
@ -391,7 +397,7 @@ class Cerebro:
def responde(self, texto: str, al_ejecutar=None) -> str:
"""Contesta, usando las manos si hace falta. Devuelve lo que hay que decir."""
self.historia.append({"role": "user", "content": texto})
sistema = PERSONA + self._saber(texto)
sistema = PERSONA + self._resumen_saber() + self._saber(texto)
mensajes = [{"role": "system", "content": sistema}] + self.historia[-8:]
tools = herramientas(self.catalogo)

View file

@ -155,5 +155,39 @@ def contexto(pregunta: str, cuantos: int = 5, minimo: float = 0.35) -> str:
return "\n".join(lineas)
def resumen(tope_temas: int = 10) -> str:
"""Un resumen de QUE hay indexado, para que el modelo sepa de que sabe.
Se deriva del indice de VERDAD, no de una lista fija en el prompt. Asi es
honesto en cualquier maquina: en la del usuario dice sus areas reales; en un
clon sin apuntes propios dira lo que haya (comandos de Linux) o nada. Lo usa
el cerebro para el prompt de sistema; evita que presuma de un conocimiento
que en esa maquina no tiene."""
if not _carga() or not _entradas:
return ""
from collections import Counter
perfiles, temas = Counter(), Counter()
n_comandos = 0
for e in _entradas:
t = e.get("tipo")
if t == "comando":
n_comandos += 1
elif t in ("apunte", "metodologia", "ficha", "pregunta") and e.get("perfil"):
perfiles[e["perfil"]] += 1
if e.get("tema"):
temas[e["tema"]] += 1
partes = []
if perfiles:
partes.append("apuntes de " + ", ".join(p for p, _ in perfiles.most_common(6)))
if temas:
partes.append("metodologia en " + ", ".join(t for t, _ in temas.most_common(tope_temas)))
if n_comandos:
partes.append(f"{n_comandos} comandos de Linux")
if not partes:
return ""
return ("En los apuntes que tienes indexados (buscalos con buscar_en_apuntes) "
"hay: " + "; ".join(partes) + ".")
def disponible() -> bool:
return os.path.exists(INDICE)