diff --git a/aria-brain/agent.py b/aria-brain/agent.py index 17d339d..85b78b5 100644 --- a/aria-brain/agent.py +++ b/aria-brain/agent.py @@ -1418,7 +1418,14 @@ class Agent: self._local_ran_skill = False local_only = bool(cfg.get("localOnly")) local_model = cfg.get("localLlmModel") or "qwen3-8b" # B0.5: llama-swap-Key - tools = self._build_local_tools() # B1b: kuratierte Tools + # B1a-Rueckbau (bewusst): local ist TOOL-LOS — nur reines Reden. Ein 8B + # ist ein unzuverlaessiger Tool-Caller: mit Werkzeug in der Hand erfindet + # er lieber eine plausible Antwort ('der Song ist X'), statt das Tool zu + # rufen — das war die Halo-Quelle UND zwang zu per-Skill-Guards. Ohne + # Tools KANN er kein Skill-Ergebnis faelschen. Alles mit Grundwahrheit + # (Fakt/Live-Zustand/Gedaechtnis/Aktion) gehoert an Claude (Router-Gate + # vorab) oder an den deterministischen Fast-Path — nicht an den 8B. + tools = [] sys_prompt = router_mod.build_local_system_prompt(IDENTITY_ANCHOR, has_tools=bool(tools)) diff --git a/aria-brain/router.py b/aria-brain/router.py index f626ffd..958074b 100644 --- a/aria-brain/router.py +++ b/aria-brain/router.py @@ -75,6 +75,26 @@ _TOOL_HINTS = re.compile( re.IGNORECASE, ) +# LIVE-/DYNAMISCH-Marker → Claude. Seit dem B1a-Rueckbau ist local TOOL-LOS +# (nur Reden), kann also nichts nachschlagen. Alles was aktuelle Grundwahrheit +# braucht — Wetter, News, Uhrzeit/Datum, Musik-/Spotify-Zustand, Preise/Kurse, +# Verkehr, Oeffnungszeiten — kann ein 8B nicht wissen und wuerde es erfinden. +# Darum vorab an Claude (der ruft das Tool). Das ist TOPIC-Ebene, nicht per-Skill: +# ein neuer Skill braucht hier keine Zeile — er faellt unter „braucht Grundwahrheit". +_LIVE_HINTS = re.compile( + r"\b(wetter|temperatur|regne\w*|schneit|grad draussen|" + r"news|nachrichten|schlagzeile\w*|" + r"uhrzeit|wie spaet|wie spät|welcher tag|welches datum|wochentag|" + r"spotify|musik|lied|song|playlist|lautstaerke|lautstärke|" + r"laeuft gerade|läuft gerade|spiele? (ab|weiter|die|den|das)|naechst\w*|nächst\w*|" + r"ueberspring\w*|überspring\w*|skip\w*|pausier\w*|" + r"timer|wecker|weck mich|erinner\w*|" + r"preis|kurs|aktie|wechselkurs|bitcoin|" + r"stau|verkehr|zugverbindung|bahn|abfahrt|" + r"oeffnungszeit\w*|öffnungszeit\w*|geoeffnet|geöffnet|hat .* auf)\b", + re.IGNORECASE, +) + # Technik-/Tiefe-Marker → Claude (lokales 8B soll das nicht raten). _HARD_HINTS = re.compile( r"```|" # Codeblock @@ -126,6 +146,8 @@ def should_try_local(user_message: str, cfg: dict) -> bool: return False if _TOOL_HINTS.search(msg): return False + if _LIVE_HINTS.search(msg): + return False if _HARD_HINTS.search(msg): return False return True @@ -138,10 +160,16 @@ def should_try_local(user_message: str, cfg: dict) -> bool: # kein volles Memory (B1a). # Was das lokale Tier NICHT selbst kann → dafuer eskaliert es an Claude. +# Seit dem B1a-Rueckbau hat local KEINE Werkzeuge mehr: es kann nichts +# nachschlagen und nichts steuern. Alles was aktuelle Grundwahrheit oder eine +# Aktion braucht, gehoert ans grosse Modell. _AWARENESS = ( - "Nur das grosse Modell (nicht du im Schnell-Modus) kann: Bilder generieren, " - "Skills bauen/aendern, Projekte & OAuth verwalten, ins Gedaechtnis SCHREIBEN, " - "sowie tiefe/technische Analysen und langen Code." + "Du hast im Schnell-Modus KEINE Werkzeuge — du kannst nichts nachschlagen und " + "nichts steuern. Nur das grosse Modell kann: aktuelle Infos holen (Wetter, " + "News, Uhrzeit, Preise), Musik/Spotify steuern oder den laufenden Song " + "nennen, Timer setzen, Bilder generieren, Skills bauen/aendern, Projekte & " + "OAuth verwalten, ins Gedaechtnis schreiben, sowie tiefe/technische Analysen " + "und langen Code. Fuer ALL das eskalierst du." )