Skip to content

Commit

Permalink
Refactoring a little bit.
Browse files Browse the repository at this point in the history
  • Loading branch information
niw committed Sep 17, 2024
1 parent 70901be commit 546a974
Show file tree
Hide file tree
Showing 10 changed files with 167 additions and 146 deletions.
2 changes: 1 addition & 1 deletion Applications/Translator/Resources/Localizable.xcstrings
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@
"Translate" : {

},
"Use as source" : {
"Use as input" : {

},
"Web Fiction" : {
Expand Down
2 changes: 1 addition & 1 deletion Applications/Translator/Sources/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,6 @@ extension AppDelegate: NSApplicationDelegate {
NSApplication.shared.servicesProvider = ServiceProvider(translatorService: translatorService)
NSUpdateDynamicServices()

translatorService.preloadModel()
translatorService.model.load()
}
}
16 changes: 8 additions & 8 deletions Applications/Translator/Sources/MainView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ struct MainView: View {

VStack(spacing: 0.0) {
HStack {
TextEditor(text: translatorServiceBindable.sourceString)
TextEditor(text: translatorServiceBindable.inputString)
TextEditor(text: .constant(translatorService.translatedString))
}
.font(.system(size: 16.0))
Expand All @@ -72,19 +72,19 @@ struct MainView: View {
HStack {
Button("Paste") {
if let string = NSPasteboard.general.string(forType: .string) {
translatorService.sourceString = string
translatorService.inputString = string
}
}

Button("Clear") {
translatorService.sourceString = ""
translatorService.inputString = ""
translatorService.translatedString = ""
}

Spacer()

Button("Use as source") {
translatorService.sourceString = translatorService.translatedString
Button("Use as input") {
translatorService.inputString = translatorService.translatedString
}
}

Expand All @@ -98,7 +98,7 @@ struct MainView: View {
}
.buttonStyle(.borderedProminent)
.controlSize(.large)
.disabled(translatorService.sourceString.isEmpty)
.disabled(translatorService.inputString.isEmpty)
}
.scenePadding()
}
Expand Down Expand Up @@ -139,9 +139,9 @@ struct MainView: View {
}
}
.onAppear {
translatorService.updateModel()
translatorService.model.update()

if case .unavailable = translatorService.modelState {
if case .unavailable = translatorService.model.state {
openSettings()
}
}
Expand Down
2 changes: 1 addition & 1 deletion Applications/Translator/Sources/ServiceProvider.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ final class ServiceProvider: NSObject {
guard let string = pasteboard.string(forType: .string) else {
return
}
translatorService.sourceString = string
translatorService.inputString = string
Task {
do {
try await translatorService.translate()
Expand Down
14 changes: 7 additions & 7 deletions Applications/Translator/Sources/SettingsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,14 @@ struct ModelSettingsView: View {
Text("Name:")
.gridColumnAlignment(.trailing)

Text(translatorService.modelSource.name)
Text(translatorService.model.source.name)
}

GridRow {
Text("Details:")
.gridColumnAlignment(.trailing)

Link(destination: translatorService.modelSource.wegpageURL) {
Link(destination: translatorService.model.source.wegpageURL) {
Text("Show details")
}
}
Expand All @@ -37,13 +37,13 @@ struct ModelSettingsView: View {
Text("File:")
.gridColumnAlignment(.trailing)

switch translatorService.modelState {
switch translatorService.model.state {
case .unavailable:
Button("Download") {
translatorService.downloadModel()
translatorService.model.download()
}

case .loading(let progress):
case .downloading(let progress):
if let progress {
VStack(alignment: .leading) {
ProgressView(progress)
Expand All @@ -70,7 +70,7 @@ struct ModelSettingsView: View {
})

Button(role: .destructive) {
translatorService.purgeModel()
translatorService.model.purge()
} label: {
Text("Delete")
}
Expand All @@ -80,7 +80,7 @@ struct ModelSettingsView: View {
}
.frame(width: 500.0)
.onAppear {
translatorService.updateModel()
translatorService.model.update()
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions Sources/LlamaModel/LlamaModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ public struct LlamaModel: Sendable {
}.value
}

public func complete(text: String) -> AsyncThrowingStream<String, any Swift.Error> {
public func complete(_ prompt: String) -> AsyncThrowingStream<String, any Swift.Error> {
AsyncThrowingStream { continuation in
let task = Task {
do {
try Task.checkCancellation()

try await context.completion_init(text: text)
try await context.completion_init(text: prompt)

try Task.checkCancellation()

Expand Down
27 changes: 11 additions & 16 deletions Sources/TranslatorSupport/CachedModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ private extension ModelSource {

@MainActor
@Observable
public final class CachedModel {
final class CachedModel {
private struct Download {
var task: Task<Void, any Swift.Error>
var progress: Progress
Expand All @@ -30,37 +30,33 @@ public final class CachedModel {

private var url: URL?

public enum State: Sendable, Equatable {
case loading(Progress?)
case available(URL)
enum State: Sendable, Equatable {
case unavailable
case downloading(Progress?)
case available(URL)
}

var state: State {
if let download {
.loading(download.progress)
.downloading(download.progress)
} else if let url {
.available(url)
} else {
.unavailable
}
}

private var modelsDirectory: URL {
get throws {
try FileManager.default.applicationSupportDirectory(named: "Models")
}
}
let modelsCacheURL: URL

let source: ModelSource

init(source: ModelSource) {
init(modelsCacheURL: URL, source: ModelSource) {
self.modelsCacheURL = modelsCacheURL
self.source = source
}

func update() throws {
let modelsDirectory = try modelsDirectory
let fileURL = modelsDirectory.appending(component: source.fileName)
let fileURL = modelsCacheURL.appending(component: source.fileName)
if FileManager.default.fileExists(at: fileURL) {
url = fileURL
} else {
Expand Down Expand Up @@ -90,9 +86,8 @@ public final class CachedModel {
let request = URLRequest(url: self.source.url)
let downloadTask = URLSession.shared.downloadTask(with: request)
let task = Task {
let modelsDirectory = try modelsDirectory
try FileManager.default.createDirectory(at: modelsDirectory, isExcludedFromBackup: true)
let fileURL = modelsDirectory.appending(component: source.fileName)
try FileManager.default.createDirectory(at: modelsCacheURL, isExcludedFromBackup: true)
let fileURL = modelsCacheURL.appending(component: source.fileName)
try await downloadTask.resumeDownloading(to: fileURL)
url = fileURL
}
Expand Down
94 changes: 94 additions & 0 deletions Sources/TranslatorSupport/Model.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
//
// Model.swift
// TranslatorSupport
//
// Created by Yoshimasa Niwa on 9/17/24.
//

import Foundation
import Observation
import LlamaModel

@MainActor
@Observable
public final class Model {
public enum State {
case unavailable
case downloading(Progress?)
case available(URL)
}

public var state: State {
switch cachedModel.state {
case .unavailable:
return .unavailable
case .downloading(let progress):
return .downloading(progress)
case .available(let url):
return .available(url)
}
}

let cachedModel: CachedModel

public var source: ModelSource {
cachedModel.source
}

init(cached cachedModel: CachedModel) {
self.cachedModel = cachedModel
}

public func update() {
do {
try cachedModel.update()
} catch {
}
}

private var loadingTask: Task<LlamaModel, any Swift.Error>?

var llamaModel: LlamaModel? {
get async throws {
try await loadingTask?.value
}
}

public func load() {
update()

guard case .available(let url) = cachedModel.state else {
return
}

loadingTask = Task {
try await LlamaModel(url: url)
}
}

public func download() {
update()

guard case .unavailable = cachedModel.state else {
return
}

Task {
do {
try await cachedModel.download()
load()
} catch {
}
}
}

public func purge() {
update()

do {
try cachedModel.purge()
loadingTask = nil
} catch {
}
}
}
Loading

0 comments on commit 546a974

Please sign in to comment.