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// SpeechService.swift3// Zyquo MLX4//5// Author: Simon-Pierre Boucher6// Mail: contact@spboucher.ai7//89import Foundation1011/// Transcription result from a speech model.12struct TranscriptionResult: Sendable {13 var text: String14 var language: String?15 var segments: Int16 var duration: TimeInterval17}1819/// Speech-to-text via the Python bridge (mlx-whisper — Python-only per20/// docs/MLX-RESEARCH.md §2). Installs the pinned package on first use.21actor SpeechService {2223 static let shared = SpeechService()2425 /// Exact pin per docs/MLX-RESEARCH.md version snapshot.26 static let whisperPin = "mlx-whisper==0.4.3"2728 private var whisperInstalled = false2930 func transcribe(model: LocalModel, audio: URL) async throws -> TranscriptionResult {31 try await ensureWhisper()3233 let start = Date()34 let stream = try await PythonRunner.shared.stream(35 script: "zyquo_transcribe",36 arguments: ["--model", model.directory.path, "--audio", audio.path])3738 var text = ""39 var language: String?40 var segments = 041 for try await event in stream {42 switch event.event {43 case "done":44 text = event.string("text") ?? ""45 language = event.string("language")46 segments = event.int("segments") ?? 047 case "error":48 throw PythonRunnerError.processFailed(49 exitCode: 1, stderr: event.string("message") ?? "transcription failed")50 default:51 break52 }53 }54 return TranscriptionResult(55 text: text, language: language, segments: segments,56 duration: Date().timeIntervalSince(start))57 }5859 private func ensureWhisper() async throws {60 guard !whisperInstalled else { return }61 let env = PythonEnvironment.shared62 if await !env.isProvisioned {63 try await env.provision()64 }65 // Cheap idempotent install (uv resolves instantly when satisfied).66 try await env.install(pins: [Self.whisperPin])67 whisperInstalled = true68 }69}70