From 482b6c5aea3456d4671f798b1ee94b11dae8c9e2 Mon Sep 17 00:00:00 2001 From: Google AI Agent Date: Mon, 30 Mar 2026 22:28:57 +0000 Subject: [PATCH] feat: add Sovereign Intersymbolic Memory Layer --- agent/symbolic_memory.py | 74 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 agent/symbolic_memory.py diff --git a/agent/symbolic_memory.py b/agent/symbolic_memory.py new file mode 100644 index 000000000..ef3cf7e07 --- /dev/null +++ b/agent/symbolic_memory.py @@ -0,0 +1,74 @@ +"""Sovereign Intersymbolic Memory Layer. + +Bridges Neural (LLM) and Symbolic (Graph) reasoning by extracting +structured triples from unstructured text and performing graph lookups. +""" + +import logging +import json +from typing import List, Dict, Any +from agent.gemini_adapter import GeminiAdapter +from tools.graph_store import GraphStore + +logger = logging.getLogger(__name__) + +class SymbolicMemory: + def __init__(self): + self.adapter = GeminiAdapter() + self.store = GraphStore() + + def ingest_text(self, text: str): + """Extracts triples from text and adds them to the graph.""" + prompt = f""" +Extract all meaningful entities and their relationships from the following text. +Format the output as a JSON list of triples: [{{"s": "subject", "p": "predicate", "o": "object"}}] + +Text: +{text} + +Guidelines: +- Use clear, concise labels for entities and predicates. +- Focus on stable facts and structural relationships. +- Predicates should be verbs or descriptive relations (e.g., 'is_a', 'works_at', 'collaborates_with'). +""" + try: + result = self.adapter.generate( + model="gemini-3.1-pro-preview", + prompt=prompt, + system_instruction="You are Timmy's Symbolic Extraction Engine. Extract high-fidelity knowledge triples.", + response_mime_type="application/json" + ) + + triples = json.loads(result["text"]) + if isinstance(triples, list): + count = self.store.add_triples(triples) + logger.info(f"Ingested {count} new triples into symbolic memory.") + return count + except Exception as e: + logger.error(f"Symbolic ingestion failed: {e}") + return 0 + + def get_context_for(self, topic: str) -> str: + """Performs a 2-hop graph search to find related context for a topic.""" + # 1. Find direct relations + direct = self.store.query(subject=topic) + self.store.query(object=topic) + + # 2. Find 2nd hop + related_entities = set() + for t in direct: + related_entities.add(t['s']) + related_entities.add(t['o']) + + extended = [] + for entity in related_entities: + if entity == topic: continue + extended.extend(self.store.query(subject=entity)) + + all_triples = direct + extended + if not all_triples: + return "" + + context = "Symbolic Knowledge Graph Context:\n" + for t in all_triples: + context += f"- {t['s']} --({t['p']})--> {t['o']}\n" + return context