spb/zyquo-mlx Public MIT
The local MLX foundry for your Mac — run, fine-tune, quantize, and ship models. Nothing leaves your machine.
Swift 93.4%
Python 3.8%
Makefile 2.2%
Shell 0.5%
1//2// AppModel.swift3// Zyquo MLX4//5// Author: Simon-Pierre Boucher6// Mail: contact@spboucher.ai7//89import Foundation10import Observation11import SwiftUI1213/// Workbench sections (left navigator, charter §4.2).14enum WorkbenchSection: String, CaseIterable, Identifiable {15 case models16 case datasets17 case train18 case convert19 case playground20 case evaluate2122 var id: String { rawValue }2324 var title: String {25 switch self {26 case .models: "Models"27 case .datasets: "Datasets"28 case .train: "Train"29 case .convert: "Convert"30 case .playground: "Playground"31 case .evaluate: "Evaluate"32 }33 }3435 var icon: String {36 switch self {37 case .models: "shippingbox"38 case .datasets: "tablecells"39 case .train: "flame"40 case .convert: "arrow.triangle.2.circlepath"41 case .playground: "bubble.left.and.text.bubble.right"42 case .evaluate: "checkmark.seal"43 }44 }4546 /// ⌘-shortcuts (charter Phase 6: ⌘L Models, ⌘D Datasets, ⌘R Train,47 /// ⌘I Playground; Convert/Evaluate get the next free letters).48 var shortcut: KeyEquivalent {49 switch self {50 case .models: "l"51 case .datasets: "d"52 case .train: "r"53 case .convert: "u"54 case .playground: "i"55 case .evaluate: "e"56 }57 }58}5960extension Notification.Name {61 /// Posted by the Foundry menu commands to switch workbench sections.62 static let zyquoNavigate = Notification.Name("zyquo.navigate")63}6465/// Root observable state for the workbench: library contents, run history,66/// active jobs, and the live memory readout in the navigator footer.67@Observable68@MainActor69final class AppModel {7071 var selectedSection: WorkbenchSection = .models7273 var models: [LocalModel] = []74 var datasets: [Dataset] = []75 var runs: [TrainingRun] = []76 var jobs: [Job] = []7778 var activeJobCount: Int { jobs.filter { $0.state == .running }.count }7980 /// GPU active memory, refreshed by the footer.81 var memoryUsedBytes: Int64 = 082 var memoryTotalBytes: Int64 = MemoryAdvisor.physicalMemory8384 var lastError: String?8586 /// Refresh all library-backed lists from disk.87 func refresh() async {88 do {89 try PersistenceService.ensureDirectories()90 models = try await ModelStore.shared.scan()91 datasets = try await DatasetService.shared.scan()92 runs = try await RunStore.shared.scan()93 let snapshot = await InferenceEngine.shared.memorySnapshot()94 memoryUsedBytes = Int64(snapshot.active)95 } catch {96 lastError = error.localizedDescription97 }98 }99}100