Files
cesnimda 4ce2df0a2b
CI / backend (push) Successful in 52s
CI / frontend (push) Successful in 14s
Deploy Staging / deploy (push) Successful in 18s
CI / backend (pull_request) Successful in 52s
CI / frontend (pull_request) Successful in 15s
Security / secrets (push) Successful in 4s
Security / dependencies (push) Successful in 55s
Security / secrets (pull_request) Successful in 4s
Security / dependencies (pull_request) Successful in 54s
docs: discovery blueprint + multi-provider design (#8)
2026-07-01 19:59:53 +02:00

3.7 KiB

08 — AI Feature-Flag Integration (Part 8)

How the AI layer plugs into the flag system while staying completely separable from core email logic. Extends the blueprint AI strategy (../06); the gate math lives in 04.

Principle: AI is a guest, never a host

Core email (sync, search-lexical, cleanup, settings, admin) never references an AI type. It calls domain services; those optionally consult AI through a single gate + facade. Remove AI entirely and nothing in the core path breaks.

Core feature code
   │ (never touches Ollama/IAiProvider directly)
   ▼
IAiGate.IsAiFeatureEnabled("summaries", user)   ──► false ─► non-AI path / hide
   │ true
   ▼
IInboxAi facade (Application)  ──►  model router  ──►  IAiProvider / IEmbeddingProvider
                                                        (Null | Ollama | future)

Toggle behaviour (flag-driven)

  • Before any AI call, code asks IAiGate (which folds in ai.enabled + ai.<feature> + provider capability + user opt-in — the AND-chain from 04).
  • Admin ai.enabled = off ⇒ gate returns false everywhere ⇒ AI UI hidden, AI code paths skipped. Flip on ⇒ features reappear (hot-reloaded flag cache) with no redeploy.
  • Per-feature flags allow shipping AI features dark and enabling gradually (rollout).

Fallback when AI is disabled (per feature)

AI feature Fallback with AI off
Semantic / NL search Lexical + structured + fuzzy search (still excellent)
Thread summary Hidden; show first snippet + metadata
Reply suggestions Hidden; normal compose
Follow-up detection Heuristic-only (sent + question + no reply in N days)
Categorisation HeuristicClassifier rules only
Ask-your-inbox Feature hidden
Dedup Exact-hash only (no near-dup)
Every fallback is first-class, not a broken/greyed feature — this satisfies "AI must never
be required for core functionality."

Ollama integration layer (local models)

  • OllamaProvider (IAiProvider) + OllamaEmbeddingProvider (IEmbeddingProvider) talk to a local Ollama (own container, optional Compose ai profile).
  • Model router maps logical task → model via config (Ai:Models:{Chat,Embed,Vision}); swapping a model is a config change, not code.
  • VRAM guard (RTX 3080 / 10 GB): embeddings hot, 7B warm, vision on-demand (../06).
  • Health surfaced to admin (05): reachable? models loaded? VRAM? latency? If Ollama is down, capability = false ⇒ gate falls back gracefully (no user errors).

Safe abstraction (IAIProvider) — separation guarantees

  1. Interface boundary: only Infrastructure implements providers; Application depends on IInboxAi/IAiGate abstractions.
  2. Null objects: NullAiProvider/NullEmbeddingProvider return "unavailable" so the DI graph is always valid, AI on or off.
  3. Analyzer pipeline: AI enrichers (IEmailAnalyzer) declare required capabilities and are skipped when unavailable — adding/removing AI features never touches core sync/search.
  4. Bounded: every AI call has timeout + CancellationToken + Polly fallback to the Null path; AI can never hang or crash the core.
  5. Provider-swap: adding a future AI provider = one class + config + (optionally) a flag — no feature-code changes.

Precedence recap (single source of truth)

The effective availability chain and admin master-switch semantics are defined once in 04 — Settings & Feature Flags; this document is the architecture of how features consume that decision.