mirror of
https://github.com/mii443/AzooKeyKanaKanjiConverter.git
synced 2025-12-03 02:58:27 +00:00
92 lines
3.5 KiB
Swift
92 lines
3.5 KiB
Swift
package import Foundation
|
|
import SwiftUtils
|
|
import EfficientNGram
|
|
|
|
private func debugLog(_ items: Any..., separator: String = " ", terminator: String = "\n") {
|
|
let message = items.map { "\($0)" }.joined(separator: separator) + terminator
|
|
let timestamp = ISO8601DateFormatter().string(from: Date())
|
|
let logEntry = "[\(timestamp)] \(message)"
|
|
|
|
print(logEntry, terminator: "")
|
|
debug(message)
|
|
|
|
let debugLogFile = FileManager.default.temporaryDirectory.appendingPathComponent("zenz_debug_\(ProcessInfo.processInfo.processIdentifier).log")
|
|
if let data = logEntry.data(using: .utf8) {
|
|
if !FileManager.default.fileExists(atPath: debugLogFile.path) {
|
|
FileManager.default.createFile(atPath: debugLogFile.path, contents: data)
|
|
} else {
|
|
if let fileHandle = try? FileHandle(forWritingTo: debugLogFile) {
|
|
fileHandle.seekToEndOfFile()
|
|
fileHandle.write(data)
|
|
fileHandle.closeFile()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
@MainActor package final class Zenz {
|
|
package var resourceURL: URL
|
|
package let ngl: Int
|
|
private var zenzContext: ZenzContext?
|
|
init(resourceURL: URL, ngl: Int = 0) throws {
|
|
self.resourceURL = resourceURL
|
|
self.ngl = ngl
|
|
debugLog("[Zenz] init called with resourceURL: \(resourceURL), ngl: \(ngl)")
|
|
do {
|
|
#if canImport(Darwin)
|
|
if #available(iOS 16, macOS 13, *) {
|
|
self.zenzContext = try ZenzContext.createContext(path: resourceURL.path(percentEncoded: false), ngl: ngl)
|
|
} else {
|
|
// this is not percent-encoded
|
|
self.zenzContext = try ZenzContext.createContext(path: resourceURL.path, ngl: ngl)
|
|
}
|
|
#else
|
|
// this is not percent-encoded
|
|
self.zenzContext = try ZenzContext.createContext(path: resourceURL.path, ngl: ngl)
|
|
#endif
|
|
debugLog("[Zenz] Loaded model \(resourceURL.lastPathComponent) successfully with ngl=\(ngl)")
|
|
} catch {
|
|
throw error
|
|
}
|
|
}
|
|
|
|
package func endSession() {
|
|
try? self.zenzContext?.reset_context()
|
|
}
|
|
|
|
func candidateEvaluate(
|
|
convertTarget: String,
|
|
candidates: [Candidate],
|
|
requestRichCandidates: Bool,
|
|
personalizationMode: (mode: ConvertRequestOptions.ZenzaiMode.PersonalizationMode, base: EfficientNGram, personal: EfficientNGram)?,
|
|
versionDependentConfig: ConvertRequestOptions.ZenzaiVersionDependentMode
|
|
) -> ZenzContext.CandidateEvaluationResult {
|
|
guard let zenzContext else {
|
|
return .error
|
|
}
|
|
for candidate in candidates {
|
|
let result = zenzContext.evaluate_candidate(
|
|
input: convertTarget.toKatakana(),
|
|
candidate: candidate,
|
|
requestRichCandidates: requestRichCandidates,
|
|
personalizationMode: personalizationMode,
|
|
versionDependentConfig: versionDependentConfig
|
|
)
|
|
return result
|
|
}
|
|
return .error
|
|
}
|
|
|
|
func predictNextCharacter(leftSideContext: String, count: Int) -> [(character: Character, value: Float)] {
|
|
guard let zenzContext else {
|
|
return []
|
|
}
|
|
let result = zenzContext.predict_next_character(leftSideContext: leftSideContext, count: count)
|
|
return result
|
|
}
|
|
|
|
package func pureGreedyDecoding(pureInput: String, maxCount: Int = .max) -> String {
|
|
return self.zenzContext?.pure_greedy_decoding(leftSideContext: pureInput, maxCount: maxCount) ?? ""
|
|
}
|
|
}
|