mana-swift-llm/Sources/ManaLLM/LLMBackendPreferenceStore.swift
till 71ad295b73 mana statt »e.V.«: Schweizer Verein (kein Store-Release, nur Quelltext-Korrektur)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 20:32:29 +02:00

62 lines
2.4 KiB
Swift

import Foundation
/// Persistenter UserDefaults-Store für die User-Wahl des On-Device-LLM-
/// Backends. Geteilt von allen mana-Apps (Memoro, Pageta, Comicello,
/// Herbatrium, …) — Wert lebt pro App in `UserDefaults.standard`, weil
/// verschiedene Apps verschiedene Use-Case-Präferenzen haben können
/// (z.B. Moodlit favorisiert Gemma E2B wegen Creative-Mood-Mapping,
/// Pageta favorisiert AppleFM wegen Latenz beim Artikel-Summary).
///
/// **Default-Wert:** `.appleFM`. Auf Geräten ohne Apple Intelligence
/// fällt der Router zur Runtime über `availability()` auf den nächsten
/// selectable Backend zurück; der Default ist also "optimistisch" und
/// muss in der UI nicht selbst nachgepflegt werden.
///
/// **Legacy-Migration:** Apps die früher eigene Keys hatten werden
/// einmalig migriert:
/// - `memoro.llmBackend` (Memoros bisheriger Key) → `mana.llm.backend`
/// - `memoro.onDeviceLLMEnabled` (Memoros älterer Bool-Toggle) →
/// `.appleFM` (true) bzw. `.noOp` (false), dann auf
/// `mana.llm.backend`
///
/// Die Migration läuft auf jedem Read aus `current`. Erster Read
/// migriert + löscht den Legacy-Key; danach existiert nur noch der
/// neue Key.
public enum LLMBackendPreferenceStore {
private static let key = "mana.llm.backend"
private static let legacyMemoroKey = "memoro.llmBackend"
private static let legacyMemoroBoolKey = "memoro.onDeviceLLMEnabled"
/// Aktuelle Backend-Wahl. Läuft die Migration aus Legacy-Keys
/// einmalig durch (siehe Doc-Kommentar oben).
public static var current: LLMBackendID {
// 1. Neuer Key
if let raw = UserDefaults.standard.string(forKey: key),
let value = LLMBackendID(rawValue: raw)
{
return value
}
// 2. Memoro-Legacy-String-Key
if let raw = UserDefaults.standard.string(forKey: legacyMemoroKey),
let value = LLMBackendID(rawValue: raw)
{
set(value)
UserDefaults.standard.removeObject(forKey: legacyMemoroKey)
return value
}
// 3. Memoros älterer Bool-Toggle
if UserDefaults.standard.object(forKey: legacyMemoroBoolKey) != nil {
let wasEnabled = UserDefaults.standard.bool(forKey: legacyMemoroBoolKey)
let migrated: LLMBackendID = wasEnabled ? .appleFM : .noOp
set(migrated)
UserDefaults.standard.removeObject(forKey: legacyMemoroBoolKey)
return migrated
}
// 4. Default
return .appleFM
}
public static func set(_ value: LLMBackendID) {
UserDefaults.standard.set(value.rawValue, forKey: key)
}
}