Skip to content

Commit 3fc02a6

Browse files
minor things
1 parent 39c24dc commit 3fc02a6

14 files changed

Lines changed: 365 additions & 222 deletions

File tree

Playground/YapRun/YapRun.xcodeproj/project.pbxproj

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@
1111
54398FFC2F497A34009D6B51 /* WidgetKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 54398FFB2F497A34009D6B51 /* WidgetKit.framework */; };
1212
54398FFE2F497A34009D6B51 /* SwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 54398FFD2F497A34009D6B51 /* SwiftUI.framework */; };
1313
5439900B2F497A35009D6B51 /* YapRunActivityExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 54398FF92F497A34009D6B51 /* YapRunActivityExtension.appex */; platformFilter = ios; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
14-
54F2B9632F4BA43F00D2FB5A /* RunAnywhere in Frameworks */ = {isa = PBXBuildFile; productRef = 54F2B9622F4BA43F00D2FB5A /* RunAnywhere */; };
15-
54F2B9652F4BA43F00D2FB5A /* RunAnywhereONNX in Frameworks */ = {isa = PBXBuildFile; productRef = 54F2B9642F4BA43F00D2FB5A /* RunAnywhereONNX */; };
16-
54F2B9672F4BA43F00D2FB5A /* RunAnywhereWhisperKit in Frameworks */ = {isa = PBXBuildFile; productRef = 54F2B9662F4BA43F00D2FB5A /* RunAnywhereWhisperKit */; };
14+
54F2BC172F4BDEC500D2FB5A /* RunAnywhere in Frameworks */ = {isa = PBXBuildFile; productRef = 54F2BC162F4BDEC500D2FB5A /* RunAnywhere */; };
15+
54F2BC192F4BDEC500D2FB5A /* RunAnywhereONNX in Frameworks */ = {isa = PBXBuildFile; productRef = 54F2BC182F4BDEC500D2FB5A /* RunAnywhereONNX */; };
16+
54F2BC1B2F4BDEC500D2FB5A /* RunAnywhereWhisperKit in Frameworks */ = {isa = PBXBuildFile; productRef = 54F2BC1A2F4BDEC500D2FB5A /* RunAnywhereWhisperKit */; };
1717
/* End PBXBuildFile section */
1818

1919
/* Begin PBXContainerItemProxy section */
@@ -139,9 +139,9 @@
139139
isa = PBXFrameworksBuildPhase;
140140
buildActionMask = 2147483647;
141141
files = (
142-
54F2B9672F4BA43F00D2FB5A /* RunAnywhereWhisperKit in Frameworks */,
143-
54F2B9652F4BA43F00D2FB5A /* RunAnywhereONNX in Frameworks */,
144-
54F2B9632F4BA43F00D2FB5A /* RunAnywhere in Frameworks */,
142+
54F2BC1B2F4BDEC500D2FB5A /* RunAnywhereWhisperKit in Frameworks */,
143+
54F2BC192F4BDEC500D2FB5A /* RunAnywhereONNX in Frameworks */,
144+
54F2BC172F4BDEC500D2FB5A /* RunAnywhere in Frameworks */,
145145
);
146146
runOnlyForDeploymentPostprocessing = 0;
147147
};
@@ -236,9 +236,9 @@
236236
);
237237
name = YapRun;
238238
packageProductDependencies = (
239-
54F2B9622F4BA43F00D2FB5A /* RunAnywhere */,
240-
54F2B9642F4BA43F00D2FB5A /* RunAnywhereONNX */,
241-
54F2B9662F4BA43F00D2FB5A /* RunAnywhereWhisperKit */,
239+
54F2BC162F4BDEC500D2FB5A /* RunAnywhere */,
240+
54F2BC182F4BDEC500D2FB5A /* RunAnywhereONNX */,
241+
54F2BC1A2F4BDEC500D2FB5A /* RunAnywhereWhisperKit */,
242242
);
243243
productName = YapRun;
244244
productReference = 54398FBA2F4979D2009D6B51 /* YapRun.app */;
@@ -373,7 +373,7 @@
373373
mainGroup = 54398FB12F4979D2009D6B51;
374374
minimizedProjectReferenceProxies = 1;
375375
packageReferences = (
376-
54F2B9612F4BA43F00D2FB5A /* XCRemoteSwiftPackageReference "runanywhere-sdks" */,
376+
54F2BC152F4BDEC500D2FB5A /* XCRemoteSwiftPackageReference "runanywhere-sdks" */,
377377
);
378378
preferredProjectObjectVersion = 77;
379379
productRefGroup = 54398FBB2F4979D2009D6B51 /* Products */;
@@ -993,30 +993,30 @@
993993
/* End XCConfigurationList section */
994994

