// // AppSettings.swift // Zyquo Local // // Author: Simon-Pierre Boucher // Mail: contact@spboucher.ai // import Foundation import Observation /// App-wide settings, persisted as JSON. Appearance lives in ThemeStore. @MainActor @Observable final class AppSettings { /// Model loaded automatically on launch (repo ID), nil = none. var defaultModelID: String? { didSet { persist() } } /// Keep the model loaded when the window closes / app is in background. var keepModelLoaded: Bool { didSet { persist() } } /// Hugging Face token for gated models. Sent only to huggingface.co. var hfToken: String { didSet { persist() } } /// Verify file sizes after download completes. var autoVerifyDownloads: Bool { didSet { persist() } } /// Default generation parameters for new conversations. var defaultParams: GenerationParams { didSet { persist() } } /// MLX GPU buffer-cache limit in MB (0 = MLX default). var gpuCacheLimitMB: Int { didSet { persist() } } /// Hard cap applied on top of the model's context window (0 = model max). var contextLengthCap: Int { didSet { persist() } } /// Global default system prompt for new conversations. var defaultSystemPrompt: String { didSet { persist() } } var menuBarExtraEnabled: Bool { didSet { persist() } } private struct Persisted: Codable { var defaultModelID: String? var keepModelLoaded: Bool var hfToken: String var autoVerifyDownloads: Bool var defaultParams: GenerationParams var gpuCacheLimitMB: Int var contextLengthCap: Int var defaultSystemPrompt: String var menuBarExtraEnabled: Bool } init() { let stored = PersistenceService.loadDocument(Persisted.self, named: "settings") defaultModelID = stored?.defaultModelID keepModelLoaded = stored?.keepModelLoaded ?? true hfToken = stored?.hfToken ?? "" autoVerifyDownloads = stored?.autoVerifyDownloads ?? true defaultParams = stored?.defaultParams ?? GenerationParams() gpuCacheLimitMB = stored?.gpuCacheLimitMB ?? 0 contextLengthCap = stored?.contextLengthCap ?? 0 defaultSystemPrompt = stored?.defaultSystemPrompt ?? "" menuBarExtraEnabled = stored?.menuBarExtraEnabled ?? true } private func persist() { PersistenceService.saveDocument( Persisted( defaultModelID: defaultModelID, keepModelLoaded: keepModelLoaded, hfToken: hfToken, autoVerifyDownloads: autoVerifyDownloads, defaultParams: defaultParams, gpuCacheLimitMB: gpuCacheLimitMB, contextLengthCap: contextLengthCap, defaultSystemPrompt: defaultSystemPrompt, menuBarExtraEnabled: menuBarExtraEnabled ), named: "settings" ) } }