Natives Pendant zur Web-LlmSourceSettings/ByokKeyManager: - ManaLLMByokSection — Schlüssel pro Anbieter (OpenAI/Anthropic/Gemini/ Mistral) hinzufügen/ändern/löschen, Standard-Anbieter-Picker; Vault = ByokKeyVault (Keychain, app-privat). Secret nie zurück in die UI. - ManaLLMSettingsState verwaltet BYOK + reicht den Vault-Resolver in makeRouter(), damit .byok in der Availability-Map .available wird. - ManaLLMSettingsView(showByok:) + Picker includeByok — Apps mit On-Device-Versprechen (memoro) blenden BYOK komplett aus. - Erschöpfende LLMBackendID-Switches um .byok ergänzt (mana-swift-llm >=0.3.0 fügte den Case hinzu). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
59 lines
2.2 KiB
Swift
59 lines
2.2 KiB
Swift
import ManaLLM
|
||
import SwiftUI
|
||
|
||
/// Drop-in-Komposition aus den drei Sections: BackendPicker, Prepare
|
||
/// (sichtbar nur für Gemma-Backends), DownloadPolicy.
|
||
///
|
||
/// **Typische Nutzung:**
|
||
///
|
||
/// ```swift
|
||
/// // In der Settings-Form der App:
|
||
/// ManaLLMSettingsView(
|
||
/// context: ManaLLMContext(
|
||
/// useCaseShort: "Artikel-Zusammenfassung",
|
||
/// useCaseLong: "fasst Artikel in zwei Sätze zusammen"
|
||
/// )
|
||
/// )
|
||
/// ```
|
||
///
|
||
/// Apps die feinere Kontrolle wollen (z.B. zwischen den Sections eine
|
||
/// app-eigene Section einschieben), nutzen die granularen
|
||
/// `ManaLLM*Section`-Views direkt und teilen sich einen explizit
|
||
/// erzeugten `ManaLLMSettingsState`.
|
||
public struct ManaLLMSettingsView: View {
|
||
@State private var state = ManaLLMSettingsState()
|
||
private let context: ManaLLMContext
|
||
private let showByok: Bool
|
||
|
||
/// - Parameters:
|
||
/// - context: App-spezifische Use-Case-Texte für die Footer.
|
||
/// - showByok: Zeigt die BYOK-Schlüssel-Verwaltung
|
||
/// (`ManaLLMByokSection`). Default `true`. Apps, die bewusst
|
||
/// keinen Dritt-Anbieter anbieten wollen, setzen `false`.
|
||
public init(context: ManaLLMContext = .generic, showByok: Bool = true) {
|
||
self.context = context
|
||
self.showByok = showByok
|
||
}
|
||
|
||
public var body: some View {
|
||
// `.task` an die immer-präsente erste Section gehängt, NICHT an den
|
||
// `Group`: Group verteilt Modifier auf jeden Member, sodass das `.task`
|
||
// pro Section (3×) liefe und beim Ein-/Ausblenden der bedingten
|
||
// Prepare-Section erneut feuerte. Die Backend-Picker-Section hat
|
||
// stabile Identität → `refreshAvailability()` läuft einmal pro
|
||
// Erscheinen. Siehe ManaTwoFactorAccountRow für dieselbe Falle.
|
||
Group {
|
||
ManaLLMBackendPickerSection(state: state, context: context, includeByok: showByok)
|
||
.task {
|
||
await state.refreshAvailability()
|
||
}
|
||
if ManaLLMPrepareSection.shouldShow(for: state) {
|
||
ManaLLMPrepareSection(state: state)
|
||
}
|
||
if showByok {
|
||
ManaLLMByokSection(state: state)
|
||
}
|
||
ManaLLMDownloadPolicySection(state: state)
|
||
}
|
||
}
|
||
}
|