Skip to content

Commit

Permalink
Merge branch 'dev' into fix-subscriber
Browse files Browse the repository at this point in the history
  • Loading branch information
tisfeng committed Jul 10, 2024
2 parents 5e3cf7e + 5191a4a commit ad05802
Show file tree
Hide file tree
Showing 21 changed files with 277 additions and 51 deletions.
24 changes: 20 additions & 4 deletions Easydict.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,10 @@
03779F0F2BB256A7008D3C42 /* Prompt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03779F0C2BB256A7008D3C42 /* Prompt.swift */; };
03779F132BB256B5008D3C42 /* APIKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03779F102BB256B5008D3C42 /* APIKey.swift */; };
03779F142BB256B5008D3C42 /* EncryptedSecretKeys.plist in Resources */ = {isa = PBXBuildFile; fileRef = 03779F112BB256B5008D3C42 /* EncryptedSecretKeys.plist */; };
03779F172BB256C5008D3C42 /* URL+IsValid.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03779F152BB256C5008D3C42 /* URL+IsValid.swift */; };
03779F172BB256C5008D3C42 /* URL+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03779F152BB256C5008D3C42 /* URL+Extension.swift */; };
03779F1A2BB25797008D3C42 /* OpenAI in Frameworks */ = {isa = PBXBuildFile; productRef = 03779F192BB25797008D3C42 /* OpenAI */; };
037852B9295D49F900D0E2CF /* EZTableRowView.m in Sources */ = {isa = PBXBuildFile; fileRef = 037852B8295D49F900D0E2CF /* EZTableRowView.m */; };
03792EA22C3831040074A145 /* OllamaService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03792EA12C3831040074A145 /* OllamaService.swift */; };
038030952B4106800009230C /* CocoaLumberjack in Frameworks */ = {isa = PBXBuildFile; productRef = 038030942B4106800009230C /* CocoaLumberjack */; };
038030972B4106800009230C /* CocoaLumberjackSwift in Frameworks */ = {isa = PBXBuildFile; productRef = 038030962B4106800009230C /* CocoaLumberjackSwift */; };
03832F542B5F6BE200D0DC64 /* AdvancedTab.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03832F532B5F6BE200D0DC64 /* AdvancedTab.swift */; };
Expand Down Expand Up @@ -201,6 +202,7 @@
03CAB9552ADBF0FF00DA94A3 /* EZSystemUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = 03CAB9542ADBF0FF00DA94A3 /* EZSystemUtility.m */; };
03CF27FE2B3DA7D500E19B57 /* Realm in Frameworks */ = {isa = PBXBuildFile; productRef = 03CF27FD2B3DA7D500E19B57 /* Realm */; };
03CF28002B3DA7D500E19B57 /* RealmSwift in Frameworks */ = {isa = PBXBuildFile; productRef = 03CF27FF2B3DA7D500E19B57 /* RealmSwift */; };
03CF5E642C39B2310058F9DB /* OllamaModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03CF5E632C39B2310058F9DB /* OllamaModel.swift */; };
03CF88632B137F650030C199 /* Array+Convenience.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03CF88622B137F650030C199 /* Array+Convenience.swift */; };
03D0434E292886D200E7559E /* EZMiniQueryWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = 03D0434D292886D200E7559E /* EZMiniQueryWindow.m */; };
03D043522928935300E7559E /* EZMainQueryWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = 03D043512928935300E7559E /* EZMainQueryWindow.m */; };
Expand Down Expand Up @@ -449,9 +451,10 @@
03779F0C2BB256A7008D3C42 /* Prompt.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Prompt.swift; sourceTree = "<group>"; };
03779F102BB256B5008D3C42 /* APIKey.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = APIKey.swift; sourceTree = "<group>"; };
03779F112BB256B5008D3C42 /* EncryptedSecretKeys.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = EncryptedSecretKeys.plist; sourceTree = "<group>"; };
03779F152BB256C5008D3C42 /* URL+IsValid.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "URL+IsValid.swift"; sourceTree = "<group>"; };
03779F152BB256C5008D3C42 /* URL+Extension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "URL+Extension.swift"; sourceTree = "<group>"; };
037852B7295D49F900D0E2CF /* EZTableRowView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EZTableRowView.h; sourceTree = "<group>"; };
037852B8295D49F900D0E2CF /* EZTableRowView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EZTableRowView.m; sourceTree = "<group>"; };
03792EA12C3831040074A145 /* OllamaService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OllamaService.swift; sourceTree = "<group>"; };
03832F532B5F6BE200D0DC64 /* AdvancedTab.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdvancedTab.swift; sourceTree = "<group>"; };
0387FB792BFBA990000A7A82 /* LLMStreamService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LLMStreamService.swift; sourceTree = "<group>"; };
03882F8229D95044005B5A52 /* CTScreen.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CTScreen.h; sourceTree = "<group>"; };
Expand Down Expand Up @@ -668,6 +671,7 @@
03CAB9532ADBF0FF00DA94A3 /* EZSystemUtility.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EZSystemUtility.h; sourceTree = "<group>"; };
03CAB9542ADBF0FF00DA94A3 /* EZSystemUtility.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EZSystemUtility.m; sourceTree = "<group>"; };
03CC6C092B21B0DC0049ED29 /* Info-debug.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Info-debug.plist"; sourceTree = "<group>"; };
03CF5E632C39B2310058F9DB /* OllamaModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OllamaModel.swift; sourceTree = "<group>"; };
03CF88622B137F650030C199 /* Array+Convenience.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Array+Convenience.swift"; sourceTree = "<group>"; };
03D0434C292886D200E7559E /* EZMiniQueryWindow.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EZMiniQueryWindow.h; sourceTree = "<group>"; };
03D0434D292886D200E7559E /* EZMiniQueryWindow.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EZMiniQueryWindow.m; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1199,6 +1203,7 @@
036D627F2BCAB5C6002C95C7 /* BuiltInAI */,
0A9AFBA92B7F8D6A0064C9A8 /* CustomOpenAI */,
C415C0AB2B450C4500A9D231 /* Gemini */,
03792EA02C3830E60074A145 /* Ollama */,
C4DD01E72B12B3B00025EE8E /* Tencent */,
2746AEBF2AF95040005FE0A1 /* Caiyun */,
62E2BF462B4082BA00E42D38 /* Ali */,
Expand Down Expand Up @@ -1230,11 +1235,20 @@
03779F162BB256C5008D3C42 /* URL */ = {
isa = PBXGroup;
children = (
03779F152BB256C5008D3C42 /* URL+IsValid.swift */,
03779F152BB256C5008D3C42 /* URL+Extension.swift */,
);
path = URL;
sourceTree = "<group>";
};
03792EA02C3830E60074A145 /* Ollama */ = {
isa = PBXGroup;
children = (
03792EA12C3831040074A145 /* OllamaService.swift */,
03CF5E632C39B2310058F9DB /* OllamaModel.swift */,
);
path = Ollama;
sourceTree = "<group>";
};
03882F8129D95044005B5A52 /* CoolToast */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -2771,6 +2785,7 @@
03008B2B2940D3230062B821 /* EZDeepLTranslate.m in Sources */,
03991166292A8A4400E1B06D /* EZTitleBarMoveView.m in Sources */,
27FE98092B3DD536000AD654 /* SettingView.swift in Sources */,
03CF5E642C39B2310058F9DB /* OllamaModel.swift in Sources */,
035E37E72A0953120061DFAF /* EZToast.m in Sources */,
03542A492937B5CF00C34C33 /* EZGoogleTranslate.m in Sources */,
03D0435A2928C4C800E7559E /* EZWindowManager.m in Sources */,
Expand Down Expand Up @@ -2913,7 +2928,7 @@
03B0231729231FA6001C7E63 /* Snip.m in Sources */,
03BFFC6E295FE59C004E033E /* EZQueryResult+EZYoudaoDictModel.m in Sources */,
03779F0F2BB256A7008D3C42 /* Prompt.swift in Sources */,
03779F172BB256C5008D3C42 /* URL+IsValid.swift in Sources */,
03779F172BB256C5008D3C42 /* URL+Extension.swift in Sources */,
6ADED1552BAE8809004A15BE /* NSBundle+Localization.m in Sources */,
03B0232829231FA6001C7E63 /* NSTextView+Height.m in Sources */,
03B0232129231FA6001C7E63 /* NSPasteboard+MM.m in Sources */,
Expand Down Expand Up @@ -2983,6 +2998,7 @@
03542A5E2938F05B00C34C33 /* EZLanguageModel.m in Sources */,
EA9943E82B534D8900EE7B97 /* LanguageDetectOptimizeExtensions.swift in Sources */,
03F639952AA6CFBB009B9914 /* EZBingConfig.m in Sources */,
03792EA22C3831040074A145 /* OllamaService.swift in Sources */,
0AC8A83F2B689E68006DA5CC /* ServiceSecretConfigreValidatable.swift in Sources */,
03D2A3E329F4C6F50035CED4 /* EZNetworkManager.m in Sources */,
9643D9562B73B3CD000FBEA6 /* Shortcut+Menu.swift in Sources */,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "Ollama.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
18 changes: 17 additions & 1 deletion Easydict/App/Localizable.xcstrings
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Apple Translation"
"value" : "Apple Translate"
}
},
"zh-Hans" : {
Expand Down Expand Up @@ -1749,6 +1749,22 @@
}
}
},
"ollama_translate" : {
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ollama Translate"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ollama 翻译"
}
}
}
},
"open_in_apple_dictionary" : {
"localizations" : {
"en" : {
Expand Down
10 changes: 8 additions & 2 deletions Easydict/Swift/Feature/Configuration/DefaultsStoredKey.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,17 @@

import Foundation

func storedKey(_ key: StoredKey, serviceType: ServiceType) -> String {
func storedKey(_ key: StoredKey, serviceType: ServiceType, id: String? = nil) -> String {
// This key should be compatible with existing OpenAI config keys
// EZOpenAIServiceUsageStatusKey
// EZOpenAIDictionaryKey
"EZ" + serviceType.rawValue + key.rawValue.capitalizeFirstLetter() + "Key"
// EZOpenAIDictionary_ID_Key

var identifier = ""
if let id, !id.isEmpty {
identifier = "_\(id)_"
}
return "EZ" + serviceType.rawValue + key.rawValue.capitalizeFirstLetter() + identifier + "Key"
}

extension UserDefaults {
Expand Down
14 changes: 8 additions & 6 deletions Easydict/Swift/Feature/DefaultAPIKeys/APIKey.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,34 +9,36 @@
import Defaults
import Foundation

// MARK: - APIKey

extension BuiltInAIService {
var defaultAPIKey: String {
var builtInAIAPIKey: String {
APIKey.builtInAIAPIKey.stringValue
}

var defaultEndpoint: String {
var builtInAIEndpoint: String {
APIKey.builtInAIEndpoint.stringValue
}
}

extension CaiyunService {
var defaultToken: String {
var caiyunToken: String {
APIKey.caiyunToken.stringValue
}
}

extension TencentService {
var defaultSecretId: String {
var tencentSecretId: String {
APIKey.tencentSecretId.stringValue
}

var defaultSecretKey: String {
var tencentSecretKey: String {
APIKey.tencentSecretKey.stringValue
}
}

extension EZNiuTransTranslate {
@objc var defaultAPIKey: String {
@objc var niutransAPIKey: String {
APIKey.niutransAPIKey.stringValue
}
}
Expand Down
4 changes: 2 additions & 2 deletions Easydict/Swift/Service/BuiltInAI/BuiltInAIService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,11 @@ class BuiltInAIService: BaseOpenAIService {
}

override var apiKey: String {
defaultAPIKey
builtInAIAPIKey
}

override var endpoint: String {
defaultEndpoint
builtInAIEndpoint
}

override var observeKeys: [Defaults.Key<String>] {
Expand Down
4 changes: 2 additions & 2 deletions Easydict/Swift/Service/Caiyun/CaiyunService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public final class CaiyunService: QueryService {
}

public override func hasPrivateAPIKey() -> Bool {
token != defaultToken
token != caiyunToken
}

public override func autoConvertTraditionalChinese() -> Bool {
Expand Down Expand Up @@ -118,7 +118,7 @@ public final class CaiyunService: QueryService {
if !token.isEmpty {
return token
} else {
return defaultToken
return caiyunToken
}
}
}
Expand Down
46 changes: 46 additions & 0 deletions Easydict/Swift/Service/Ollama/OllamaModel.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
//
// OllamaModel.swift
// Easydict
//
// Created by tisfeng on 2024/7/7.
// Copyright © 2024 izual. All rights reserved.
//

import Foundation

// MARK: - OllamaModels

// Ollama docs https://github.com/ollama/ollama/blob/main/docs/api.md#list-local-models
struct OllamaModels: Codable {
let models: [OllamaModel]
}

// MARK: - OllamaModel

struct OllamaModel: Codable {
enum CodingKeys: String, CodingKey {
case name, model
case modifiedAt = "modified_at"
case size, digest, details
}

let name, model, modifiedAt: String
let size: Int
let digest: String
let details: OllamaModelDetails
}

// MARK: - OllamaModelDetails

struct OllamaModelDetails: Codable {
enum CodingKeys: String, CodingKey {
case parentModel = "parent_model"
case format, family, families
case parameterSize = "parameter_size"
case quantizationLevel = "quantization_level"
}

let parentModel, format, family: String
let families: [String]?
let parameterSize, quantizationLevel: String
}
84 changes: 84 additions & 0 deletions Easydict/Swift/Service/Ollama/OllamaService.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
//
// OllamaService.swift
// Easydict
//
// Created by tisfeng on 2024/7/5.
// Copyright © 2024 izual. All rights reserved.
//

import Alamofire
import Defaults
import Foundation

// MARK: - OllamaService

@objc(EZOllamaService)
class OllamaService: BaseOpenAIService {
// MARK: Lifecycle

override init() {
super.init()

Task {
let models = try await localModels()
self.ollamaModels = models.models.map(\.name)
logInfo("ollama models: \(ollamaModels)")
}
}

// MARK: Public

public override func name() -> String {
NSLocalizedString("ollama_translate", comment: "")
}

public override func serviceType() -> ServiceType {
.ollama
}

// MARK: Internal

override var defaultEndpoint: String {
"http://localhost:11434/v1/chat/completions"
}

override var defaultModels: [String] {
ollamaModels
}

override var observeKeys: [Defaults.Key<String>] {
[supportedModelsKey]
}

override var isSentenceEnabledByDefault: Bool {
false
}

override var isDictionaryEnabledByDefault: Bool {
false
}

override func configurationListItems() -> Any {
StreamConfigurationView(
service: self,
showAPIKeySection: false
)
}

// MARK: Private

private var ollamaModels = [""]

/// Get Ollama modles https://github.com/ollama/ollama/blob/main/docs/api.md#list-local-models
private func localModels() async throws -> OllamaModels {
// endpoint is http://localhost:11434/v1/chat/completions, we need url http://localhost:11434/api/tags
let endpointURL = URL(string: endpoint)
guard let endpointURL, let trueBaseURL = endpointURL.rootURL else {
throw EZError(type: .param, description: "`\(serviceType().rawValue)` endpoint is invalid")
}

let modelsURL = trueBaseURL.appendingPathComponent("api/tags")
let dataTask = AF.request(modelsURL).serializingDecodable(OllamaModels.self)
return try await dataTask.value
}
}
2 changes: 0 additions & 2 deletions Easydict/Swift/Service/OpenAI/BaseOpenAIService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ import OpenAI

// MARK: - BaseOpenAIService

// In order to solve the problems caused by inheriting the OpenAI service for custom OpenAI services, we had to add a new base class. FIX https://github.com/tisfeng/Easydict/pull/473#issuecomment-2022587699

@objcMembers
@objc(EZBaseOpenAIService)
public class BaseOpenAIService: LLMStreamService {
Expand Down
Loading

0 comments on commit ad05802

Please sign in to comment.