995995
/* Begin XCRemoteSwiftPackageReference section */
996-
54F2B9612F4BA43F00D2FB5A /* XCRemoteSwiftPackageReference "runanywhere-sdks" */ = {
996+
54F2BC152F4BDEC500D2FB5A /* XCRemoteSwiftPackageReference "runanywhere-sdks" */ = {
997997
isa = XCRemoteSwiftPackageReference;
998998
repositoryURL = "https://github.com/RunanywhereAI/runanywhere-sdks";
999999
requirement = {
10001000
kind = upToNextMajorVersion;
1001-
minimumVersion = 0.19.2;
1001+
minimumVersion = 0.19.3;
10021002
};
10031003
};
10041004
/* End XCRemoteSwiftPackageReference section */
10051005

10061006
/* Begin XCSwiftPackageProductDependency section */
1007-
54F2B9622F4BA43F00D2FB5A /* RunAnywhere */ = {
1007+
54F2BC162F4BDEC500D2FB5A /* RunAnywhere */ = {
10081008
isa = XCSwiftPackageProductDependency;
1009-
package = 54F2B9612F4BA43F00D2FB5A /* XCRemoteSwiftPackageReference "runanywhere-sdks" */;
1009+
package = 54F2BC152F4BDEC500D2FB5A /* XCRemoteSwiftPackageReference "runanywhere-sdks" */;
10101010
productName = RunAnywhere;
10111011
};
1012-
54F2B9642F4BA43F00D2FB5A /* RunAnywhereONNX */ = {
1012+
54F2BC182F4BDEC500D2FB5A /* RunAnywhereONNX */ = {
10131013
isa = XCSwiftPackageProductDependency;
1014-
package = 54F2B9612F4BA43F00D2FB5A /* XCRemoteSwiftPackageReference "runanywhere-sdks" */;
1014+
package = 54F2BC152F4BDEC500D2FB5A /* XCRemoteSwiftPackageReference "runanywhere-sdks" */;
10151015
productName = RunAnywhereONNX;
10161016
};
1017-
54F2B9662F4BA43F00D2FB5A /* RunAnywhereWhisperKit */ = {
1017+
54F2BC1A2F4BDEC500D2FB5A /* RunAnywhereWhisperKit */ = {
10181018
isa = XCSwiftPackageProductDependency;
1019-
package = 54F2B9612F4BA43F00D2FB5A /* XCRemoteSwiftPackageReference "runanywhere-sdks" */;
1019+
package = 54F2BC152F4BDEC500D2FB5A /* XCRemoteSwiftPackageReference "runanywhere-sdks" */;
10201020
productName = RunAnywhereWhisperKit;
10211021
};
10221022
/* End XCSwiftPackageProductDependency section */

Playground/YapRun/YapRun.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Playground/YapRun/YapRun/ContentView.swift

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -203,27 +203,14 @@ struct ContentView: View {
203203

204204
private var modelSection: some View {
205205
VStack(alignment: .leading, spacing: 12) {
206-
HStack {
207-
Text("Models")
206+
VStack(alignment: .leading, spacing: 4) {
207+
Text("Voice Model")
208208
.font(.headline)
209209
.foregroundStyle(AppColors.textPrimary)
210210

211-
Spacer()
212-
213-
Button {
214-
viewModel.showAddModelSheet = true
215-
} label: {
216-
HStack(spacing: 4) {
217-
Image(systemName: "plus")
218-
.font(.system(size: 12, weight: .bold))
219-
Text("Add URL")
220-
.font(.caption.weight(.semibold))
221-
}
222-
.foregroundStyle(AppColors.textSecondary)
223-
.padding(.horizontal, 10)
224-
.padding(.vertical, 6)
225-
.background(AppColors.overlayLight, in: Capsule())
226-
}
211+
Text("Your selection is auto-used when you tap Yap from the keyboard.")
212+
.font(.caption)
213+
.foregroundStyle(AppColors.textTertiary)
227214
}
228215

229216
if viewModel.models.isEmpty {
@@ -238,6 +225,7 @@ struct ContentView: View {
238225
model: model,
239226
isActive: model.id == viewModel.currentSTTModelId,
240227
downloadProgress: viewModel.downloadProgress[model.id],
228+
modelDescription: ModelRegistry.description(for: model.id),
241229
onDownload: { Task { await viewModel.downloadModel(model.id) } },
242230
onLoad: { Task { await viewModel.loadModel(model.id) } },
243231
onDelete: { Task { await viewModel.deleteModel(model.id) } }

Playground/YapRun/YapRun/Core/ModelRegistry.swift

Lines changed: 37 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ enum ModelRegistry {
1313
struct ASRModel {
1414
let id: String
1515
let name: String
16+
let description: String
1617
let url: URL
1718
let archiveType: ArchiveType
1819
let framework: InferenceFramework
@@ -22,65 +23,74 @@ enum ModelRegistry {
2223
/// Default model used during onboarding.
2324
static let defaultModelId = "whisperkit-tiny.en"
2425

25-
/// All available ASR models (tar.gz for fast native gzip extraction on iOS/macOS).
26+
/// Curated ASR models with consumer-friendly names (tar.gz for fast native gzip extraction on iOS/macOS).
2627
static let asrModels: [ASRModel] = [
2728
// ─── WhisperKit (Apple Neural Engine via Core ML) ───────────────
28-
// Optimized: runs on the Neural Engine, freeing CPU for other tasks.
29-
// Lower memory footprint and better battery efficiency.
3029
ASRModel(
3130
id: "whisperkit-tiny.en",
32-
name: "Whisper Tiny EN",
31+
name: "Fast",
32+
description: "Fastest transcription on Apple Neural Engine — low battery and memory. Best for quick notes.",
3333
url: URL(string: "https://github.com/RunanywhereAI/sherpa-onnx/releases/download/runanywhere-models-v2/whisperkit-tiny.en.tar.gz")!,
3434
archiveType: .tarGz,
35-
framework: .whisperKit,
35+
framework: .whisperKitCoreML,
3636
sizeBytes: 70_000_000
3737
),
3838
ASRModel(
3939
id: "whisperkit-base.en",
40-
name: "Whisper Base EN",
40+
name: "Accurate",
41+
description: "Higher accuracy on Neural Engine. Uses more memory. Best for longer dictation.",
4142
url: URL(string: "https://github.com/RunanywhereAI/sherpa-onnx/releases/download/runanywhere-models-v2/whisperkit-base.en.tar.gz")!,
4243
archiveType: .tarGz,
43-
framework: .whisperKit,
44+
framework: .whisperKitCoreML,
4445
sizeBytes: 134_000_000
4546
),
4647

4748
// ─── ONNX (CPU via sherpa-onnx) ────────────────────────────────
48-
// CPU-intensive: runs entirely on CPU cores.
49-
// Higher memory usage and battery consumption.
5049
ASRModel(
5150
id: "asr-moonshine-tiny-en-int8",
52-
name: "Moonshine Tiny EN (int8)",
51+
name: "Compact (CPU)",
52+
description: "Quantized int8 model on CPU. Good if Neural Engine is busy.",
5353
url: URL(string: "https://github.com/RunanywhereAI/sherpa-onnx/releases/download/runanywhere-models-v2/sherpa-onnx-moonshine-tiny-en-int8.tar.gz")!,
5454
archiveType: .tarGz,
5555
framework: .onnx,
5656
sizeBytes: 118_000_000
5757
),
58-
ASRModel(
59-
id: "asr-moonshine-base-en-int8",
60-
name: "Moonshine Base EN (int8)",
61-
url: URL(string: "https://github.com/RunanywhereAI/sherpa-onnx/releases/download/runanywhere-models-v2/sherpa-onnx-moonshine-base-en-int8.tar.gz")!,
62-
archiveType: .tarGz,
63-
framework: .onnx,
64-
sizeBytes: 273_000_000
65-
),
6658
ASRModel(
6759
id: "sherpa-onnx-whisper-tiny.en",
68-
name: "Whisper Tiny EN",
60+
name: "Whisper CPU",
61+
description: "Standard Whisper on CPU. Maximum device compatibility.",
6962
url: URL(string: "https://github.com/RunanywhereAI/sherpa-onnx/releases/download/runanywhere-models-v2/sherpa-onnx-whisper-tiny.en.tar.gz")!,
7063
archiveType: .tarGz,
7164
framework: .onnx,
7265
sizeBytes: 75_000_000
7366
),
74-
ASRModel(
75-
id: "asr-parakeet-tdt-ctc-110m-en-int8",
76-
name: "Parakeet TDT-CTC 110M EN (int8)",
77-
url: URL(string: "https://github.com/RunanywhereAI/sherpa-onnx/releases/download/runanywhere-models-v2/sherpa-onnx-nemo-parakeet_tdt_ctc_110m-en-36000-int8.tar.gz")!,
78-
archiveType: .tarGz,
79-
framework: .onnx,
80-
sizeBytes: 126_000_000
81-
),
67+
68+
// ─── Commented out: too heavy or niche for consumer use ────────
69+
// ASRModel(
70+
// id: "asr-moonshine-base-en-int8",
71+
// name: "Moonshine Base EN (int8)",
72+
// description: "Larger Moonshine model. 273 MB — heavy for most devices.",
73+
// url: URL(string: "https://github.com/RunanywhereAI/sherpa-onnx/releases/download/runanywhere-models-v2/sherpa-onnx-moonshine-base-en-int8.tar.gz")!,
74+
// archiveType: .tarGz,
75+
// framework: .onnx,
76+
// sizeBytes: 273_000_000
77+
// ),
78+
// ASRModel(
79+
// id: "asr-parakeet-tdt-ctc-110m-en-int8",
80+
// name: "Parakeet TDT-CTC 110M EN (int8)",
81+
// description: "Niche NVIDIA Parakeet model.",
82+
// url: URL(string: "https://github.com/RunanywhereAI/sherpa-onnx/releases/download/runanywhere-models-v2/sherpa-onnx-nemo-parakeet_tdt_ctc_110m-en-36000-int8.tar.gz")!,
83+
// archiveType: .tarGz,
84+
// framework: .onnx,
85+
// sizeBytes: 126_000_000
86+
// ),
8287
]
8388

89+
/// Look up the consumer-facing description for a model ID.
90+
static func description(for modelId: String) -> String? {
91+
asrModels.first { $0.id == modelId }?.description
92+
}
93+
8494
/// Register all ASR models with the RunAnywhere SDK.
8595
static func registerAll() {
8696
for model in asrModels {

Playground/YapRun/YapRun/Features/Home/HomeViewModel.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -239,15 +239,15 @@ extension ModelInfo {
239239

240240
var frameworkBadge: String {
241241
switch framework {
242-
case .whisperKit: return "Neural Engine"
242+
case .whisperKitCoreML: return "Neural Engine"
243243
case .onnx: return "ONNX CPU"
244244
default: return framework.rawValue
245245
}
246246
}
247247

248248
var engineNote: String {
249249
switch framework {
250-
case .whisperKit: return "Optimized - runs on Apple Neural Engine with low CPU and memory usage"
250+
case .whisperKitCoreML: return "Optimized - runs on Apple Neural Engine with low CPU and memory usage"
251251
case .onnx: return "High CPU usage - runs entirely on CPU with higher memory consumption"
252252
default: return ""
253253
}
@@ -259,7 +259,7 @@ extension ModelInfo {
259259
case .llamaCpp: return .purple
260260
case .foundationModels: return .blue
261261
case .coreml: return .cyan
262-
case .whisperKit: return .green
262+
case .whisperKitCoreML: return .green
263263
default: return .gray
264264
}
265265
}

Playground/YapRun/YapRun/Features/Home/ModelCardView.swift

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,15 @@ struct ModelCardView: View {
1313
let model: ModelInfo
1414
let isActive: Bool
1515
let downloadProgress: Double?
16+
let modelDescription: String?
1617
let onDownload: () -> Void
1718
let onLoad: () -> Void
1819
let onDelete: () -> Void
1920

2021
var body: some View {
2122
HStack(spacing: 12) {
2223
// Icon
23-
Image(systemName: model.framework == .whisperKit ? "brain" : "cpu")
24+
Image(systemName: model.framework == .whisperKitCoreML ? "brain" : "cpu")
2425
.font(.system(size: 18, weight: .medium))
2526
.foregroundStyle(model.frameworkColor)
2627
.frame(width: 40, height: 40)
@@ -52,11 +53,18 @@ struct ModelCardView: View {
5253
.font(.caption)
5354
.foregroundStyle(AppColors.textTertiary)
5455

55-
Text(model.framework == .whisperKit ? "Optimized" : "High CPU")
56+
Text(model.framework == .whisperKitCoreML ? "Optimized" : "High CPU")
5657
.font(.system(size: 9, weight: .semibold))
57-
.foregroundStyle(model.framework == .whisperKit ? .green : .orange)
58+
.foregroundStyle(model.framework == .whisperKitCoreML ? .green : .orange)
5859
}
5960
}
61+
62+
if let modelDescription {
63+
Text(modelDescription)
64+
.font(.caption2)
65+
.foregroundStyle(AppColors.textTertiary)
66+
.lineLimit(2)
67+
}
6068
}
6169

6270
Spacer()

Playground/YapRun/YapRun/Shared/SharedConstants.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ enum SharedConstants {
2525
static let dictationHistory = "dictationHistory"
2626
static let audioLevel = "audioLevel"
2727
static let lastInsertedText = "lastInsertedText"
28+
static let undoText = "undoText"
2829
static let lastHeartbeat = "lastHeartbeat"
2930
static let hasCompletedOnboarding = "hasCompletedOnboarding"
3031
}

Playground/YapRun/YapRun/Shared/SharedDataBridge.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,17 +141,32 @@ final class SharedDataBridge {
141141
}
142142
}
143143

144+
// MARK: - Undo Text (saved for redo after undo)
145+
146+
var undoText: String? {
147+
get { defaults?.string(forKey: SharedConstants.Keys.undoText) }
148+
set {
149+
if let value = newValue {
150+
defaults?.set(value, forKey: SharedConstants.Keys.undoText)
151+
} else {
152+
defaults?.removeObject(forKey: SharedConstants.Keys.undoText)
153+
}
154+
}
155+
}
156+
144157
// MARK: - Cleanup
145158

146159
func clearAfterInsertion() {
147160
defaults?.removeObject(forKey: SharedConstants.Keys.transcribedText)
148161
defaults?.removeObject(forKey: SharedConstants.Keys.lastInsertedText)
162+
defaults?.removeObject(forKey: SharedConstants.Keys.undoText)
149163
sessionState = "ready"
150164
}
151165

152166
func clearSession() {
153167
defaults?.removeObject(forKey: SharedConstants.Keys.transcribedText)
154168
defaults?.removeObject(forKey: SharedConstants.Keys.lastInsertedText)
169+
defaults?.removeObject(forKey: SharedConstants.Keys.undoText)
155170
defaults?.set(Float(0), forKey: SharedConstants.Keys.audioLevel)
156171
defaults?.set(Double(0), forKey: SharedConstants.Keys.lastHeartbeat)
157172
sessionState = "idle"

Playground/YapRun/YapRun/macOS/Features/MacHomeView.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@ struct MacHomeView: View {
196196
model: model,
197197
isActive: model.id == viewModel.currentSTTModelId,
198198
downloadProgress: viewModel.downloadProgress[model.id],
199+
modelDescription: ModelRegistry.description(for: model.id),
199200
onDownload: { Task { await viewModel.downloadModel(model.id) } },
200201
onLoad: { Task { await viewModel.loadModel(model.id) } },
201202
onDelete: { Task { await viewModel.deleteModel(model.id) } }

Playground/YapRun/YapRun/macOS/MacAppDelegate.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import AppKit
1010
import SwiftUI
1111
import RunAnywhere
1212
import ONNXRuntime
13+
import WhisperKitRuntime
1314
import os
1415

1516
@MainActor
@@ -63,11 +64,19 @@ final class MacAppDelegate: NSObject, NSApplicationDelegate {
6364
private func initializeSDK() async {
6465
do {
6566
ONNX.register(priority: 100)
67+
WhisperKitSTT.register(priority: 200)
68+
6669
try RunAnywhere.initialize()
6770
logger.info("SDK initialized")
6871

6972
ModelRegistry.registerAll()
7073
logger.info("ASR models registered")
74+
75+
await RunAnywhere.flushPendingRegistrations()
76+
let discovered = await RunAnywhere.discoverDownloadedModels()
77+
if discovered > 0 {
78+
logger.info("Discovered \(discovered) previously downloaded models")
79+
}
7180
} catch {
7281
logger.error("SDK initialization failed: \(error.localizedDescription)")
7382
}

0 commit comments

Comments
 (0)