Created
January 17, 2025 20:38
-
-
Save kunal732/05b36a314c4eb0214ebb8fc9d58afa38 to your computer and use it in GitHub Desktop.
JinaAI ReaderLM in Swift app - https://huggingface.co/mlx-community/jinaai-ReaderLM-v2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import SwiftUI | |
import MLXModelManager | |
import MarkdownUI | |
struct ContentView: View { | |
@StateObject var JinaManager = ModelManager(modelPath: "mlx-community/jinaai-ReaderLM-v2") | |
// Instead of directly holding HTML, we now hold a URL string. | |
@State var urlString = "https://news.ycombinator.com/" | |
var body: some View { | |
VStack(alignment: .leading) { | |
// Top controls: progress indicators | |
HStack { | |
Spacer() | |
if JinaManager.isLoading { | |
VStack { | |
ProgressView( | |
value: Double(JinaManager.progressPercent), | |
total: 100 | |
) { | |
Text("Downloading Model...") | |
} | |
.frame(maxWidth: 200) | |
Text("\(JinaManager.progressPercent)%") | |
.font(.subheadline) | |
} | |
} | |
Spacer() | |
} | |
// Scrollable output (Markdown only) | |
ScrollView(.vertical) { | |
ScrollViewReader { scrollProxy in | |
Markdown(JinaManager.output) | |
.textSelection(.enabled) | |
.onChange(of: JinaManager.output) { _, _ in | |
scrollProxy.scrollTo("bottom", anchor: .bottom) | |
} | |
// "Bottom" spacer | |
Spacer() | |
.frame(width: 1, height: 1) | |
.id("bottom") | |
} | |
} | |
// URL input + "Answer Prompt" button | |
HStack { | |
TextField("Enter URL", text: $urlString) | |
.onSubmit { answerPrompt() } | |
.disabled(JinaManager.isGenerating || JinaManager.isLoading) | |
.textFieldStyle(.roundedBorder) | |
//.textInputAutocapitalization(.never) | |
.disableAutocorrection(true) | |
Button("Answer Prompt") { | |
answerPrompt() | |
} | |
.disabled(JinaManager.isGenerating || JinaManager.isLoading) | |
} | |
} | |
.padding() | |
.task { | |
do { | |
try await JinaManager.loadModel() | |
} catch { | |
print("Failed to load model: \(error)") | |
} | |
} | |
} | |
/// Trigger text generation using the current URL (download HTML, strip whitespace, then pass to the model) | |
private func answerPrompt() { | |
Task { | |
do { | |
try await JinaManager.loadModel() | |
// Convert urlString to URL | |
guard let url = URL(string: urlString) else { | |
print("Invalid URL string: \(urlString)") | |
return | |
} | |
// Download HTML | |
let (data, _) = try await URLSession.shared.data(from: url) | |
guard let html = String(data: data, encoding: .utf8) else { | |
print("Failed to decode HTML data.") | |
return | |
} | |
let prompt = "convert to markdown: \(html)" | |
// Run inference | |
await JinaManager.generate(prompt: prompt) | |
} catch { | |
print("Error during prompt generation: \(error)") | |
} | |
} | |
} | |
} | |
#Preview { | |
ContentView() | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment