diff --git a/aria-brain/agent.py b/aria-brain/agent.py index c72c5e7..662b3cd 100644 --- a/aria-brain/agent.py +++ b/aria-brain/agent.py @@ -1402,10 +1402,10 @@ def _extract_flow_markers(text: str) -> tuple: # ([^.!?]{0,15}) in beliebiger Reihenfolge; "befehls?kette" damit "Lieferkette" # o.ae. nicht faelschlich matcht. _CONV_NOUN = r"(?:konversation|gespr[aä]ch|befehls?kette)" -_CONV_END_VERB = r"(?:ende|beenden|beende|aus|stop|stopp|schluss)" +_CONV_END_VERB = r"(?:ende|beend\w*|aus|stop\w*|schluss)" _END_CONVERSATION_RE = re.compile( rf"\b{_CONV_NOUN}\b[^.!?]{{0,15}}\b{_CONV_END_VERB}\b" - rf"|\b(?:beende|schlie(?:ß|ss)e?)\b[^.!?]{{0,15}}\b{_CONV_NOUN}\b", + rf"|\b(?:beend\w*|schlie(?:ß|ss)\w*)\b[^.!?]{{0,15}}\b{_CONV_NOUN}\b", re.IGNORECASE, ) @@ -1929,6 +1929,15 @@ class Agent: logger.warning("Cold-Search fehlgeschlagen: %s", exc) cold = [] + # 3b. Titel-Index des kalten Gedaechtnisses — ARIA sieht WAS sie an + # Nachschlage-Wissen hat (Zugangsdaten, Infra, Projekte) und holt es via + # memory_search, statt Stefan danach zu fragen. Nur Titel = billig. + try: + memory_index = self.store.list_index_titles() + except Exception as exc: + logger.warning("Titel-Index laden fehlgeschlagen: %s", exc) + memory_index = [] + # 4. Aktive Skills holen + Tool-Liste bauen all_skills = skills_mod.list_skills(active_only=False) active_skills = [s for s in all_skills if s.get("active", True)] @@ -1951,7 +1960,8 @@ class Agent: oauth_port = os.environ.get("RVS_PORT_PUBLIC", os.environ.get("RVS_PORT", "443")).strip() oauth_tls = os.environ.get("RVS_TLS", "true").strip().lower() != "false" - system_prompt = build_system_prompt(hot, cold, skills=all_skills, + system_prompt = build_system_prompt(hot, cold, memory_index=memory_index, + skills=all_skills, triggers=all_triggers, condition_vars=condition_vars, condition_funcs=condition_funcs, diff --git a/aria-brain/prompts.py b/aria-brain/prompts.py index f54e1dc..7bdbf09 100644 --- a/aria-brain/prompts.py +++ b/aria-brain/prompts.py @@ -300,6 +300,36 @@ def build_cold_memory_section(matches: List[MemoryPoint]) -> str: return "\n".join(lines) +def build_memory_index_section(index_titles: List[MemoryPoint]) -> str: + """Titel-Index des kalten Gedaechtnisses: ARIA sieht WELCHES Nachschlage- + Wissen sie hat (nur Titel, kein Inhalt = billig), damit sie den Inhalt via + memory_search holt statt Stefan nach etwas zu fragen, das schon da ist. + Nach Kategorie gruppiert; Conversation-Logs + auto-destillierte Fakten sind + bereits ausgefiltert (siehe list_index_titles).""" + if not index_titles: + return "" + grouped: dict[str, List[MemoryPoint]] = {} + for p in index_titles: + key = (p.category or p.type or "sonstiges").strip() or "sonstiges" + grouped.setdefault(key, []).append(p) + + lines = [ + "## Was in deinem Gedaechtnis liegt (per memory_search abrufbar)", + "Diese Eintraege hast DU gespeichert — hier nur die Titel, nicht der " + "Inhalt. Wenn einer zur Aufgabe passt, hol den Inhalt mit `memory_search` " + "(Titel oder Stichwort). **Frag Stefan NICHT nach etwas, das hier steht** " + "(Zugangsdaten, Server/Hosts, Projekt-Stand, Konfig) — erst nachsehen.", + "", + ] + for cat in sorted(grouped.keys()): + items = grouped[cat] + lines.append(f"### {cat}") + for p in items: + lines.append(f"- {p.title}") + lines.append("") + return "\n".join(lines).strip() + + def build_skills_section(skills: List[dict]) -> str: """Listet alle Skills (aktiv + deaktiviert) damit ARIA weiss was es gibt und keine doppelt baut. Plus klare Schwelle wann ein Skill sich lohnt.""" @@ -490,6 +520,7 @@ def build_flux_section(flux_config: dict) -> str: def build_system_prompt( pinned: List[MemoryPoint], cold: List[MemoryPoint] | None = None, + memory_index: List[MemoryPoint] | None = None, skills: List[dict] | None = None, triggers: List[dict] | None = None, condition_vars: List[dict] | None = None, @@ -523,6 +554,9 @@ def build_system_prompt( callback_host=oauth_callback_host, callback_port=oauth_callback_port, callback_tls=oauth_callback_tls)) + if memory_index: + parts.append("") + parts.append(build_memory_index_section(memory_index)) if cold: parts.append("") parts.append(build_cold_memory_section(cold))