feat(brain): Titel-Index fürs kalte Gedächtnis + 'beendet' erkennen
Punkt 4B: jeder System-Prompt bekommt einen kompakten Titel-Index der bewusst gespeicherten Nachschlage-Memories (Zugangsdaten, Infra, Projekte) — ARIA sieht WAS sie hat und holt es via memory_search, statt Stefan nach etwas zu fragen, das schon da ist (Git-Credentials-Vorfall). Auto-distillierte Fakten + Conversation-Logs sind ausgefiltert → billig. Punkt 1: _CONV_END_VERB erkennt jetzt auch 'beendet' (beend\w*) und 'stoppe' (stop\w*) — 'Konversation beendet' schloss vorher das Mikro nicht. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+13
-3
@@ -1402,10 +1402,10 @@ def _extract_flow_markers(text: str) -> tuple:
|
|||||||
# ([^.!?]{0,15}) in beliebiger Reihenfolge; "befehls?kette" damit "Lieferkette"
|
# ([^.!?]{0,15}) in beliebiger Reihenfolge; "befehls?kette" damit "Lieferkette"
|
||||||
# o.ae. nicht faelschlich matcht.
|
# o.ae. nicht faelschlich matcht.
|
||||||
_CONV_NOUN = r"(?:konversation|gespr[aä]ch|befehls?kette)"
|
_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(
|
_END_CONVERSATION_RE = re.compile(
|
||||||
rf"\b{_CONV_NOUN}\b[^.!?]{{0,15}}\b{_CONV_END_VERB}\b"
|
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,
|
re.IGNORECASE,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -1929,6 +1929,15 @@ class Agent:
|
|||||||
logger.warning("Cold-Search fehlgeschlagen: %s", exc)
|
logger.warning("Cold-Search fehlgeschlagen: %s", exc)
|
||||||
cold = []
|
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
|
# 4. Aktive Skills holen + Tool-Liste bauen
|
||||||
all_skills = skills_mod.list_skills(active_only=False)
|
all_skills = skills_mod.list_skills(active_only=False)
|
||||||
active_skills = [s for s in all_skills if s.get("active", True)]
|
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_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"
|
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,
|
triggers=all_triggers,
|
||||||
condition_vars=condition_vars,
|
condition_vars=condition_vars,
|
||||||
condition_funcs=condition_funcs,
|
condition_funcs=condition_funcs,
|
||||||
|
|||||||
@@ -300,6 +300,36 @@ def build_cold_memory_section(matches: List[MemoryPoint]) -> str:
|
|||||||
return "\n".join(lines)
|
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:
|
def build_skills_section(skills: List[dict]) -> str:
|
||||||
"""Listet alle Skills (aktiv + deaktiviert) damit ARIA weiss was es gibt
|
"""Listet alle Skills (aktiv + deaktiviert) damit ARIA weiss was es gibt
|
||||||
und keine doppelt baut. Plus klare Schwelle wann ein Skill sich lohnt."""
|
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(
|
def build_system_prompt(
|
||||||
pinned: List[MemoryPoint],
|
pinned: List[MemoryPoint],
|
||||||
cold: List[MemoryPoint] | None = None,
|
cold: List[MemoryPoint] | None = None,
|
||||||
|
memory_index: List[MemoryPoint] | None = None,
|
||||||
skills: List[dict] | None = None,
|
skills: List[dict] | None = None,
|
||||||
triggers: List[dict] | None = None,
|
triggers: List[dict] | None = None,
|
||||||
condition_vars: List[dict] | None = None,
|
condition_vars: List[dict] | None = None,
|
||||||
@@ -523,6 +554,9 @@ def build_system_prompt(
|
|||||||
callback_host=oauth_callback_host,
|
callback_host=oauth_callback_host,
|
||||||
callback_port=oauth_callback_port,
|
callback_port=oauth_callback_port,
|
||||||
callback_tls=oauth_callback_tls))
|
callback_tls=oauth_callback_tls))
|
||||||
|
if memory_index:
|
||||||
|
parts.append("")
|
||||||
|
parts.append(build_memory_index_section(memory_index))
|
||||||
if cold:
|
if cold:
|
||||||
parts.append("")
|
parts.append("")
|
||||||
parts.append(build_cold_memory_section(cold))
|
parts.append(build_cold_memory_section(cold))
|
||||||
|
|||||||
Reference in New Issue
Block a user