fix: refine privacy routing and provider reporting

This commit is contained in:
2026-07-30 18:34:01 +02:00
parent a6c46f34e4
commit 7a14fe87f9
10 changed files with 139 additions and 72 deletions
+30 -10
View File
@@ -26,6 +26,8 @@ class RouteStatus:
provider: str
privacy_policy: CloudPolicy
fallback: bool
cloud_suppressed_by_local_mode: bool
technical_fallback: bool
reason: str
@@ -94,7 +96,13 @@ class HybridProvider:
)
if self.mode == "local":
return self._local(messages, decision, "lokaler Modus", fallback=False)
return self._local(
messages,
decision,
"lokaler Modus",
fallback=False,
cloud_suppressed_by_local_mode=True,
)
if decision.policy is CloudPolicy.NEVER:
return self._local(messages, decision, decision.reason, fallback=True)
@@ -148,10 +156,12 @@ class HybridProvider:
)
)
self.last_route = RouteStatus(
cloud_provider.name,
decision.policy,
False,
"Cloudaufruf erfolgreich",
provider=cloud_provider.name,
privacy_policy=decision.policy,
fallback=False,
cloud_suppressed_by_local_mode=False,
technical_fallback=False,
reason="Cloudaufruf erfolgreich",
)
return response
@@ -192,7 +202,13 @@ class HybridProvider:
reason = "Gemini nicht verfügbar"
if disable_notice:
reason = "Gemini-Schlüssel abgelehnt; Cloud für diese Sitzung deaktiviert"
return self._local(messages, decision, reason, fallback=True)
return self._local(
messages,
decision,
reason,
fallback=True,
technical_fallback=True,
)
def _local(
self,
@@ -201,6 +217,8 @@ class HybridProvider:
reason: str,
*,
fallback: bool,
cloud_suppressed_by_local_mode: bool = False,
technical_fallback: bool = False,
) -> str:
if fallback:
self._notice_callback(f"{reason} lokale Antwort mit Ollama.")
@@ -216,10 +234,12 @@ class HybridProvider:
)
)
self.last_route = RouteStatus(
self.local_provider.name,
decision.policy,
fallback,
reason,
provider=self.local_provider.name,
privacy_policy=decision.policy,
fallback=fallback,
cloud_suppressed_by_local_mode=cloud_suppressed_by_local_mode,
technical_fallback=technical_fallback,
reason=reason,
)
return response
+4 -2
View File
@@ -227,9 +227,11 @@ def run_chat(
output("Noch keine Datenschutzentscheidung in dieser Sitzung.")
else:
output(
"Letzte Datenschutzentscheidung: "
"Datenschutzentscheidung: "
f"{route.privacy_policy.value}; Provider: {route.provider}; "
f"Fallback: {'ja' if route.fallback else 'nein'}"
"Cloud durch Modus local unterdrückt: "
f"{'ja' if route.cloud_suppressed_by_local_mode else 'nein'}; "
f"Technischer Fallback: {'ja' if route.technical_fallback else 'nein'}"
)
continue
if entered == "/status":
+5 -2
View File
@@ -75,7 +75,8 @@ _ASK_PATTERNS: tuple[tuple[re.Pattern[str], str], ...] = (
),
(
re.compile(
r"(?i)\b(intern(?:e[rsn]?|er)? hostname|interne? domain|rootserver|"
r"(?i)\b(intern(?:e|er|es|en)?\s+"
r"(?:hostname|server|domain|infrastruktur)|rootserver|"
r"privates? projekt|nicht öffentlich|systeminformation|"
r"private[rs]? termin)\b"
),
@@ -90,7 +91,9 @@ _ASK_PATTERNS: tuple[tuple[re.Pattern[str], str], ...] = (
_ALLOWED_PATTERNS: tuple[re.Pattern[str], ...] = (
re.compile(
r"(?i)\b(python|programmier|quellcode|algorithmus|sqlite|linux|windows|"
r"öffentliche dokumentation|allgemeine wissensfrage|was ist|wie funktioniert)\b"
r"git|ram|arbeitsspeicher|ssd|solid state drive|http|statuscode|"
r"transaktion|öffentliche dokumentation|allgemeine wissensfrage|"
r"was ist|wie funktioniert)\b"
),
)