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
+10 -2
View File
@@ -70,7 +70,8 @@ class CliTests(unittest.TestCase):
provider.last_route = SimpleNamespace(
privacy_policy=CloudPolicy.ASK,
provider="ollama",
fallback=True,
cloud_suppressed_by_local_mode=True,
technical_fallback=False,
)
service = ChatService(store, provider)
inputs = iter(
@@ -97,7 +98,14 @@ class CliTests(unittest.TestCase):
self.assertEqual(result, 0)
self.assertIn("Aktiver Providermodus: auto", output)
self.assertIn("Providermodus: local", output)
self.assertTrue(any("ask; Provider: ollama; Fallback: ja" in line for line in output))
self.assertTrue(
any(
"Datenschutzentscheidung: ask; Provider: ollama; "
"Cloud durch Modus local unterdrückt: ja; "
"Technischer Fallback: nein" in line
for line in output
)
)
self.assertIn("Gemini-Schlüssel vorhanden: ja", output)
def test_gemini_configuration_defaults_to_no(self) -> None:
+26 -3
View File
@@ -9,10 +9,33 @@ class PrivacyRouterTests(unittest.TestCase):
self.router = PrivacyRouter()
def test_general_technical_question_is_allowed(self) -> None:
self.assertEqual(
self.router.classify("Wie funktioniert SQLite in Python?").policy,
CloudPolicy.ALLOWED,
for question in (
"Erkläre in zwei Sätzen den Unterschied zwischen RAM und SSD.",
"Wie funktioniert eine SQLite-Transaktion?",
"Was bedeutet HTTP 404?",
"Wie funktioniert Git?",
):
with self.subTest(question=question):
self.assertEqual(
self.router.classify(question).policy,
CloudPolicy.ALLOWED,
)
def test_internal_server_question_requires_approval(self) -> None:
decision = self.router.classify(
"Wie konfiguriere ich den internen Server mit Hostname srv-intern-01?"
)
self.assertEqual(decision.policy, CloudPolicy.ASK)
def test_technical_question_with_api_key_is_never(self) -> None:
decision = self.router.classify("Wie nutze ich diesen API-Key in Python: AIza" + "x" * 25)
self.assertEqual(decision.policy, CloudPolicy.NEVER)
def test_personal_technical_situation_requires_approval(self) -> None:
decision = self.router.classify(
"Meine SSD ist voll. Wie verschiebe ich meine persönlichen Dateien?"
)
self.assertEqual(decision.policy, CloudPolicy.ASK)
def test_personal_information_requires_approval(self) -> None:
self.assertEqual(
+12
View File
@@ -253,6 +253,18 @@ class HybridProviderTests(unittest.TestCase):
self.assertEqual(answer, "Lokal")
self.assertFalse(self.approvals)
self.assertFalse(self.cloud.calls)
self.assertFalse(router.last_route.fallback)
self.assertTrue(router.last_route.cloud_suppressed_by_local_mode)
self.assertFalse(router.last_route.technical_fallback)
def test_network_failure_is_reported_as_technical_fallback(self) -> None:
self.cloud.error = CloudNetworkError("offline")
router = self._router()
router.chat([ChatMessage("user", "Wie funktioniert Python?")])
self.assertFalse(router.last_route.cloud_suppressed_by_local_mode)
self.assertTrue(router.last_route.technical_fallback)
if __name__ == "__main__":