spb/zyquo-local Public MIT
Native macOS AI chat that runs LLMs 100% locally on Apple Silicon with MLX — no cloud, no API keys.
Swift 97.2%
Shell 1.8%
Makefile 1%
1//2// AppSettings.swift3// Zyquo Local4//5// Author: Simon-Pierre Boucher6// Mail: contact@spboucher.ai7//89import Foundation10import Observation1112/// App-wide settings, persisted as JSON. Appearance lives in ThemeStore.13@MainActor14@Observable15final class AppSettings {16 /// Model loaded automatically on launch (repo ID), nil = none.17 var defaultModelID: String? {18 didSet { persist() }19 }2021 /// Keep the model loaded when the window closes / app is in background.22 var keepModelLoaded: Bool {23 didSet { persist() }24 }2526 /// Hugging Face token for gated models. Sent only to huggingface.co.27 var hfToken: String {28 didSet { persist() }29 }3031 /// Verify file sizes after download completes.32 var autoVerifyDownloads: Bool {33 didSet { persist() }34 }3536 /// Default generation parameters for new conversations.37 var defaultParams: GenerationParams {38 didSet { persist() }39 }4041 /// MLX GPU buffer-cache limit in MB (0 = MLX default).42 var gpuCacheLimitMB: Int {43 didSet { persist() }44 }4546 /// Hard cap applied on top of the model's context window (0 = model max).47 var contextLengthCap: Int {48 didSet { persist() }49 }5051 /// Global default system prompt for new conversations.52 var defaultSystemPrompt: String {53 didSet { persist() }54 }5556 var menuBarExtraEnabled: Bool {57 didSet { persist() }58 }5960 private struct Persisted: Codable {61 var defaultModelID: String?62 var keepModelLoaded: Bool63 var hfToken: String64 var autoVerifyDownloads: Bool65 var defaultParams: GenerationParams66 var gpuCacheLimitMB: Int67 var contextLengthCap: Int68 var defaultSystemPrompt: String69 var menuBarExtraEnabled: Bool70 }7172 init() {73 let stored = PersistenceService.loadDocument(Persisted.self, named: "settings")74 defaultModelID = stored?.defaultModelID75 keepModelLoaded = stored?.keepModelLoaded ?? true76 hfToken = stored?.hfToken ?? ""77 autoVerifyDownloads = stored?.autoVerifyDownloads ?? true78 defaultParams = stored?.defaultParams ?? GenerationParams()79 gpuCacheLimitMB = stored?.gpuCacheLimitMB ?? 080 contextLengthCap = stored?.contextLengthCap ?? 081 defaultSystemPrompt = stored?.defaultSystemPrompt ?? ""82 menuBarExtraEnabled = stored?.menuBarExtraEnabled ?? true83 }8485 private func persist() {86 PersistenceService.saveDocument(87 Persisted(88 defaultModelID: defaultModelID,89 keepModelLoaded: keepModelLoaded,90 hfToken: hfToken,91 autoVerifyDownloads: autoVerifyDownloads,92 defaultParams: defaultParams,93 gpuCacheLimitMB: gpuCacheLimitMB,94 contextLengthCap: contextLengthCap,95 defaultSystemPrompt: defaultSystemPrompt,96 menuBarExtraEnabled: menuBarExtraEnabled97 ),98 named: "settings"99 )100 }101}102