From c2b92c78ca6e03bbced14d022c3ded80dfb8a241 Mon Sep 17 00:00:00 2001 From: Jerry Date: Thu, 11 Jul 2024 04:37:37 +0800 Subject: [PATCH 01/18] perf: add icons for polishing and grammar --- .../Grammar.imageset/Contents.json | 22 ++++++++++++++++++ .../service-icon/Grammar.imageset/Grammar.png | Bin 0 -> 4599 bytes .../Grammar.imageset/Grammar@2x.png | Bin 0 -> 11251 bytes .../Polishing.imageset/Contents.json | 22 ++++++++++++++++++ .../Polishing.imageset/Polishing.png | Bin 0 -> 4837 bytes .../Polishing.imageset/Polishing@2x.png | Bin 0 -> 12528 bytes 6 files changed, 44 insertions(+) create mode 100644 Easydict/App/Assets.xcassets/service-icon/Grammar.imageset/Contents.json create mode 100644 Easydict/App/Assets.xcassets/service-icon/Grammar.imageset/Grammar.png create mode 100644 Easydict/App/Assets.xcassets/service-icon/Grammar.imageset/Grammar@2x.png create mode 100644 Easydict/App/Assets.xcassets/service-icon/Polishing.imageset/Contents.json create mode 100644 Easydict/App/Assets.xcassets/service-icon/Polishing.imageset/Polishing.png create mode 100644 Easydict/App/Assets.xcassets/service-icon/Polishing.imageset/Polishing@2x.png diff --git a/Easydict/App/Assets.xcassets/service-icon/Grammar.imageset/Contents.json b/Easydict/App/Assets.xcassets/service-icon/Grammar.imageset/Contents.json new file mode 100644 index 000000000..3404b6480 --- /dev/null +++ b/Easydict/App/Assets.xcassets/service-icon/Grammar.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "filename" : "Grammar.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "Grammar@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Easydict/App/Assets.xcassets/service-icon/Grammar.imageset/Grammar.png b/Easydict/App/Assets.xcassets/service-icon/Grammar.imageset/Grammar.png new file mode 100644 index 0000000000000000000000000000000000000000..f88e31c501cb90c95cd3b787663b7f84221eb296 GIT binary patch literal 4599 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 N(bqQ7syOQy`yX}9XA1xT literal 0 HcmV?d00001 diff --git a/Easydict/App/Assets.xcassets/service-icon/Polishing.imageset/Polishing@2x.png b/Easydict/App/Assets.xcassets/service-icon/Polishing.imageset/Polishing@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..b8afd763d0a6c8e2499774c278670544f55551e5 GIT binary patch literal 12528 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 Date: Thu, 11 Jul 2024 05:31:36 +0800 Subject: [PATCH 02/18] fix: wrong icon placement --- .../service-icon/Grammar.imageset/Grammar.png | Bin 4599 -> 4837 bytes .../Grammar.imageset/Grammar@2x.png | Bin 11251 -> 12528 bytes .../Polishing.imageset/Polishing.png | Bin 4837 -> 4599 bytes .../Polishing.imageset/Polishing@2x.png | Bin 12528 -> 11251 bytes 4 files changed, 0 insertions(+), 0 deletions(-) diff --git a/Easydict/App/Assets.xcassets/service-icon/Grammar.imageset/Grammar.png b/Easydict/App/Assets.xcassets/service-icon/Grammar.imageset/Grammar.png index f88e31c501cb90c95cd3b787663b7f84221eb296..1870dd5a2948534f1f1e273d5a7f940e3adfecd9 100644 GIT binary patch delta 3844 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 a(*FadKqtxQr?Ef)0000 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 WjF}v?YAFl%Zz;=b$koYMhWsCzA7xnp delta 10243 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 WjF}v?YAFl%Zz;=b$koYMhWsCzA7xnp From b642f00815923b35a72ffeb39c786c01c79a71c0 Mon Sep 17 00:00:00 2001 From: Jerry Date: Thu, 11 Jul 2024 05:31:53 +0800 Subject: [PATCH 03/18] perf: setup base for grammar and polishing --- Easydict.xcodeproj/project.pbxproj | 24 +++++++++++++++ Easydict/App/Localizable.xcstrings | 32 ++++++++++++++++++++ Easydict/objc/Service/Model/EZEnumTypes.h | 2 ++ Easydict/objc/Service/Model/EZEnumTypes.m | 2 ++ Easydict/objc/Service/Model/EZServiceTypes.m | 2 ++ 5 files changed, 62 insertions(+) diff --git a/Easydict.xcodeproj/project.pbxproj b/Easydict.xcodeproj/project.pbxproj index faa39eef2..2b86b5e50 100644 --- a/Easydict.xcodeproj/project.pbxproj +++ b/Easydict.xcodeproj/project.pbxproj @@ -294,6 +294,8 @@ C477BF912C0E2C61006A3F27 /* InfoPlist.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = C477BF902C0E2C61006A3F27 /* InfoPlist.xcstrings */; }; C490BF722BE910B70021E40A /* AdvancedTabItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C490BF712BE910B70021E40A /* AdvancedTabItemView.swift */; }; C4BFDD7A2BE61F550094026B /* Vortex in Frameworks */ = {isa = PBXBuildFile; productRef = C4BFDD792BE61F550094026B /* Vortex */; }; + C4D1ADDE2C3F2B7A00A19D02 /* PolishingService.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D1ADDD2C3F2B7A00A19D02 /* PolishingService.swift */; }; + C4D1ADE32C3F341500A19D02 /* GrammarService.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D1ADE22C3F341500A19D02 /* GrammarService.swift */; }; C4DD01E92B12B3C80025EE8E /* TencentService.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4DD01E82B12B3C80025EE8E /* TencentService.swift */; }; C4DD01EB2B12BA250025EE8E /* TencentResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4DD01EA2B12BA250025EE8E /* TencentResponse.swift */; }; C4DD01ED2B12BE9B0025EE8E /* TencentTranslateType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4DD01EC2B12BE9B0025EE8E /* TencentTranslateType.swift */; }; @@ -792,6 +794,8 @@ C415C0AC2B450D4800A9D231 /* GeminiService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeminiService.swift; sourceTree = ""; }; C477BF902C0E2C61006A3F27 /* InfoPlist.xcstrings */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; path = InfoPlist.xcstrings; sourceTree = ""; }; C490BF712BE910B70021E40A /* AdvancedTabItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = AdvancedTabItemView.swift; path = Easydict/Swift/View/AdvancedTabItemView.swift; sourceTree = SOURCE_ROOT; }; + C4D1ADDD2C3F2B7A00A19D02 /* PolishingService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = PolishingService.swift; path = ../../../../../../../PolishingService.swift; sourceTree = ""; }; + C4D1ADE22C3F341500A19D02 /* GrammarService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = GrammarService.swift; path = ../../../../../../../GrammarService.swift; sourceTree = ""; }; C4DD01E82B12B3C80025EE8E /* TencentService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TencentService.swift; sourceTree = ""; }; C4DD01EA2B12BA250025EE8E /* TencentResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TencentResponse.swift; sourceTree = ""; }; C4DD01EC2B12BE9B0025EE8E /* TencentTranslateType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TencentTranslateType.swift; sourceTree = ""; }; @@ -1204,6 +1208,8 @@ 0A9AFBA92B7F8D6A0064C9A8 /* CustomOpenAI */, C415C0AB2B450C4500A9D231 /* Gemini */, 03792EA02C3830E60074A145 /* Ollama */, + C4D1ADDC2C3F2B6C00A19D02 /* Polishing */, + C4D1ADE12C3F340500A19D02 /* Grammar */, C4DD01E72B12B3B00025EE8E /* Tencent */, 2746AEBF2AF95040005FE0A1 /* Caiyun */, 62E2BF462B4082BA00E42D38 /* Ali */, @@ -2295,6 +2301,22 @@ name = "Recovered References"; sourceTree = ""; }; + C4D1ADDC2C3F2B6C00A19D02 /* Polishing */ = { + isa = PBXGroup; + children = ( + C4D1ADDD2C3F2B7A00A19D02 /* PolishingService.swift */, + ); + path = Polishing; + sourceTree = ""; + }; + C4D1ADE12C3F340500A19D02 /* Grammar */ = { + isa = PBXGroup; + children = ( + C4D1ADE22C3F341500A19D02 /* GrammarService.swift */, + ); + path = Grammar; + sourceTree = ""; + }; C4DD01E72B12B3B00025EE8E /* Tencent */ = { isa = PBXGroup; children = ( @@ -2777,6 +2799,7 @@ 962B9ACE2BFA03270080F4D4 /* EZAppModel.m in Sources */, 03BDA7C42A26DA280079D04F /* NSDictionary+RubyDescription.m in Sources */, 62ED29A22B15F1F500901F51 /* EZWrapView.m in Sources */, + C4D1ADE32C3F341500A19D02 /* GrammarService.swift in Sources */, C4DD01EB2B12BA250025EE8E /* TencentResponse.swift in Sources */, 036A0DB82AD8403A006E6D4F /* NSString+EZHandleInputText.m in Sources */, 03BDA7C12A26DA280079D04F /* XPMArgumentParser.m in Sources */, @@ -2897,6 +2920,7 @@ 03BB2DEF29F59C8A00447EDD /* EZSymbolImageButton.m in Sources */, 0A2BA9642B4A3CCD002872A4 /* Notification+Name.swift in Sources */, C415C0AD2B450D4800A9D231 /* GeminiService.swift in Sources */, + C4D1ADDE2C3F2B7A00A19D02 /* PolishingService.swift in Sources */, 9643D9402B6FC426000FBEA6 /* MainMenuShortcutCommand.swift in Sources */, 62A2D03F2A82967F007EEB01 /* EZBingRequest.m in Sources */, 03BDA7BE2A26DA280079D04F /* XPMCountedArgument.m in Sources */, diff --git a/Easydict/App/Localizable.xcstrings b/Easydict/App/Localizable.xcstrings index 1b8173da6..32abf9d1b 100644 --- a/Easydict/App/Localizable.xcstrings +++ b/Easydict/App/Localizable.xcstrings @@ -1176,6 +1176,22 @@ } } }, + "grammar_service" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Grammar Correction" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "语法纠错" + } + } + } + }, "Help" : { "localizations" : { "zh-Hans" : { @@ -1968,6 +1984,22 @@ } } }, + "polishing_service" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Polishing" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "润色" + } + } + } + }, "present_participle" : { "localizations" : { "en" : { diff --git a/Easydict/objc/Service/Model/EZEnumTypes.h b/Easydict/objc/Service/Model/EZEnumTypes.h index e7a48ea69..fa9868b17 100644 --- a/Easydict/objc/Service/Model/EZEnumTypes.h +++ b/Easydict/objc/Service/Model/EZEnumTypes.h @@ -47,6 +47,8 @@ FOUNDATION_EXPORT EZServiceType const EZServiceTypeTencent; FOUNDATION_EXPORT EZServiceType const EZServiceTypeAli; FOUNDATION_EXPORT EZServiceType const EZServiceTypeGemini; FOUNDATION_EXPORT EZServiceType const EZServiceTypeOllama; +FOUNDATION_EXPORT EZServiceType const EZServiceTypePolishing; +FOUNDATION_EXPORT EZServiceType const EZServiceTypeGrammar; FOUNDATION_EXPORT NSString *const EZQueryTextTypeKey; FOUNDATION_EXPORT NSString *const EZIntelligentQueryTextTypeKey; diff --git a/Easydict/objc/Service/Model/EZEnumTypes.m b/Easydict/objc/Service/Model/EZEnumTypes.m index 0bb9fb108..34615584a 100644 --- a/Easydict/objc/Service/Model/EZEnumTypes.m +++ b/Easydict/objc/Service/Model/EZEnumTypes.m @@ -26,6 +26,8 @@ NSString *const EZServiceTypeAli = @"Alibaba"; NSString *const EZServiceTypeGemini = @"Gemini"; NSString *const EZServiceTypeOllama = @"Ollama"; +NSString *const EZServiceTypePolishing = @"Polishing"; +NSString *const EZServiceTypeGrammar = @"Grammar"; NSString *const EZServiceTypeAppleDictionary = @"AppleDictionary"; diff --git a/Easydict/objc/Service/Model/EZServiceTypes.m b/Easydict/objc/Service/Model/EZServiceTypes.m index 5c83051aa..c40d5b60e 100644 --- a/Easydict/objc/Service/Model/EZServiceTypes.m +++ b/Easydict/objc/Service/Model/EZServiceTypes.m @@ -53,6 +53,8 @@ + (instancetype)allocWithZone:(struct _NSZone *)zone { EZServiceTypeBuiltInAI, [EZBuiltInAIService class], EZServiceTypeGemini, [EZGeminiService class], EZServiceTypeOllama, [EZOllamaService class], + EZServiceTypePolishing, [EZPolishingService class], + EZServiceTypeGrammar, [EZGrammarService class], EZServiceTypeCustomOpenAI, [EZCustomOpenAIService class], EZServiceTypeDeepL, [EZDeepLTranslate class], EZServiceTypeGoogle, [EZGoogleTranslate class], From cb76796e8329895f93842dd510d7dcf2e28034c0 Mon Sep 17 00:00:00 2001 From: Jerry Date: Fri, 12 Jul 2024 04:38:36 +0800 Subject: [PATCH 04/18] fix: missing files --- Easydict.xcodeproj/project.pbxproj | 24 ++++------- .../Service/Grammar/GrammarService.swift | 43 +++++++++++++++++++ .../Service/Grammar/PolishingService.swift | 43 +++++++++++++++++++ 3 files changed, 94 insertions(+), 16 deletions(-) create mode 100644 Easydict/Swift/Service/Grammar/GrammarService.swift create mode 100644 Easydict/Swift/Service/Grammar/PolishingService.swift diff --git a/Easydict.xcodeproj/project.pbxproj b/Easydict.xcodeproj/project.pbxproj index 2b86b5e50..f07e5119c 100644 --- a/Easydict.xcodeproj/project.pbxproj +++ b/Easydict.xcodeproj/project.pbxproj @@ -294,8 +294,8 @@ C477BF912C0E2C61006A3F27 /* InfoPlist.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = C477BF902C0E2C61006A3F27 /* InfoPlist.xcstrings */; }; C490BF722BE910B70021E40A /* AdvancedTabItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C490BF712BE910B70021E40A /* AdvancedTabItemView.swift */; }; C4BFDD7A2BE61F550094026B /* Vortex in Frameworks */ = {isa = PBXBuildFile; productRef = C4BFDD792BE61F550094026B /* Vortex */; }; - C4D1ADDE2C3F2B7A00A19D02 /* PolishingService.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D1ADDD2C3F2B7A00A19D02 /* PolishingService.swift */; }; - C4D1ADE32C3F341500A19D02 /* GrammarService.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D1ADE22C3F341500A19D02 /* GrammarService.swift */; }; + C4CCDAA32C407A0D00AC88BA /* GrammarService.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4CCDAA22C407A0D00AC88BA /* GrammarService.swift */; }; + C4CCDAA52C407A4100AC88BA /* PolishingService.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4CCDAA42C407A4100AC88BA /* PolishingService.swift */; }; C4DD01E92B12B3C80025EE8E /* TencentService.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4DD01E82B12B3C80025EE8E /* TencentService.swift */; }; C4DD01EB2B12BA250025EE8E /* TencentResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4DD01EA2B12BA250025EE8E /* TencentResponse.swift */; }; C4DD01ED2B12BE9B0025EE8E /* TencentTranslateType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4DD01EC2B12BE9B0025EE8E /* TencentTranslateType.swift */; }; @@ -794,8 +794,8 @@ C415C0AC2B450D4800A9D231 /* GeminiService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeminiService.swift; sourceTree = ""; }; C477BF902C0E2C61006A3F27 /* InfoPlist.xcstrings */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; path = InfoPlist.xcstrings; sourceTree = ""; }; C490BF712BE910B70021E40A /* AdvancedTabItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = AdvancedTabItemView.swift; path = Easydict/Swift/View/AdvancedTabItemView.swift; sourceTree = SOURCE_ROOT; }; - C4D1ADDD2C3F2B7A00A19D02 /* PolishingService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = PolishingService.swift; path = ../../../../../../../PolishingService.swift; sourceTree = ""; }; - C4D1ADE22C3F341500A19D02 /* GrammarService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = GrammarService.swift; path = ../../../../../../../GrammarService.swift; sourceTree = ""; }; + C4CCDAA22C407A0D00AC88BA /* GrammarService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GrammarService.swift; sourceTree = ""; }; + C4CCDAA42C407A4100AC88BA /* PolishingService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PolishingService.swift; sourceTree = ""; }; C4DD01E82B12B3C80025EE8E /* TencentService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TencentService.swift; sourceTree = ""; }; C4DD01EA2B12BA250025EE8E /* TencentResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TencentResponse.swift; sourceTree = ""; }; C4DD01EC2B12BE9B0025EE8E /* TencentTranslateType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TencentTranslateType.swift; sourceTree = ""; }; @@ -1208,7 +1208,6 @@ 0A9AFBA92B7F8D6A0064C9A8 /* CustomOpenAI */, C415C0AB2B450C4500A9D231 /* Gemini */, 03792EA02C3830E60074A145 /* Ollama */, - C4D1ADDC2C3F2B6C00A19D02 /* Polishing */, C4D1ADE12C3F340500A19D02 /* Grammar */, C4DD01E72B12B3B00025EE8E /* Tencent */, 2746AEBF2AF95040005FE0A1 /* Caiyun */, @@ -2301,18 +2300,11 @@ name = "Recovered References"; sourceTree = ""; }; - C4D1ADDC2C3F2B6C00A19D02 /* Polishing */ = { - isa = PBXGroup; - children = ( - C4D1ADDD2C3F2B7A00A19D02 /* PolishingService.swift */, - ); - path = Polishing; - sourceTree = ""; - }; C4D1ADE12C3F340500A19D02 /* Grammar */ = { isa = PBXGroup; children = ( - C4D1ADE22C3F341500A19D02 /* GrammarService.swift */, + C4CCDAA22C407A0D00AC88BA /* GrammarService.swift */, + C4CCDAA42C407A4100AC88BA /* PolishingService.swift */, ); path = Grammar; sourceTree = ""; @@ -2799,7 +2791,7 @@ 962B9ACE2BFA03270080F4D4 /* EZAppModel.m in Sources */, 03BDA7C42A26DA280079D04F /* NSDictionary+RubyDescription.m in Sources */, 62ED29A22B15F1F500901F51 /* EZWrapView.m in Sources */, - C4D1ADE32C3F341500A19D02 /* GrammarService.swift in Sources */, + C4CCDAA32C407A0D00AC88BA /* GrammarService.swift in Sources */, C4DD01EB2B12BA250025EE8E /* TencentResponse.swift in Sources */, 036A0DB82AD8403A006E6D4F /* NSString+EZHandleInputText.m in Sources */, 03BDA7C12A26DA280079D04F /* XPMArgumentParser.m in Sources */, @@ -2876,6 +2868,7 @@ 03E02A2629250D1D00A10260 /* EZEventMonitor.m in Sources */, 03B0233429231FA6001C7E63 /* MMConsoleLogFormatter.m in Sources */, 037852B9295D49F900D0E2CF /* EZTableRowView.m in Sources */, + C4CCDAA52C407A4100AC88BA /* PolishingService.swift in Sources */, 03779F0E2BB256A7008D3C42 /* OpenAIService.swift in Sources */, 033363A6293C4AFA00FED9C8 /* PrintBeautifulLog.m in Sources */, 039CC914292FB3180037B91E /* EZPopUpButton.m in Sources */, @@ -2920,7 +2913,6 @@ 03BB2DEF29F59C8A00447EDD /* EZSymbolImageButton.m in Sources */, 0A2BA9642B4A3CCD002872A4 /* Notification+Name.swift in Sources */, C415C0AD2B450D4800A9D231 /* GeminiService.swift in Sources */, - C4D1ADDE2C3F2B7A00A19D02 /* PolishingService.swift in Sources */, 9643D9402B6FC426000FBEA6 /* MainMenuShortcutCommand.swift in Sources */, 62A2D03F2A82967F007EEB01 /* EZBingRequest.m in Sources */, 03BDA7BE2A26DA280079D04F /* XPMCountedArgument.m in Sources */, diff --git a/Easydict/Swift/Service/Grammar/GrammarService.swift b/Easydict/Swift/Service/Grammar/GrammarService.swift new file mode 100644 index 000000000..20fc904ce --- /dev/null +++ b/Easydict/Swift/Service/Grammar/GrammarService.swift @@ -0,0 +1,43 @@ +// +// GrammarService.swift +// Easydict +// +// Created by Jerry on 2024-07-11. +// Copyright © 2024 izual. All rights reserved. +// + +import Foundation + +@objc(EZGrammarService) +class GrammarService: BuiltInAIService { + // MARK: Public + + public override func name() -> String { + NSLocalizedString("grammar_service", comment: "") + } + + public override func serviceType() -> ServiceType { + .grammar + } + + public override func configurationListItems() -> Any { + StreamConfigurationView( + service: self, + showNameSection: false, + showAPIKeySection: false, + showEndpointSection: false, + showSupportedModelsSection: false, + showUsedModelSection: false, + showTranslationToggle: false, + showSentenceToggle: false, + showDictionaryToggle: false, + showUsageStatusPicker: true + ) + } + + // MARK: Internal + + override var defaultModels: [String] { + ["llama3-70b-8192"] + } +} diff --git a/Easydict/Swift/Service/Grammar/PolishingService.swift b/Easydict/Swift/Service/Grammar/PolishingService.swift new file mode 100644 index 000000000..c2290ef78 --- /dev/null +++ b/Easydict/Swift/Service/Grammar/PolishingService.swift @@ -0,0 +1,43 @@ +// +// PolishingService.swift +// Easydict +// +// Created by Jerry on 2024-07-11. +// Copyright © 2024 izual. All rights reserved. +// + +import Foundation + +@objc(EZPolishingService) +class PolishingService: BuiltInAIService { + // MARK: Public + + public override func name() -> String { + NSLocalizedString("polishing_service", comment: "") + } + + public override func serviceType() -> ServiceType { + .polishing + } + + public override func configurationListItems() -> Any { + StreamConfigurationView( + service: self, + showNameSection: false, + showAPIKeySection: false, + showEndpointSection: false, + showSupportedModelsSection: false, + showUsedModelSection: false, + showTranslationToggle: false, + showSentenceToggle: false, + showDictionaryToggle: false, + showUsageStatusPicker: true + ) + } + + // MARK: Internal + + override var defaultModels: [String] { + ["llama3-70b-8192"] + } +} From 5c686a265207d693470abdf03abc950c6ab43def Mon Sep 17 00:00:00 2001 From: Jerry Date: Fri, 12 Jul 2024 05:08:23 +0800 Subject: [PATCH 05/18] fix: wrong service name for summary --- Easydict.xcodeproj/project.pbxproj | 14 +++++----- .../Contents.json | 0 .../Grammar.png | Bin .../Grammar@2x.png | Bin Easydict/App/Localizable.xcstrings | 26 +++++++----------- .../PolishingService.swift | 0 .../SummaryService.swift} | 11 ++++---- Easydict/objc/Service/Model/EZEnumTypes.h | 2 +- Easydict/objc/Service/Model/EZEnumTypes.m | 2 +- Easydict/objc/Service/Model/EZServiceTypes.m | 2 +- 10 files changed, 26 insertions(+), 31 deletions(-) rename Easydict/App/Assets.xcassets/service-icon/{Grammar.imageset => Summary.imageset}/Contents.json (100%) rename Easydict/App/Assets.xcassets/service-icon/{Grammar.imageset => Summary.imageset}/Grammar.png (100%) rename Easydict/App/Assets.xcassets/service-icon/{Grammar.imageset => Summary.imageset}/Grammar@2x.png (100%) rename Easydict/Swift/Service/{Grammar => LLMDerivs}/PolishingService.swift (100%) rename Easydict/Swift/Service/{Grammar/GrammarService.swift => LLMDerivs/SummaryService.swift} (82%) diff --git a/Easydict.xcodeproj/project.pbxproj b/Easydict.xcodeproj/project.pbxproj index f07e5119c..68e798963 100644 --- a/Easydict.xcodeproj/project.pbxproj +++ b/Easydict.xcodeproj/project.pbxproj @@ -294,7 +294,7 @@ C477BF912C0E2C61006A3F27 /* InfoPlist.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = C477BF902C0E2C61006A3F27 /* InfoPlist.xcstrings */; }; C490BF722BE910B70021E40A /* AdvancedTabItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C490BF712BE910B70021E40A /* AdvancedTabItemView.swift */; }; C4BFDD7A2BE61F550094026B /* Vortex in Frameworks */ = {isa = PBXBuildFile; productRef = C4BFDD792BE61F550094026B /* Vortex */; }; - C4CCDAA32C407A0D00AC88BA /* GrammarService.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4CCDAA22C407A0D00AC88BA /* GrammarService.swift */; }; + C4CCDAA32C407A0D00AC88BA /* SummaryService.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4CCDAA22C407A0D00AC88BA /* SummaryService.swift */; }; C4CCDAA52C407A4100AC88BA /* PolishingService.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4CCDAA42C407A4100AC88BA /* PolishingService.swift */; }; C4DD01E92B12B3C80025EE8E /* TencentService.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4DD01E82B12B3C80025EE8E /* TencentService.swift */; }; C4DD01EB2B12BA250025EE8E /* TencentResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4DD01EA2B12BA250025EE8E /* TencentResponse.swift */; }; @@ -794,7 +794,7 @@ C415C0AC2B450D4800A9D231 /* GeminiService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeminiService.swift; sourceTree = ""; }; C477BF902C0E2C61006A3F27 /* InfoPlist.xcstrings */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; path = InfoPlist.xcstrings; sourceTree = ""; }; C490BF712BE910B70021E40A /* AdvancedTabItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = AdvancedTabItemView.swift; path = Easydict/Swift/View/AdvancedTabItemView.swift; sourceTree = SOURCE_ROOT; }; - C4CCDAA22C407A0D00AC88BA /* GrammarService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GrammarService.swift; sourceTree = ""; }; + C4CCDAA22C407A0D00AC88BA /* SummaryService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SummaryService.swift; sourceTree = ""; }; C4CCDAA42C407A4100AC88BA /* PolishingService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PolishingService.swift; sourceTree = ""; }; C4DD01E82B12B3C80025EE8E /* TencentService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TencentService.swift; sourceTree = ""; }; C4DD01EA2B12BA250025EE8E /* TencentResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TencentResponse.swift; sourceTree = ""; }; @@ -1208,7 +1208,7 @@ 0A9AFBA92B7F8D6A0064C9A8 /* CustomOpenAI */, C415C0AB2B450C4500A9D231 /* Gemini */, 03792EA02C3830E60074A145 /* Ollama */, - C4D1ADE12C3F340500A19D02 /* Grammar */, + C4D1ADE12C3F340500A19D02 /* LLMDerivs */, C4DD01E72B12B3B00025EE8E /* Tencent */, 2746AEBF2AF95040005FE0A1 /* Caiyun */, 62E2BF462B4082BA00E42D38 /* Ali */, @@ -2300,13 +2300,13 @@ name = "Recovered References"; sourceTree = ""; }; - C4D1ADE12C3F340500A19D02 /* Grammar */ = { + C4D1ADE12C3F340500A19D02 /* LLMDerivs */ = { isa = PBXGroup; children = ( - C4CCDAA22C407A0D00AC88BA /* GrammarService.swift */, C4CCDAA42C407A4100AC88BA /* PolishingService.swift */, + C4CCDAA22C407A0D00AC88BA /* SummaryService.swift */, ); - path = Grammar; + path = LLMDerivs; sourceTree = ""; }; C4DD01E72B12B3B00025EE8E /* Tencent */ = { @@ -2791,7 +2791,7 @@ 962B9ACE2BFA03270080F4D4 /* EZAppModel.m in Sources */, 03BDA7C42A26DA280079D04F /* NSDictionary+RubyDescription.m in Sources */, 62ED29A22B15F1F500901F51 /* EZWrapView.m in Sources */, - C4CCDAA32C407A0D00AC88BA /* GrammarService.swift in Sources */, + C4CCDAA32C407A0D00AC88BA /* SummaryService.swift in Sources */, C4DD01EB2B12BA250025EE8E /* TencentResponse.swift in Sources */, 036A0DB82AD8403A006E6D4F /* NSString+EZHandleInputText.m in Sources */, 03BDA7C12A26DA280079D04F /* XPMArgumentParser.m in Sources */, diff --git a/Easydict/App/Assets.xcassets/service-icon/Grammar.imageset/Contents.json b/Easydict/App/Assets.xcassets/service-icon/Summary.imageset/Contents.json similarity index 100% rename from Easydict/App/Assets.xcassets/service-icon/Grammar.imageset/Contents.json rename to Easydict/App/Assets.xcassets/service-icon/Summary.imageset/Contents.json diff --git a/Easydict/App/Assets.xcassets/service-icon/Grammar.imageset/Grammar.png b/Easydict/App/Assets.xcassets/service-icon/Summary.imageset/Grammar.png similarity index 100% rename from Easydict/App/Assets.xcassets/service-icon/Grammar.imageset/Grammar.png rename to Easydict/App/Assets.xcassets/service-icon/Summary.imageset/Grammar.png diff --git a/Easydict/App/Assets.xcassets/service-icon/Grammar.imageset/Grammar@2x.png b/Easydict/App/Assets.xcassets/service-icon/Summary.imageset/Grammar@2x.png similarity index 100% rename from Easydict/App/Assets.xcassets/service-icon/Grammar.imageset/Grammar@2x.png rename to Easydict/App/Assets.xcassets/service-icon/Summary.imageset/Grammar@2x.png diff --git a/Easydict/App/Localizable.xcstrings b/Easydict/App/Localizable.xcstrings index 0f613bb9a..2551207a0 100644 --- a/Easydict/App/Localizable.xcstrings +++ b/Easydict/App/Localizable.xcstrings @@ -1210,22 +1210,6 @@ } } }, - "grammar_service" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Grammar Correction" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "语法纠错" - } - } - } - }, "Help" : { "localizations" : { "zh-Hans" : { @@ -3866,6 +3850,16 @@ } } }, + "summary_service" : { + "localizations" : { + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "总结" + } + } + } + }, "superlative" : { "localizations" : { "en" : { diff --git a/Easydict/Swift/Service/Grammar/PolishingService.swift b/Easydict/Swift/Service/LLMDerivs/PolishingService.swift similarity index 100% rename from Easydict/Swift/Service/Grammar/PolishingService.swift rename to Easydict/Swift/Service/LLMDerivs/PolishingService.swift diff --git a/Easydict/Swift/Service/Grammar/GrammarService.swift b/Easydict/Swift/Service/LLMDerivs/SummaryService.swift similarity index 82% rename from Easydict/Swift/Service/Grammar/GrammarService.swift rename to Easydict/Swift/Service/LLMDerivs/SummaryService.swift index 20fc904ce..b5da3ffeb 100644 --- a/Easydict/Swift/Service/Grammar/GrammarService.swift +++ b/Easydict/Swift/Service/LLMDerivs/SummaryService.swift @@ -1,5 +1,5 @@ // -// GrammarService.swift +// SummaryService.swift // Easydict // // Created by Jerry on 2024-07-11. @@ -7,17 +7,18 @@ // import Foundation +import OpenAI -@objc(EZGrammarService) -class GrammarService: BuiltInAIService { +@objc(EZSummaryService) +class SummaryService: BuiltInAIService { // MARK: Public public override func name() -> String { - NSLocalizedString("grammar_service", comment: "") + NSLocalizedString("summary_service", comment: "") } public override func serviceType() -> ServiceType { - .grammar + .summary } public override func configurationListItems() -> Any { diff --git a/Easydict/objc/Service/Model/EZEnumTypes.h b/Easydict/objc/Service/Model/EZEnumTypes.h index fa9868b17..56842948b 100644 --- a/Easydict/objc/Service/Model/EZEnumTypes.h +++ b/Easydict/objc/Service/Model/EZEnumTypes.h @@ -48,7 +48,7 @@ FOUNDATION_EXPORT EZServiceType const EZServiceTypeAli; FOUNDATION_EXPORT EZServiceType const EZServiceTypeGemini; FOUNDATION_EXPORT EZServiceType const EZServiceTypeOllama; FOUNDATION_EXPORT EZServiceType const EZServiceTypePolishing; -FOUNDATION_EXPORT EZServiceType const EZServiceTypeGrammar; +FOUNDATION_EXPORT EZServiceType const EZServiceTypeSummary; FOUNDATION_EXPORT NSString *const EZQueryTextTypeKey; FOUNDATION_EXPORT NSString *const EZIntelligentQueryTextTypeKey; diff --git a/Easydict/objc/Service/Model/EZEnumTypes.m b/Easydict/objc/Service/Model/EZEnumTypes.m index 34615584a..c23081b55 100644 --- a/Easydict/objc/Service/Model/EZEnumTypes.m +++ b/Easydict/objc/Service/Model/EZEnumTypes.m @@ -27,7 +27,7 @@ NSString *const EZServiceTypeGemini = @"Gemini"; NSString *const EZServiceTypeOllama = @"Ollama"; NSString *const EZServiceTypePolishing = @"Polishing"; -NSString *const EZServiceTypeGrammar = @"Grammar"; +NSString *const EZServiceTypeSummary = @"Summary"; NSString *const EZServiceTypeAppleDictionary = @"AppleDictionary"; diff --git a/Easydict/objc/Service/Model/EZServiceTypes.m b/Easydict/objc/Service/Model/EZServiceTypes.m index c40d5b60e..72c4c0150 100644 --- a/Easydict/objc/Service/Model/EZServiceTypes.m +++ b/Easydict/objc/Service/Model/EZServiceTypes.m @@ -54,7 +54,7 @@ + (instancetype)allocWithZone:(struct _NSZone *)zone { EZServiceTypeGemini, [EZGeminiService class], EZServiceTypeOllama, [EZOllamaService class], EZServiceTypePolishing, [EZPolishingService class], - EZServiceTypeGrammar, [EZGrammarService class], + EZServiceTypeSummary, [EZSummaryService class], EZServiceTypeCustomOpenAI, [EZCustomOpenAIService class], EZServiceTypeDeepL, [EZDeepLTranslate class], EZServiceTypeGoogle, [EZGoogleTranslate class], From 5572131feea56cbd8cc339e2ad8e2115040f4dfc Mon Sep 17 00:00:00 2001 From: Jerry Date: Fri, 12 Jul 2024 19:33:07 +0800 Subject: [PATCH 06/18] perf: add LLMDerivService as the base of LLMDerivs --- Easydict.xcodeproj/project.pbxproj | 4 ++ .../Service/LLMDerivs/LLMDerivService.swift | 37 +++++++++++++++++++ .../Service/LLMDerivs/PolishingService.swift | 25 +------------ .../Service/LLMDerivs/SummaryService.swift | 25 +------------ 4 files changed, 43 insertions(+), 48 deletions(-) create mode 100644 Easydict/Swift/Service/LLMDerivs/LLMDerivService.swift diff --git a/Easydict.xcodeproj/project.pbxproj b/Easydict.xcodeproj/project.pbxproj index 68e798963..496bbf9ec 100644 --- a/Easydict.xcodeproj/project.pbxproj +++ b/Easydict.xcodeproj/project.pbxproj @@ -293,6 +293,7 @@ C415C0AD2B450D4800A9D231 /* GeminiService.swift in Sources */ = {isa = PBXBuildFile; fileRef = C415C0AC2B450D4800A9D231 /* GeminiService.swift */; }; C477BF912C0E2C61006A3F27 /* InfoPlist.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = C477BF902C0E2C61006A3F27 /* InfoPlist.xcstrings */; }; C490BF722BE910B70021E40A /* AdvancedTabItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C490BF712BE910B70021E40A /* AdvancedTabItemView.swift */; }; + C4A512BE2C414A2400F00F33 /* LLMDerivService.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4A512BD2C414A2400F00F33 /* LLMDerivService.swift */; }; C4BFDD7A2BE61F550094026B /* Vortex in Frameworks */ = {isa = PBXBuildFile; productRef = C4BFDD792BE61F550094026B /* Vortex */; }; C4CCDAA32C407A0D00AC88BA /* SummaryService.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4CCDAA22C407A0D00AC88BA /* SummaryService.swift */; }; C4CCDAA52C407A4100AC88BA /* PolishingService.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4CCDAA42C407A4100AC88BA /* PolishingService.swift */; }; @@ -794,6 +795,7 @@ C415C0AC2B450D4800A9D231 /* GeminiService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeminiService.swift; sourceTree = ""; }; C477BF902C0E2C61006A3F27 /* InfoPlist.xcstrings */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; path = InfoPlist.xcstrings; sourceTree = ""; }; C490BF712BE910B70021E40A /* AdvancedTabItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = AdvancedTabItemView.swift; path = Easydict/Swift/View/AdvancedTabItemView.swift; sourceTree = SOURCE_ROOT; }; + C4A512BD2C414A2400F00F33 /* LLMDerivService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LLMDerivService.swift; sourceTree = ""; }; C4CCDAA22C407A0D00AC88BA /* SummaryService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SummaryService.swift; sourceTree = ""; }; C4CCDAA42C407A4100AC88BA /* PolishingService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PolishingService.swift; sourceTree = ""; }; C4DD01E82B12B3C80025EE8E /* TencentService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TencentService.swift; sourceTree = ""; }; @@ -2303,6 +2305,7 @@ C4D1ADE12C3F340500A19D02 /* LLMDerivs */ = { isa = PBXGroup; children = ( + C4A512BD2C414A2400F00F33 /* LLMDerivService.swift */, C4CCDAA42C407A4100AC88BA /* PolishingService.swift */, C4CCDAA22C407A0D00AC88BA /* SummaryService.swift */, ); @@ -2806,6 +2809,7 @@ 03D0435A2928C4C800E7559E /* EZWindowManager.m in Sources */, 6295DE342A84EF76006145F4 /* EZBingLookupModel.m in Sources */, 03FD68BE2B1E151A00FD388E /* String+EncryptAES.swift in Sources */, + C4A512BE2C414A2400F00F33 /* LLMDerivService.swift in Sources */, 03B0230729231FA6001C7E63 /* EZCommonView.m in Sources */, 03B0233329231FA6001C7E63 /* MMLog.m in Sources */, 0AC8A8352B6641A7006DA5CC /* TencentService+ConfigurableService.swift in Sources */, diff --git a/Easydict/Swift/Service/LLMDerivs/LLMDerivService.swift b/Easydict/Swift/Service/LLMDerivs/LLMDerivService.swift new file mode 100644 index 000000000..a248d875c --- /dev/null +++ b/Easydict/Swift/Service/LLMDerivs/LLMDerivService.swift @@ -0,0 +1,37 @@ +// +// LLMDerivService.swift +// Easydict +// +// Created by Jerry on 2024-07-12. +// Copyright © 2024 izual. All rights reserved. +// + +import Foundation +import OpenAI + +/// A class used for LLM derivatives such as summary and polishing +/// Based on `BuiltInAIService` and takes `llama3-70b-8192` as the LLM +class LLMDerivService: BuiltInAIService { + // MARK: Public + + public override func configurationListItems() -> Any { + StreamConfigurationView( + service: self, + showNameSection: false, + showAPIKeySection: false, + showEndpointSection: false, + showSupportedModelsSection: false, + showUsedModelSection: false, + showTranslationToggle: false, + showSentenceToggle: false, + showDictionaryToggle: false, + showUsageStatusPicker: true + ) + } + + // MARK: Internal + + override var defaultModels: [String] { + ["llama3-70b-8192"] + } +} diff --git a/Easydict/Swift/Service/LLMDerivs/PolishingService.swift b/Easydict/Swift/Service/LLMDerivs/PolishingService.swift index c2290ef78..f50ca8a2d 100644 --- a/Easydict/Swift/Service/LLMDerivs/PolishingService.swift +++ b/Easydict/Swift/Service/LLMDerivs/PolishingService.swift @@ -9,9 +9,7 @@ import Foundation @objc(EZPolishingService) -class PolishingService: BuiltInAIService { - // MARK: Public - +class PolishingService: LLMDerivService { public override func name() -> String { NSLocalizedString("polishing_service", comment: "") } @@ -19,25 +17,4 @@ class PolishingService: BuiltInAIService { public override func serviceType() -> ServiceType { .polishing } - - public override func configurationListItems() -> Any { - StreamConfigurationView( - service: self, - showNameSection: false, - showAPIKeySection: false, - showEndpointSection: false, - showSupportedModelsSection: false, - showUsedModelSection: false, - showTranslationToggle: false, - showSentenceToggle: false, - showDictionaryToggle: false, - showUsageStatusPicker: true - ) - } - - // MARK: Internal - - override var defaultModels: [String] { - ["llama3-70b-8192"] - } } diff --git a/Easydict/Swift/Service/LLMDerivs/SummaryService.swift b/Easydict/Swift/Service/LLMDerivs/SummaryService.swift index b5da3ffeb..fcf7829b2 100644 --- a/Easydict/Swift/Service/LLMDerivs/SummaryService.swift +++ b/Easydict/Swift/Service/LLMDerivs/SummaryService.swift @@ -10,9 +10,7 @@ import Foundation import OpenAI @objc(EZSummaryService) -class SummaryService: BuiltInAIService { - // MARK: Public - +class SummaryService: LLMDerivService { public override func name() -> String { NSLocalizedString("summary_service", comment: "") } @@ -20,25 +18,4 @@ class SummaryService: BuiltInAIService { public override func serviceType() -> ServiceType { .summary } - - public override func configurationListItems() -> Any { - StreamConfigurationView( - service: self, - showNameSection: false, - showAPIKeySection: false, - showEndpointSection: false, - showSupportedModelsSection: false, - showUsedModelSection: false, - showTranslationToggle: false, - showSentenceToggle: false, - showDictionaryToggle: false, - showUsageStatusPicker: true - ) - } - - // MARK: Internal - - override var defaultModels: [String] { - ["llama3-70b-8192"] - } } From fa6805edaafd885d6747590171a34c5c028cbd32 Mon Sep 17 00:00:00 2001 From: Jerry Date: Fri, 12 Jul 2024 21:44:58 +0800 Subject: [PATCH 07/18] feat: implement polishing and summary features --- .../Service/LLMDerivs/LLMDerivService.swift | 15 ++- .../Service/LLMDerivs/PolishingService.swift | 77 ++++++++++++ .../Service/LLMDerivs/SummaryService.swift | 76 ++++++++++++ .../Service/OpenAI/LLMStreamService.swift | 12 ++ Easydict/Swift/Service/OpenAI/Prompt.swift | 114 ++++++++++++++++++ 5 files changed, 293 insertions(+), 1 deletion(-) diff --git a/Easydict/Swift/Service/LLMDerivs/LLMDerivService.swift b/Easydict/Swift/Service/LLMDerivs/LLMDerivService.swift index a248d875c..074195add 100644 --- a/Easydict/Swift/Service/LLMDerivs/LLMDerivService.swift +++ b/Easydict/Swift/Service/LLMDerivs/LLMDerivService.swift @@ -7,7 +7,6 @@ // import Foundation -import OpenAI /// A class used for LLM derivatives such as summary and polishing /// Based on `BuiltInAIService` and takes `llama3-70b-8192` as the LLM @@ -34,4 +33,18 @@ class LLMDerivService: BuiltInAIService { override var defaultModels: [String] { ["llama3-70b-8192"] } + + func serviceChatMessage(_ chatQuery: LLMDerivParam) -> [Any] { + var chatModels: [ChatMessage] = [] + for message in llmDerivMessageDicts(chatQuery) { + if let roleRawValue = message["role"], + let role = ChatMessage.Role(rawValue: roleRawValue), + let content = message["content"] { + if let chat = ChatMessage(role: role, content: content) { + chatModels.append(chat) + } + } + } + return chatModels + } } diff --git a/Easydict/Swift/Service/LLMDerivs/PolishingService.swift b/Easydict/Swift/Service/LLMDerivs/PolishingService.swift index f50ca8a2d..b1b47b9b5 100644 --- a/Easydict/Swift/Service/LLMDerivs/PolishingService.swift +++ b/Easydict/Swift/Service/LLMDerivs/PolishingService.swift @@ -7,6 +7,7 @@ // import Foundation +import OpenAI @objc(EZPolishingService) class PolishingService: LLMDerivService { @@ -17,4 +18,80 @@ class PolishingService: LLMDerivService { public override func serviceType() -> ServiceType { .polishing } + + public override func translate( + _ text: String, + from: Language, + to: Language, + completion: @escaping (EZQueryResult, Error?) -> () + ) { + let url = URL(string: endpoint) + let invalidURLError = EZError(type: .param, description: "`\(serviceType().rawValue)` endpoint is invalid") + guard let url, url.isValid else { + completion(result, invalidURLError) + return + } + + var resultText = "" + + result.isStreamFinished = false + + // Set EZQueryTextType as translation since no formatting is needed + let queryType = EZQueryTextType.translation + let chatParam = LLMDerivParam( + text: text, + sourceLanguage: from, + serviceType: .polishing + ) + + let chatHistory = serviceChatMessage(chatParam) + guard let chatHistory = chatHistory as? [ChatMessage] else { return } + + let query = ChatQuery(messages: chatHistory, model: model, temperature: 0) + let openAI = OpenAI(apiToken: apiKey) + + // FIXME: It seems that `control` will cause a memory leak, but it is not clear how to solve it. + unowned let unownedControl = control + + // TODO: refactor chatsStream with await + openAI.chatsStream(query: query, url: url, control: unownedControl) { [weak self] res in + guard let self else { return } + + switch res { + case let .success(chatResult): + if let content = chatResult.choices.first?.delta.content { + resultText += content + } + updateResultText(resultText, queryType: queryType, error: nil, completion: completion) + case let .failure(error): + // For stream requests, certain special cases may be normal for the first part of the data transfer, but the final parsing is incorrect. + var text: String? + var err: Error? = error + if !resultText.isEmpty { + text = resultText + err = nil + + logError("\(name())-(\(model)) error: \(error.localizedDescription)") + logError(String(describing: error)) + } + updateResultText(text, queryType: queryType, error: err, completion: completion) + } + + } completion: { [weak self] error in + guard let self else { return } + + if let error { + updateResultText(nil, queryType: queryType, error: error, completion: completion) + return + } + + // If already has error, we do not need to update it. + if result.error == nil { + resultText = getFinalResultText(resultText) +// log("\(name())-(\(model)): \(resultText)") + updateResultText(resultText, queryType: queryType, error: nil, completion: completion) + result.isStreamFinished = true + } + } + } } diff --git a/Easydict/Swift/Service/LLMDerivs/SummaryService.swift b/Easydict/Swift/Service/LLMDerivs/SummaryService.swift index fcf7829b2..4394a75aa 100644 --- a/Easydict/Swift/Service/LLMDerivs/SummaryService.swift +++ b/Easydict/Swift/Service/LLMDerivs/SummaryService.swift @@ -18,4 +18,80 @@ class SummaryService: LLMDerivService { public override func serviceType() -> ServiceType { .summary } + + public override func translate( + _ text: String, + from: Language, + to: Language, + completion: @escaping (EZQueryResult, Error?) -> () + ) { + let url = URL(string: endpoint) + let invalidURLError = EZError(type: .param, description: "`\(serviceType().rawValue)` endpoint is invalid") + guard let url, url.isValid else { + completion(result, invalidURLError) + return + } + + var resultText = "" + + result.isStreamFinished = false + + // Set EZQueryTextType as translation since no formatting is needed + let queryType = EZQueryTextType.translation + let chatParam = LLMDerivParam( + text: text, + sourceLanguage: from, + serviceType: .summary + ) + + let chatHistory = serviceChatMessage(chatParam) + guard let chatHistory = chatHistory as? [ChatMessage] else { return } + + let query = ChatQuery(messages: chatHistory, model: model, temperature: 0) + let openAI = OpenAI(apiToken: apiKey) + + // FIXME: It seems that `control` will cause a memory leak, but it is not clear how to solve it. + unowned let unownedControl = control + + // TODO: refactor chatsStream with await + openAI.chatsStream(query: query, url: url, control: unownedControl) { [weak self] res in + guard let self else { return } + + switch res { + case let .success(chatResult): + if let content = chatResult.choices.first?.delta.content { + resultText += content + } + updateResultText(resultText, queryType: queryType, error: nil, completion: completion) + case let .failure(error): + // For stream requests, certain special cases may be normal for the first part of the data transfer, but the final parsing is incorrect. + var text: String? + var err: Error? = error + if !resultText.isEmpty { + text = resultText + err = nil + + logError("\(name())-(\(model)) error: \(error.localizedDescription)") + logError(String(describing: error)) + } + updateResultText(text, queryType: queryType, error: err, completion: completion) + } + + } completion: { [weak self] error in + guard let self else { return } + + if let error { + updateResultText(nil, queryType: queryType, error: error, completion: completion) + return + } + + // If already has error, we do not need to update it. + if result.error == nil { + resultText = getFinalResultText(resultText) +// log("\(name())-(\(model)): \(resultText)") + updateResultText(resultText, queryType: queryType, error: nil, completion: completion) + result.isStreamFinished = true + } + } + } } diff --git a/Easydict/Swift/Service/OpenAI/LLMStreamService.swift b/Easydict/Swift/Service/OpenAI/LLMStreamService.swift index b446d0cdf..8a4e1d7db 100644 --- a/Easydict/Swift/Service/OpenAI/LLMStreamService.swift +++ b/Easydict/Swift/Service/OpenAI/LLMStreamService.swift @@ -317,3 +317,15 @@ struct ChatQueryParam { (text, sourceLanguage, targetLanguage, queryType, enableSystemPrompt) } } + +// MARK: - LLMDerivParam + +struct LLMDerivParam { + let text: String + let sourceLanguage: Language + let serviceType: LLMDerivType + + func unpack() -> (String, Language, LLMDerivType) { + (text, sourceLanguage, serviceType) + } +} diff --git a/Easydict/Swift/Service/OpenAI/Prompt.swift b/Easydict/Swift/Service/OpenAI/Prompt.swift index cf01c78de..272eeac79 100644 --- a/Easydict/Swift/Service/OpenAI/Prompt.swift +++ b/Easydict/Swift/Service/OpenAI/Prompt.swift @@ -19,6 +19,113 @@ extension LLMStreamService { You are a word search assistant skilled in multiple languages and knowledgeable in etymology. You can help search for words, phrases, slang, abbreviations, and other information. Prioritize queries from authoritative dictionary databases, such as the Oxford Dictionary, Cambridge Dictionary, and Wikipedia. If a word or abbreviation has multiple meanings, look up the most commonly used ones. """ + static let polishingSystemPrompt = """ + You are a text polishing expert skilled in refining and enhancing written content. Your task is to improve the clarity, coherence, grammar, and overall quality of the text while maintaining the original meaning and intent. Focus on correcting grammatical errors, improving sentence structure, and enhancing readability. Ensure the polished text is natural and fluent. Only return the polished text, without including redundant quotes or additional notes. + """ + + static let summarySystemPrompt = """ + You are a text summarization expert proficient in condensing lengthy documents, articles, and other text formats into concise and coherent summaries. Your summaries should capture the main points, key details, and overall essence of the original text while maintaining clarity and accuracy. Avoid adding personal opinions or interpretations. Only return the summary, without including redundant quotes or additional notes. + """ + + // MARK: LLM Derivatives Messages + + func llmDerivMessageDicts(_ chatQuery: LLMDerivParam) -> [[String: String]] { + switch chatQuery.serviceType { + case .polishing: + polishingMessages(chatQuery) + case .summary: + summaryMessages(chatQuery) + } + } + + private func polishingPrompt(text: String, in sourceLanguage: Language) -> String { + "Polish the following \(sourceLanguage.queryLanguageName) text to improve its clarity, coherence, grammar, and overall quality while maintaining the original meaning and intent: \"\"\"\(text)\"\"\"" + } + + private func summaryPrompt(text: String, in sourceLanguage: Language) -> String { + "Summarize the following \(sourceLanguage.queryLanguageName) text, capturing the main points, key details, and overall essence while maintaining clarity and accuracy: \"\"\"\(text)\"\"\"" + } + + private func polishingMessages(_ derivParam: LLMDerivParam) -> [[String: String]] { + let (text, sourceLanguage, _) = derivParam.unpack() + + let prompt = polishingPrompt(text: text, in: sourceLanguage) + + let englishFewShot = [ + chatMessagePair( + userContent: "Polish the following English text to improve its clarity and coherence: \"\"\"The book was wrote by an unknown author but it was very popular among readers.\"\"\"", + assistantContent: "The book was written by an unknown author, but it was very popular among readers." + ), + chatMessagePair( + userContent: "Polish the following English text to improve its grammar and readability: \"\"\"She don’t like the weather today, it makes her feel bad.\"\"\"", + assistantContent: "She doesn't like the weather today; it makes her feel bad." + ), + chatMessagePair( + userContent: "Polish the following English text to enhance its overall quality: \"\"\"The project was successful although we faced many problems in the beginning.\"\"\"", + assistantContent: "The project was successful despite facing many problems in the beginning." + ), + ].flatMap { $0 } + + let systemMessages = [chatMessage( + role: .system, + content: LLMStreamService.polishingSystemPrompt + )] + + var messages = systemMessages + messages.append(contentsOf: englishFewShot) + + let userMessages = [ + [ + "role": "user", + "content": prompt, + ], + ] + + messages.append(contentsOf: userMessages) + return messages + } + + private func summaryMessages(_ derivParam: LLMDerivParam) -> [[String: String]] { + let (text, sourceLanguage, _) = derivParam.unpack() + + let prompt = summaryPrompt(text: text, in: sourceLanguage) + + let englishFewShot = [ + chatMessagePair( + userContent: "Summarize the following English text: \"\"\"The quick brown fox jumps over the lazy dog. The fox is very quick and agile, making it difficult for the dog to catch up. Despite several attempts, the dog remains lazy and doesn't put in much effort to chase the fox.\"\"\"", + assistantContent: "The quick and agile fox jumps over the lazy dog, who remains lazy and doesn't put in much effort to chase the fox." + ), + chatMessagePair( + userContent: "Summarize the following English text: \"\"\"In a faraway land, there was a kingdom ruled by a wise king. The king was known for his fairness and kindness. He ensured that all his subjects were treated equally and that justice was served. Under his rule, the kingdom prospered and the people lived in peace and harmony.\"\"\"", + assistantContent: "A wise and fair king ruled a prosperous kingdom where justice was served and people lived in peace and harmony." + ), + chatMessagePair( + userContent: "Summarize the following English text: \"\"\"The new restaurant in town has become very popular due to its delicious food and excellent service. Many people visit the restaurant every day to enjoy the meals and the pleasant atmosphere. The chef is renowned for his culinary skills and the staff are very friendly.\"\"\"", + assistantContent: "The new restaurant is popular for its delicious food, excellent service, renowned chef, and friendly staff." + ), + ].flatMap { $0 } + + let systemMessages = [chatMessage( + role: .system, + content: LLMStreamService.summarySystemPrompt + )] + + var messages = systemMessages + messages.append(contentsOf: englishFewShot) + + let userMessages = [ + [ + "role": "user", + "content": prompt, + ], + ] + + messages.append(contentsOf: userMessages) + return messages + } + + // MARK: Translation Messages + func chatMessageDicts(_ chatQuery: ChatQueryParam) -> [[String: String]] { switch chatQuery.queryType { @@ -704,4 +811,11 @@ enum ChatRole: String, Codable, Equatable, CaseIterable { case model // Gemini role, equal to OpenAI assistant role. } +// MARK: - LLMDerivType + +enum LLMDerivType { + case polishing + case summary +} + // swiftlint:enable all From f9e08ff0df24fad6cc690ff9646b25cf8578a654 Mon Sep 17 00:00:00 2001 From: tisfeng Date: Sat, 13 Jul 2024 01:35:20 +0800 Subject: [PATCH 08/18] refactor: make AIToolService override method chatMessageDicts() --- Easydict.xcodeproj/project.pbxproj | 14 +-- .../AIToolService.swift} | 24 +---- .../Service/AITool/PolishingService.swift | 29 ++++++ .../Swift/Service/AITool/SummaryService.swift | 29 ++++++ .../Service/LLMDerivs/PolishingService.swift | 97 ------------------- .../Service/LLMDerivs/SummaryService.swift | 97 ------------------- .../Service/OpenAI/LLMStreamService.swift | 12 +++ Easydict/Swift/Service/OpenAI/Prompt.swift | 37 ++----- 8 files changed, 85 insertions(+), 254 deletions(-) rename Easydict/Swift/Service/{LLMDerivs/LLMDerivService.swift => AITool/AIToolService.swift} (53%) create mode 100644 Easydict/Swift/Service/AITool/PolishingService.swift create mode 100644 Easydict/Swift/Service/AITool/SummaryService.swift delete mode 100644 Easydict/Swift/Service/LLMDerivs/PolishingService.swift delete mode 100644 Easydict/Swift/Service/LLMDerivs/SummaryService.swift diff --git a/Easydict.xcodeproj/project.pbxproj b/Easydict.xcodeproj/project.pbxproj index 496bbf9ec..db53e1bc8 100644 --- a/Easydict.xcodeproj/project.pbxproj +++ b/Easydict.xcodeproj/project.pbxproj @@ -293,7 +293,7 @@ C415C0AD2B450D4800A9D231 /* GeminiService.swift in Sources */ = {isa = PBXBuildFile; fileRef = C415C0AC2B450D4800A9D231 /* GeminiService.swift */; }; C477BF912C0E2C61006A3F27 /* InfoPlist.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = C477BF902C0E2C61006A3F27 /* InfoPlist.xcstrings */; }; C490BF722BE910B70021E40A /* AdvancedTabItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C490BF712BE910B70021E40A /* AdvancedTabItemView.swift */; }; - C4A512BE2C414A2400F00F33 /* LLMDerivService.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4A512BD2C414A2400F00F33 /* LLMDerivService.swift */; }; + C4A512BE2C414A2400F00F33 /* AIToolService.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4A512BD2C414A2400F00F33 /* AIToolService.swift */; }; C4BFDD7A2BE61F550094026B /* Vortex in Frameworks */ = {isa = PBXBuildFile; productRef = C4BFDD792BE61F550094026B /* Vortex */; }; C4CCDAA32C407A0D00AC88BA /* SummaryService.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4CCDAA22C407A0D00AC88BA /* SummaryService.swift */; }; C4CCDAA52C407A4100AC88BA /* PolishingService.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4CCDAA42C407A4100AC88BA /* PolishingService.swift */; }; @@ -795,7 +795,7 @@ C415C0AC2B450D4800A9D231 /* GeminiService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeminiService.swift; sourceTree = ""; }; C477BF902C0E2C61006A3F27 /* InfoPlist.xcstrings */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; path = InfoPlist.xcstrings; sourceTree = ""; }; C490BF712BE910B70021E40A /* AdvancedTabItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = AdvancedTabItemView.swift; path = Easydict/Swift/View/AdvancedTabItemView.swift; sourceTree = SOURCE_ROOT; }; - C4A512BD2C414A2400F00F33 /* LLMDerivService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LLMDerivService.swift; sourceTree = ""; }; + C4A512BD2C414A2400F00F33 /* AIToolService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AIToolService.swift; sourceTree = ""; }; C4CCDAA22C407A0D00AC88BA /* SummaryService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SummaryService.swift; sourceTree = ""; }; C4CCDAA42C407A4100AC88BA /* PolishingService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PolishingService.swift; sourceTree = ""; }; C4DD01E82B12B3C80025EE8E /* TencentService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TencentService.swift; sourceTree = ""; }; @@ -1210,7 +1210,7 @@ 0A9AFBA92B7F8D6A0064C9A8 /* CustomOpenAI */, C415C0AB2B450C4500A9D231 /* Gemini */, 03792EA02C3830E60074A145 /* Ollama */, - C4D1ADE12C3F340500A19D02 /* LLMDerivs */, + C4D1ADE12C3F340500A19D02 /* AITool */, C4DD01E72B12B3B00025EE8E /* Tencent */, 2746AEBF2AF95040005FE0A1 /* Caiyun */, 62E2BF462B4082BA00E42D38 /* Ali */, @@ -2302,14 +2302,14 @@ name = "Recovered References"; sourceTree = ""; }; - C4D1ADE12C3F340500A19D02 /* LLMDerivs */ = { + C4D1ADE12C3F340500A19D02 /* AITool */ = { isa = PBXGroup; children = ( - C4A512BD2C414A2400F00F33 /* LLMDerivService.swift */, + C4A512BD2C414A2400F00F33 /* AIToolService.swift */, C4CCDAA42C407A4100AC88BA /* PolishingService.swift */, C4CCDAA22C407A0D00AC88BA /* SummaryService.swift */, ); - path = LLMDerivs; + path = AITool; sourceTree = ""; }; C4DD01E72B12B3B00025EE8E /* Tencent */ = { @@ -2809,7 +2809,7 @@ 03D0435A2928C4C800E7559E /* EZWindowManager.m in Sources */, 6295DE342A84EF76006145F4 /* EZBingLookupModel.m in Sources */, 03FD68BE2B1E151A00FD388E /* String+EncryptAES.swift in Sources */, - C4A512BE2C414A2400F00F33 /* LLMDerivService.swift in Sources */, + C4A512BE2C414A2400F00F33 /* AIToolService.swift in Sources */, 03B0230729231FA6001C7E63 /* EZCommonView.m in Sources */, 03B0233329231FA6001C7E63 /* MMLog.m in Sources */, 0AC8A8352B6641A7006DA5CC /* TencentService+ConfigurableService.swift in Sources */, diff --git a/Easydict/Swift/Service/LLMDerivs/LLMDerivService.swift b/Easydict/Swift/Service/AITool/AIToolService.swift similarity index 53% rename from Easydict/Swift/Service/LLMDerivs/LLMDerivService.swift rename to Easydict/Swift/Service/AITool/AIToolService.swift index 074195add..3a3a7fd40 100644 --- a/Easydict/Swift/Service/LLMDerivs/LLMDerivService.swift +++ b/Easydict/Swift/Service/AITool/AIToolService.swift @@ -10,9 +10,7 @@ import Foundation /// A class used for LLM derivatives such as summary and polishing /// Based on `BuiltInAIService` and takes `llama3-70b-8192` as the LLM -class LLMDerivService: BuiltInAIService { - // MARK: Public - +class AIToolService: BuiltInAIService { public override func configurationListItems() -> Any { StreamConfigurationView( service: self, @@ -27,24 +25,4 @@ class LLMDerivService: BuiltInAIService { showUsageStatusPicker: true ) } - - // MARK: Internal - - override var defaultModels: [String] { - ["llama3-70b-8192"] - } - - func serviceChatMessage(_ chatQuery: LLMDerivParam) -> [Any] { - var chatModels: [ChatMessage] = [] - for message in llmDerivMessageDicts(chatQuery) { - if let roleRawValue = message["role"], - let role = ChatMessage.Role(rawValue: roleRawValue), - let content = message["content"] { - if let chat = ChatMessage(role: role, content: content) { - chatModels.append(chat) - } - } - } - return chatModels - } } diff --git a/Easydict/Swift/Service/AITool/PolishingService.swift b/Easydict/Swift/Service/AITool/PolishingService.swift new file mode 100644 index 000000000..05abc1674 --- /dev/null +++ b/Easydict/Swift/Service/AITool/PolishingService.swift @@ -0,0 +1,29 @@ +// +// PolishingService.swift +// Easydict +// +// Created by Jerry on 2024-07-11. +// Copyright © 2024 izual. All rights reserved. +// + +import Foundation +import OpenAI + +@objc(EZPolishingService) +class PolishingService: AIToolService { + // MARK: Public + + public override func name() -> String { + NSLocalizedString("polishing_service", comment: "") + } + + public override func serviceType() -> ServiceType { + .polishing + } + + // MARK: Internal + + override func chatMessageDicts(_ chatQuery: ChatQueryParam) -> [[String: String]] { + polishingMessages(chatQuery) + } +} diff --git a/Easydict/Swift/Service/AITool/SummaryService.swift b/Easydict/Swift/Service/AITool/SummaryService.swift new file mode 100644 index 000000000..9e0db6187 --- /dev/null +++ b/Easydict/Swift/Service/AITool/SummaryService.swift @@ -0,0 +1,29 @@ +// +// SummaryService.swift +// Easydict +// +// Created by Jerry on 2024-07-11. +// Copyright © 2024 izual. All rights reserved. +// + +import Foundation +import OpenAI + +@objc(EZSummaryService) +class SummaryService: AIToolService { + // MARK: Public + + public override func name() -> String { + NSLocalizedString("summary_service", comment: "") + } + + public override func serviceType() -> ServiceType { + .summary + } + + // MARK: Internal + + override func chatMessageDicts(_ chatQuery: ChatQueryParam) -> [[String: String]] { + summaryMessages(chatQuery) + } +} diff --git a/Easydict/Swift/Service/LLMDerivs/PolishingService.swift b/Easydict/Swift/Service/LLMDerivs/PolishingService.swift deleted file mode 100644 index b1b47b9b5..000000000 --- a/Easydict/Swift/Service/LLMDerivs/PolishingService.swift +++ /dev/null @@ -1,97 +0,0 @@ -// -// PolishingService.swift -// Easydict -// -// Created by Jerry on 2024-07-11. -// Copyright © 2024 izual. All rights reserved. -// - -import Foundation -import OpenAI - -@objc(EZPolishingService) -class PolishingService: LLMDerivService { - public override func name() -> String { - NSLocalizedString("polishing_service", comment: "") - } - - public override func serviceType() -> ServiceType { - .polishing - } - - public override func translate( - _ text: String, - from: Language, - to: Language, - completion: @escaping (EZQueryResult, Error?) -> () - ) { - let url = URL(string: endpoint) - let invalidURLError = EZError(type: .param, description: "`\(serviceType().rawValue)` endpoint is invalid") - guard let url, url.isValid else { - completion(result, invalidURLError) - return - } - - var resultText = "" - - result.isStreamFinished = false - - // Set EZQueryTextType as translation since no formatting is needed - let queryType = EZQueryTextType.translation - let chatParam = LLMDerivParam( - text: text, - sourceLanguage: from, - serviceType: .polishing - ) - - let chatHistory = serviceChatMessage(chatParam) - guard let chatHistory = chatHistory as? [ChatMessage] else { return } - - let query = ChatQuery(messages: chatHistory, model: model, temperature: 0) - let openAI = OpenAI(apiToken: apiKey) - - // FIXME: It seems that `control` will cause a memory leak, but it is not clear how to solve it. - unowned let unownedControl = control - - // TODO: refactor chatsStream with await - openAI.chatsStream(query: query, url: url, control: unownedControl) { [weak self] res in - guard let self else { return } - - switch res { - case let .success(chatResult): - if let content = chatResult.choices.first?.delta.content { - resultText += content - } - updateResultText(resultText, queryType: queryType, error: nil, completion: completion) - case let .failure(error): - // For stream requests, certain special cases may be normal for the first part of the data transfer, but the final parsing is incorrect. - var text: String? - var err: Error? = error - if !resultText.isEmpty { - text = resultText - err = nil - - logError("\(name())-(\(model)) error: \(error.localizedDescription)") - logError(String(describing: error)) - } - updateResultText(text, queryType: queryType, error: err, completion: completion) - } - - } completion: { [weak self] error in - guard let self else { return } - - if let error { - updateResultText(nil, queryType: queryType, error: error, completion: completion) - return - } - - // If already has error, we do not need to update it. - if result.error == nil { - resultText = getFinalResultText(resultText) -// log("\(name())-(\(model)): \(resultText)") - updateResultText(resultText, queryType: queryType, error: nil, completion: completion) - result.isStreamFinished = true - } - } - } -} diff --git a/Easydict/Swift/Service/LLMDerivs/SummaryService.swift b/Easydict/Swift/Service/LLMDerivs/SummaryService.swift deleted file mode 100644 index 4394a75aa..000000000 --- a/Easydict/Swift/Service/LLMDerivs/SummaryService.swift +++ /dev/null @@ -1,97 +0,0 @@ -// -// SummaryService.swift -// Easydict -// -// Created by Jerry on 2024-07-11. -// Copyright © 2024 izual. All rights reserved. -// - -import Foundation -import OpenAI - -@objc(EZSummaryService) -class SummaryService: LLMDerivService { - public override func name() -> String { - NSLocalizedString("summary_service", comment: "") - } - - public override func serviceType() -> ServiceType { - .summary - } - - public override func translate( - _ text: String, - from: Language, - to: Language, - completion: @escaping (EZQueryResult, Error?) -> () - ) { - let url = URL(string: endpoint) - let invalidURLError = EZError(type: .param, description: "`\(serviceType().rawValue)` endpoint is invalid") - guard let url, url.isValid else { - completion(result, invalidURLError) - return - } - - var resultText = "" - - result.isStreamFinished = false - - // Set EZQueryTextType as translation since no formatting is needed - let queryType = EZQueryTextType.translation - let chatParam = LLMDerivParam( - text: text, - sourceLanguage: from, - serviceType: .summary - ) - - let chatHistory = serviceChatMessage(chatParam) - guard let chatHistory = chatHistory as? [ChatMessage] else { return } - - let query = ChatQuery(messages: chatHistory, model: model, temperature: 0) - let openAI = OpenAI(apiToken: apiKey) - - // FIXME: It seems that `control` will cause a memory leak, but it is not clear how to solve it. - unowned let unownedControl = control - - // TODO: refactor chatsStream with await - openAI.chatsStream(query: query, url: url, control: unownedControl) { [weak self] res in - guard let self else { return } - - switch res { - case let .success(chatResult): - if let content = chatResult.choices.first?.delta.content { - resultText += content - } - updateResultText(resultText, queryType: queryType, error: nil, completion: completion) - case let .failure(error): - // For stream requests, certain special cases may be normal for the first part of the data transfer, but the final parsing is incorrect. - var text: String? - var err: Error? = error - if !resultText.isEmpty { - text = resultText - err = nil - - logError("\(name())-(\(model)) error: \(error.localizedDescription)") - logError(String(describing: error)) - } - updateResultText(text, queryType: queryType, error: err, completion: completion) - } - - } completion: { [weak self] error in - guard let self else { return } - - if let error { - updateResultText(nil, queryType: queryType, error: error, completion: completion) - return - } - - // If already has error, we do not need to update it. - if result.error == nil { - resultText = getFinalResultText(resultText) -// log("\(name())-(\(model)): \(resultText)") - updateResultText(resultText, queryType: queryType, error: nil, completion: completion) - result.isStreamFinished = true - } - } - } -} diff --git a/Easydict/Swift/Service/OpenAI/LLMStreamService.swift b/Easydict/Swift/Service/OpenAI/LLMStreamService.swift index 8a4e1d7db..78696415b 100644 --- a/Easydict/Swift/Service/OpenAI/LLMStreamService.swift +++ b/Easydict/Swift/Service/OpenAI/LLMStreamService.swift @@ -210,6 +210,18 @@ public class LLMStreamService: QueryService { fatalError(mustOverride) } + func chatMessageDicts(_ chatQuery: ChatQueryParam) + -> [[String: String]] { + switch chatQuery.queryType { + case .dictionary: + dictMessages(chatQuery) + case .sentence: + sentenceMessages(chatQuery) + default: + translationMessages(chatQuery) + } + } + func getFinalResultText(_ text: String) -> String { var resultText = text.trim() diff --git a/Easydict/Swift/Service/OpenAI/Prompt.swift b/Easydict/Swift/Service/OpenAI/Prompt.swift index 272eeac79..529050acc 100644 --- a/Easydict/Swift/Service/OpenAI/Prompt.swift +++ b/Easydict/Swift/Service/OpenAI/Prompt.swift @@ -27,17 +27,6 @@ extension LLMStreamService { You are a text summarization expert proficient in condensing lengthy documents, articles, and other text formats into concise and coherent summaries. Your summaries should capture the main points, key details, and overall essence of the original text while maintaining clarity and accuracy. Avoid adding personal opinions or interpretations. Only return the summary, without including redundant quotes or additional notes. """ - // MARK: LLM Derivatives Messages - - func llmDerivMessageDicts(_ chatQuery: LLMDerivParam) -> [[String: String]] { - switch chatQuery.serviceType { - case .polishing: - polishingMessages(chatQuery) - case .summary: - summaryMessages(chatQuery) - } - } - private func polishingPrompt(text: String, in sourceLanguage: Language) -> String { "Polish the following \(sourceLanguage.queryLanguageName) text to improve its clarity, coherence, grammar, and overall quality while maintaining the original meaning and intent: \"\"\"\(text)\"\"\"" } @@ -46,8 +35,8 @@ extension LLMStreamService { "Summarize the following \(sourceLanguage.queryLanguageName) text, capturing the main points, key details, and overall essence while maintaining clarity and accuracy: \"\"\"\(text)\"\"\"" } - private func polishingMessages(_ derivParam: LLMDerivParam) -> [[String: String]] { - let (text, sourceLanguage, _) = derivParam.unpack() + func polishingMessages(_ derivParam: ChatQueryParam) -> [[String: String]] { + let (text, sourceLanguage, _, _, _) = derivParam.unpack() let prompt = polishingPrompt(text: text, in: sourceLanguage) @@ -85,8 +74,8 @@ extension LLMStreamService { return messages } - private func summaryMessages(_ derivParam: LLMDerivParam) -> [[String: String]] { - let (text, sourceLanguage, _) = derivParam.unpack() + func summaryMessages(_ derivParam: ChatQueryParam) -> [[String: String]] { + let (text, sourceLanguage, _, _, _) = derivParam.unpack() let prompt = summaryPrompt(text: text, in: sourceLanguage) @@ -126,23 +115,11 @@ extension LLMStreamService { // MARK: Translation Messages - func chatMessageDicts(_ chatQuery: ChatQueryParam) - -> [[String: String]] { - switch chatQuery.queryType { - case .dictionary: - dictMessages(chatQuery) - case .sentence: - sentenceMessages(chatQuery) - default: - translationMessages(chatQuery) - } - } - private func translationPrompt(text: String, from sourceLanguage: Language, to targetLanguage: Language) -> String { "Translate the following \(sourceLanguage.queryLanguageName) text into \(targetLanguage.queryLanguageName) text: \"\"\"\(text)\"\"\"" } - private func translationMessages(_ chatQuery: ChatQueryParam) -> [[String: String]] { + func translationMessages(_ chatQuery: ChatQueryParam) -> [[String: String]] { let (text, sourceLanguage, targetLanguage, _, enableSystemPrompt) = chatQuery.unpack() // Use """ %@ """ to wrap user input, Ref: https://help.openai.com/en/articles/6654000-best-practices-for-prompt-engineering-with-openai-api#h_21d4f4dc3d @@ -265,7 +242,7 @@ extension LLMStreamService { return messages } - private func sentenceMessages(_ chatQuery: ChatQueryParam) -> [[String: String]] { + func sentenceMessages(_ chatQuery: ChatQueryParam) -> [[String: String]] { let (sentence, sourceLanguage, targetLanguage, _, enableSystemPrompt) = chatQuery.unpack() let answerLanguage = Configuration.shared.firstLanguage @@ -447,7 +424,7 @@ extension LLMStreamService { return messages } - private func dictMessages(_ chatQuery: ChatQueryParam) -> [[String: String]] { + func dictMessages(_ chatQuery: ChatQueryParam) -> [[String: String]] { let (word, sourceLanguage, targetLanguage, _, enableSystemPrompt) = chatQuery.unpack() var prompt = "" From 0dfec4483f6fd2e5d1d99baf38ac2396193589b0 Mon Sep 17 00:00:00 2001 From: Jerry Date: Sat, 13 Jul 2024 01:49:56 +0800 Subject: [PATCH 09/18] perf: rename LLM Derivatives to AI Tools --- Easydict/Swift/Service/AITool/AIToolService.swift | 4 ++-- Easydict/Swift/Service/OpenAI/LLMStreamService.swift | 8 ++++---- Easydict/Swift/Service/OpenAI/Prompt.swift | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Easydict/Swift/Service/AITool/AIToolService.swift b/Easydict/Swift/Service/AITool/AIToolService.swift index 3a3a7fd40..62d2f1046 100644 --- a/Easydict/Swift/Service/AITool/AIToolService.swift +++ b/Easydict/Swift/Service/AITool/AIToolService.swift @@ -1,5 +1,5 @@ // -// LLMDerivService.swift +// AIToolService.swift // Easydict // // Created by Jerry on 2024-07-12. @@ -8,7 +8,7 @@ import Foundation -/// A class used for LLM derivatives such as summary and polishing +/// A class used for AI Tools such as summary and polishing /// Based on `BuiltInAIService` and takes `llama3-70b-8192` as the LLM class AIToolService: BuiltInAIService { public override func configurationListItems() -> Any { diff --git a/Easydict/Swift/Service/OpenAI/LLMStreamService.swift b/Easydict/Swift/Service/OpenAI/LLMStreamService.swift index 78696415b..93af8dc3d 100644 --- a/Easydict/Swift/Service/OpenAI/LLMStreamService.swift +++ b/Easydict/Swift/Service/OpenAI/LLMStreamService.swift @@ -330,14 +330,14 @@ struct ChatQueryParam { } } -// MARK: - LLMDerivParam +// MARK: - AIToolParam -struct LLMDerivParam { +struct AIToolParam { let text: String let sourceLanguage: Language - let serviceType: LLMDerivType + let serviceType: AIToolType - func unpack() -> (String, Language, LLMDerivType) { + func unpack() -> (String, Language, AIToolype) { (text, sourceLanguage, serviceType) } } diff --git a/Easydict/Swift/Service/OpenAI/Prompt.swift b/Easydict/Swift/Service/OpenAI/Prompt.swift index 529050acc..938768991 100644 --- a/Easydict/Swift/Service/OpenAI/Prompt.swift +++ b/Easydict/Swift/Service/OpenAI/Prompt.swift @@ -788,9 +788,9 @@ enum ChatRole: String, Codable, Equatable, CaseIterable { case model // Gemini role, equal to OpenAI assistant role. } -// MARK: - LLMDerivType +// MARK: - AIToolType -enum LLMDerivType { +enum AIToolType { case polishing case summary } From c4550ef27d1496da09bde46f242fd770a371d86d Mon Sep 17 00:00:00 2001 From: Jerry Date: Sat, 13 Jul 2024 01:52:02 +0800 Subject: [PATCH 10/18] perf: remove unused code --- Easydict/Swift/Service/OpenAI/LLMStreamService.swift | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/Easydict/Swift/Service/OpenAI/LLMStreamService.swift b/Easydict/Swift/Service/OpenAI/LLMStreamService.swift index 93af8dc3d..c4418222b 100644 --- a/Easydict/Swift/Service/OpenAI/LLMStreamService.swift +++ b/Easydict/Swift/Service/OpenAI/LLMStreamService.swift @@ -329,15 +329,3 @@ struct ChatQueryParam { (text, sourceLanguage, targetLanguage, queryType, enableSystemPrompt) } } - -// MARK: - AIToolParam - -struct AIToolParam { - let text: String - let sourceLanguage: Language - let serviceType: AIToolType - - func unpack() -> (String, Language, AIToolype) { - (text, sourceLanguage, serviceType) - } -} From 7d3518d3725764972e7397e341ac3f70a743aa2d Mon Sep 17 00:00:00 2001 From: Jerry Date: Sat, 13 Jul 2024 18:54:41 +0800 Subject: [PATCH 11/18] perf: improve prompts for text summary --- Easydict/Swift/Service/OpenAI/Prompt.swift | 42 +++++++++++++++++++--- 1 file changed, 38 insertions(+), 4 deletions(-) diff --git a/Easydict/Swift/Service/OpenAI/Prompt.swift b/Easydict/Swift/Service/OpenAI/Prompt.swift index 938768991..3bce76ac5 100644 --- a/Easydict/Swift/Service/OpenAI/Prompt.swift +++ b/Easydict/Swift/Service/OpenAI/Prompt.swift @@ -32,7 +32,7 @@ extension LLMStreamService { } private func summaryPrompt(text: String, in sourceLanguage: Language) -> String { - "Summarize the following \(sourceLanguage.queryLanguageName) text, capturing the main points, key details, and overall essence while maintaining clarity and accuracy: \"\"\"\(text)\"\"\"" + "Summarize the following \(sourceLanguage.queryLanguageName) text, capturing the main points, key details, and overall essence while maintaining clarity and accuracy: \"\"\"\(text)\"\"\" Your summary should also be in \(sourceLanguage.queryLanguageName)." } func polishingMessages(_ derivParam: ChatQueryParam) -> [[String: String]] { @@ -81,17 +81,51 @@ extension LLMStreamService { let englishFewShot = [ chatMessagePair( - userContent: "Summarize the following English text: \"\"\"The quick brown fox jumps over the lazy dog. The fox is very quick and agile, making it difficult for the dog to catch up. Despite several attempts, the dog remains lazy and doesn't put in much effort to chase the fox.\"\"\"", + userContent: "Summarize the following English text: \"\"\"The quick brown fox jumps over the lazy dog. The fox is very quick and agile, making it difficult for the dog to catch up. Despite several attempts, the dog remains lazy and doesn't put in much effort to chase the fox.\"\"\" Your summary should also be in English.", assistantContent: "The quick and agile fox jumps over the lazy dog, who remains lazy and doesn't put in much effort to chase the fox." ), chatMessagePair( - userContent: "Summarize the following English text: \"\"\"In a faraway land, there was a kingdom ruled by a wise king. The king was known for his fairness and kindness. He ensured that all his subjects were treated equally and that justice was served. Under his rule, the kingdom prospered and the people lived in peace and harmony.\"\"\"", + userContent: "Summarize the following English text: \"\"\"In a faraway land, there was a kingdom ruled by a wise king. The king was known for his fairness and kindness. He ensured that all his subjects were treated equally and that justice was served. Under his rule, the kingdom prospered and the people lived in peace and harmony.\"\"\" Your summary should also be in English.", assistantContent: "A wise and fair king ruled a prosperous kingdom where justice was served and people lived in peace and harmony." ), chatMessagePair( - userContent: "Summarize the following English text: \"\"\"The new restaurant in town has become very popular due to its delicious food and excellent service. Many people visit the restaurant every day to enjoy the meals and the pleasant atmosphere. The chef is renowned for his culinary skills and the staff are very friendly.\"\"\"", + userContent: "Summarize the following English text: \"\"\"The new restaurant in town has become very popular due to its delicious food and excellent service. Many people visit the restaurant every day to enjoy the meals and the pleasant atmosphere. The chef is renowned for his culinary skills and the staff are very friendly.\"\"\" Your summary should also be in English.", assistantContent: "The new restaurant is popular for its delicious food, excellent service, renowned chef, and friendly staff." ), + chatMessagePair( + userContent: "Summarize the following 简体中文 text: \"\"\"联合国在西非地区的最高官员周五表示,马里、布基纳法索和尼日尔决定退出西非国家经济共同体,将全面破坏地区关系,而此时恐怖主义和跨国有组织犯罪仍然对该地区构成普遍威胁。联合国西非和萨赫勒办事处负责人莱昂纳多•桑托斯•西芒向安理会表示,放弃西非经共体 将使三个军方领导的政府放弃关键利益,包括地区一体化、行动自由、安全合作和一体化的地区经济,这既伤害了他们自己,也伤害了西非经共体的其他成员。在高级军官分别于 2021 年、2022 年和 2023 年发动军事接管后,这三个过渡政府断绝了与西非经共体的关系。西芒说,军事领导人因此推迟了恢复宪政的时间,并引发了对长期不确定性的恐惧,因为公民空间继续缩小。\"\"\" Your summary should also be in 简体中文.", + assistantContent: "马里、布基纳法索和尼日尔退出西非国家经济共同体,将严重破坏地区关系,尤其是在恐怖主义和跨国有组织犯罪仍威胁该地区的情况下。联合国官员西芒指出,这一决定将使这三个国家失去地区一体化、安全合作和经济利益,推迟恢复宪政,并加剧长期不确定性。" + ), + chatMessagePair( + userContent: "Summarize the following 简体中文 text: \"\"\"联合国秘书长古特雷斯在为世界人口日的致辞中表示,为了实现社会边缘人群的权利和选择,我们必须将他们算在内——因为每个人都很重要。他说:“我们丰富多彩的人类织锦的强度取决于它最薄弱的丝线。当数据和其他系统为边缘人群服务时,它们就为所有人服务了。这就是我们加速所有人进步的方式。” 为了更深入研究这些人口数据,自1951年起,联合国经济和社会事务部已经出版了28版《世界人口展望》报告,该报告提供了237个国家从1950年至2024年的最新人口数据,以及直至2100年的预测数据。《世界人口展望》对监测可持续发展目标至关重要,大约四分之一的指标依赖于其数据。报告指出,世界总体生育率正在下降,妇女平均生育子女数比1990年左右减少了一个。超过半数的国家和地区,女性平均生育子女数低于2.1个,这是维持人口稳定的水平。 与此同时,将近五分之一的国家和地区,包括中国、意大利、韩国和西班牙,现在面临“超低生育率”,女性一生平均生育子女数少于1.4个。\"\"\" Your summary should also be in 简体中文.", + assistantContent: "联合国秘书长古特雷斯在世界人口日致辞中强调,包容社会边缘人群至关重要。自1951年以来,联合国经济和社会事务部发布了28版《世界人口展望》,提供237个国家从1950年至2024年的数据及至2100年的预测。报告显示,全球生育率下降,女性平均生育子女数比1990年减少一个。超过半数国家和地区生育率低于2.1,近五分之一(如中国、意大利、韩国、西班牙)面临“超低生育率”,生育率低于1.4。" + ), + chatMessagePair( + userContent: "Summarize the following 简体中文 text: \"\"\"新数据显示,全球近三分之一(31%)的成年人(约18亿人)在2022年未达到所建议的身体活动水平。研究结果指出,成年人缺乏身体活动的趋势令人担忧。2010年至2022年期间,成年人缺乏身体活动百分比增加了大约5个百分点。如果这一趋势继续下去,预计到2030年,缺乏身体活动百分比将进一步上升到35%。目前全世界距离实现到2030年减少缺乏身体活动率的全球目标还有很大差距。世界卫生组织(世卫组织)建议成年人每周进行150分钟的中等强度身体活动或75分钟的高强度身体活动。缺乏身体活动会加剧成年人患心血管疾病(如心脏病和中风)、2型糖尿病、痴呆症以及乳腺癌和结肠癌的风险。这项研究由世卫组织研究人员与学术界同事共同开展,研究结果发表在《柳叶刀全球健康》杂志上。世卫组织总干事谭德塞博士说,“这些新研究成果显示,由于未能增加身体活动,人们未能抓住机会减少癌症和心脏病以及改善精神健康和福祉。我们必须重申承诺,努力提高身体活动水平,大力采取果断行动,包括加强政策和增加资金,以扭转这一令人担忧的趋势”。高收入亚太地区(48%)和南亚(45%)缺乏身体活动率最高。其他地区的缺乏身体活动水平从高收入西方国家的28%到大洋洲的14%不等。令人关切的是,在不同性别之间和不同年龄之间仍然存在差距。与男性相比,全球女性缺乏身体活动情况仍较普遍,缺乏活动率为34%,男性为29%。在一些国家,这一差距达20个百分点。此外,与其他成年人群相比,60岁以上的人身体活动较少,因此,我们需要促进老年人开展更多身体活动。\"\"\" Your summary should also be in 简体中文.", + assistantContent: "2022年,全球31%(约18亿人)的成年人未达到建议的身体活动水平,2010年至2022年间增加了5个百分点。如果持续下去,2030年将升至35%。世卫组织建议每周150分钟中等强度或75分钟高强度活动,缺乏活动增加多种疾病风险。世卫组织总干事谭德塞博士呼吁加强政策和资金投入以提高身体活动水平。高收入亚太地区(48%)和南亚(45%)的缺乏活动率最高,其他地区从高收入西方国家的28%到大洋洲的14%不等。女性(34%)和老年人缺乏活动较多,男性为29%。性别差距在一些国家达20个百分点,60岁以上人群活动较少。" + ),世卫组织对用于治疗糖尿病和减肥的伪造药物发出警告 + Jun 20, 2024 at 21:00 + 世界卫生组织(世卫组织)发布了关于伪造司美格鲁肽的医疗产品警报,一些国家使用这种药物治疗2型糖尿病和肥胖症。 + + 该警报涉及2023年10月在巴西、2023年10月在大不列颠及北爱尔兰联合王国和2023年12月在美利坚合众国发现的3批伪造的司美格鲁肽类药物产品(具体品牌是Ozempic)。世卫组织全球监测和监督系统观察到,自2022年以来,关于伪造的司美格鲁肽产品的报告在所有地理区域都有所增加。这是世卫组织在确认部分报告后发布的首份正式通告。 + + 世卫组织基本药物和卫生产品部门助理总干事Yukiko Nakatani博士说:“世卫组织建议卫生保健专业人员、监管机构和公众注意这些伪造的药品批次。我们呼吁利益攸关方停止使用任何可疑药物,并向有关机构报告”。 + + 供应短缺和伪造增多 + + 司美格鲁肽,包括被伪造的特定品牌产品,是为2型糖尿病患者开具的处方药,以降低其血糖水平。司美格鲁肽还可降低心血管事件的风险。大多数司美格鲁肽产品必须每周进行皮下注射,但也有可每天口服的片剂。这些药物经证明除了降低血糖水平外还能抑制食欲,因此在一些国家越来越多地被用于减肥。 + + 世卫组织一直在注意对这些药物越来越多的需求以及关于伪造的报告。这些伪造产品可能对人们的健康产生有害影响;如果伪造的药物产品不含必要的原料成分,可能会使血糖水平或体重失控从而导致并发症。在另一些情况下,注射装置中可能含有另一种未申明的活性成分,例如胰岛素,从而导致不可预测的健康风险或并发症。 + + 由于司美格鲁肽目前费用高昂,因此世卫组织未将其列入用于糖尿病管理的推荐疗法。费用障碍使得不宜通过公共卫生方法来提供这些产品,因为公共卫生方法旨在确保尽可能广泛地向人口提供药物,并在最佳护理标准与资源有限环境中可大规模实行的标准之间取得平衡。此外,还有更多负担得起的糖尿病治疗方法,对血糖和心血管风险的影响与司美格鲁肽相似。 + + 世卫组织目前正在制定一份快速建议指南,涉及可能使用包括司美格鲁肽在内的GLP-1RAs治疗成人肥胖症,并将其作为更全面的护理模式的一部分。术语GLP-1 RA代表胰高血糖素样肽-1受体激动剂,其中包括司美格鲁肽,属于一类用于糖尿病治疗的药物,可降低血糖和帮助减肥。 + + 个体行动 + + 为保护自己免受伪造药物及其有害影响,使用这些产品的患者可以采取措施,例如使用执业医生开具的处方购买药物,并避免从不熟悉或未经验证的来源,例如从网上购买药物。 + + 人们在购买药物时应始终检查其包装和有效期,并按照规定使用产品。对于注射用司美格鲁肽,患者应确保将其储存在冰箱中。所有关于伪造药品的通报均可通过rapidalert@who.int发送给世卫组织。 ].flatMap { $0 } let systemMessages = [chatMessage( From b145bfbd8e335dede5028d665a0c54a1fc03cc2c Mon Sep 17 00:00:00 2001 From: Jerry Date: Sat, 13 Jul 2024 19:08:23 +0800 Subject: [PATCH 12/18] fix: extraneous prompt --- Easydict/Swift/Service/OpenAI/Prompt.swift | 24 +--------------------- 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/Easydict/Swift/Service/OpenAI/Prompt.swift b/Easydict/Swift/Service/OpenAI/Prompt.swift index 3bce76ac5..4e1295f79 100644 --- a/Easydict/Swift/Service/OpenAI/Prompt.swift +++ b/Easydict/Swift/Service/OpenAI/Prompt.swift @@ -103,29 +103,7 @@ extension LLMStreamService { chatMessagePair( userContent: "Summarize the following 简体中文 text: \"\"\"新数据显示,全球近三分之一(31%)的成年人(约18亿人)在2022年未达到所建议的身体活动水平。研究结果指出,成年人缺乏身体活动的趋势令人担忧。2010年至2022年期间,成年人缺乏身体活动百分比增加了大约5个百分点。如果这一趋势继续下去,预计到2030年,缺乏身体活动百分比将进一步上升到35%。目前全世界距离实现到2030年减少缺乏身体活动率的全球目标还有很大差距。世界卫生组织(世卫组织)建议成年人每周进行150分钟的中等强度身体活动或75分钟的高强度身体活动。缺乏身体活动会加剧成年人患心血管疾病(如心脏病和中风)、2型糖尿病、痴呆症以及乳腺癌和结肠癌的风险。这项研究由世卫组织研究人员与学术界同事共同开展,研究结果发表在《柳叶刀全球健康》杂志上。世卫组织总干事谭德塞博士说,“这些新研究成果显示,由于未能增加身体活动,人们未能抓住机会减少癌症和心脏病以及改善精神健康和福祉。我们必须重申承诺,努力提高身体活动水平,大力采取果断行动,包括加强政策和增加资金,以扭转这一令人担忧的趋势”。高收入亚太地区(48%)和南亚(45%)缺乏身体活动率最高。其他地区的缺乏身体活动水平从高收入西方国家的28%到大洋洲的14%不等。令人关切的是,在不同性别之间和不同年龄之间仍然存在差距。与男性相比,全球女性缺乏身体活动情况仍较普遍,缺乏活动率为34%,男性为29%。在一些国家,这一差距达20个百分点。此外,与其他成年人群相比,60岁以上的人身体活动较少,因此,我们需要促进老年人开展更多身体活动。\"\"\" Your summary should also be in 简体中文.", assistantContent: "2022年,全球31%(约18亿人)的成年人未达到建议的身体活动水平,2010年至2022年间增加了5个百分点。如果持续下去,2030年将升至35%。世卫组织建议每周150分钟中等强度或75分钟高强度活动,缺乏活动增加多种疾病风险。世卫组织总干事谭德塞博士呼吁加强政策和资金投入以提高身体活动水平。高收入亚太地区(48%)和南亚(45%)的缺乏活动率最高,其他地区从高收入西方国家的28%到大洋洲的14%不等。女性(34%)和老年人缺乏活动较多,男性为29%。性别差距在一些国家达20个百分点,60岁以上人群活动较少。" - ),世卫组织对用于治疗糖尿病和减肥的伪造药物发出警告 - Jun 20, 2024 at 21:00 - 世界卫生组织(世卫组织)发布了关于伪造司美格鲁肽的医疗产品警报,一些国家使用这种药物治疗2型糖尿病和肥胖症。 - - 该警报涉及2023年10月在巴西、2023年10月在大不列颠及北爱尔兰联合王国和2023年12月在美利坚合众国发现的3批伪造的司美格鲁肽类药物产品(具体品牌是Ozempic)。世卫组织全球监测和监督系统观察到,自2022年以来,关于伪造的司美格鲁肽产品的报告在所有地理区域都有所增加。这是世卫组织在确认部分报告后发布的首份正式通告。 - - 世卫组织基本药物和卫生产品部门助理总干事Yukiko Nakatani博士说:“世卫组织建议卫生保健专业人员、监管机构和公众注意这些伪造的药品批次。我们呼吁利益攸关方停止使用任何可疑药物,并向有关机构报告”。 - - 供应短缺和伪造增多 - - 司美格鲁肽,包括被伪造的特定品牌产品,是为2型糖尿病患者开具的处方药,以降低其血糖水平。司美格鲁肽还可降低心血管事件的风险。大多数司美格鲁肽产品必须每周进行皮下注射,但也有可每天口服的片剂。这些药物经证明除了降低血糖水平外还能抑制食欲,因此在一些国家越来越多地被用于减肥。 - - 世卫组织一直在注意对这些药物越来越多的需求以及关于伪造的报告。这些伪造产品可能对人们的健康产生有害影响;如果伪造的药物产品不含必要的原料成分,可能会使血糖水平或体重失控从而导致并发症。在另一些情况下,注射装置中可能含有另一种未申明的活性成分,例如胰岛素,从而导致不可预测的健康风险或并发症。 - - 由于司美格鲁肽目前费用高昂,因此世卫组织未将其列入用于糖尿病管理的推荐疗法。费用障碍使得不宜通过公共卫生方法来提供这些产品,因为公共卫生方法旨在确保尽可能广泛地向人口提供药物,并在最佳护理标准与资源有限环境中可大规模实行的标准之间取得平衡。此外,还有更多负担得起的糖尿病治疗方法,对血糖和心血管风险的影响与司美格鲁肽相似。 - - 世卫组织目前正在制定一份快速建议指南,涉及可能使用包括司美格鲁肽在内的GLP-1RAs治疗成人肥胖症,并将其作为更全面的护理模式的一部分。术语GLP-1 RA代表胰高血糖素样肽-1受体激动剂,其中包括司美格鲁肽,属于一类用于糖尿病治疗的药物,可降低血糖和帮助减肥。 - - 个体行动 - - 为保护自己免受伪造药物及其有害影响,使用这些产品的患者可以采取措施,例如使用执业医生开具的处方购买药物,并避免从不熟悉或未经验证的来源,例如从网上购买药物。 - - 人们在购买药物时应始终检查其包装和有效期,并按照规定使用产品。对于注射用司美格鲁肽,患者应确保将其储存在冰箱中。所有关于伪造药品的通报均可通过rapidalert@who.int发送给世卫组织。 + ), ].flatMap { $0 } let systemMessages = [chatMessage( From 57cf75e64b8d2991b5bcde05e5e105c41ef2d776 Mon Sep 17 00:00:00 2001 From: tisfeng Date: Sat, 13 Jul 2024 22:04:36 +0800 Subject: [PATCH 13/18] fix: use first preferred langauge to summarize text --- Easydict/Swift/Service/OpenAI/Prompt.swift | 38 ++++++++-------------- 1 file changed, 14 insertions(+), 24 deletions(-) diff --git a/Easydict/Swift/Service/OpenAI/Prompt.swift b/Easydict/Swift/Service/OpenAI/Prompt.swift index 4e1295f79..4e942ff86 100644 --- a/Easydict/Swift/Service/OpenAI/Prompt.swift +++ b/Easydict/Swift/Service/OpenAI/Prompt.swift @@ -31,8 +31,13 @@ extension LLMStreamService { "Polish the following \(sourceLanguage.queryLanguageName) text to improve its clarity, coherence, grammar, and overall quality while maintaining the original meaning and intent: \"\"\"\(text)\"\"\"" } - private func summaryPrompt(text: String, in sourceLanguage: Language) -> String { - "Summarize the following \(sourceLanguage.queryLanguageName) text, capturing the main points, key details, and overall essence while maintaining clarity and accuracy: \"\"\"\(text)\"\"\" Your summary should also be in \(sourceLanguage.queryLanguageName)." + private func summaryPrompt( + text: String, + sourceLanguage: Language, + answerLanguage: Language + ) + -> String { + "Using \(answerLanguage.rawValue) to summarize the following \(sourceLanguage.queryLanguageName) text: \"\"\"\(text)\"\"\"." } func polishingMessages(_ derivParam: ChatQueryParam) -> [[String: String]] { @@ -76,34 +81,19 @@ extension LLMStreamService { func summaryMessages(_ derivParam: ChatQueryParam) -> [[String: String]] { let (text, sourceLanguage, _, _, _) = derivParam.unpack() + let answerLanguage = Configuration.shared.firstLanguage + let prompt = summaryPrompt(text: text, sourceLanguage: sourceLanguage, answerLanguage: answerLanguage) - let prompt = summaryPrompt(text: text, in: sourceLanguage) - - let englishFewShot = [ + let fewShot = [ chatMessagePair( - userContent: "Summarize the following English text: \"\"\"The quick brown fox jumps over the lazy dog. The fox is very quick and agile, making it difficult for the dog to catch up. Despite several attempts, the dog remains lazy and doesn't put in much effort to chase the fox.\"\"\" Your summary should also be in English.", + userContent: "Using English to summarize the following English text: \"\"\"The quick brown fox jumps over the lazy dog. The fox is very quick and agile, making it difficult for the dog to catch up. Despite several attempts, the dog remains lazy and doesn't put in much effort to chase the fox.\"\"\" Your summary should also be in English.", assistantContent: "The quick and agile fox jumps over the lazy dog, who remains lazy and doesn't put in much effort to chase the fox." ), chatMessagePair( - userContent: "Summarize the following English text: \"\"\"In a faraway land, there was a kingdom ruled by a wise king. The king was known for his fairness and kindness. He ensured that all his subjects were treated equally and that justice was served. Under his rule, the kingdom prospered and the people lived in peace and harmony.\"\"\" Your summary should also be in English.", - assistantContent: "A wise and fair king ruled a prosperous kingdom where justice was served and people lived in peace and harmony." - ), - chatMessagePair( - userContent: "Summarize the following English text: \"\"\"The new restaurant in town has become very popular due to its delicious food and excellent service. Many people visit the restaurant every day to enjoy the meals and the pleasant atmosphere. The chef is renowned for his culinary skills and the staff are very friendly.\"\"\" Your summary should also be in English.", - assistantContent: "The new restaurant is popular for its delicious food, excellent service, renowned chef, and friendly staff." - ), - chatMessagePair( - userContent: "Summarize the following 简体中文 text: \"\"\"联合国在西非地区的最高官员周五表示,马里、布基纳法索和尼日尔决定退出西非国家经济共同体,将全面破坏地区关系,而此时恐怖主义和跨国有组织犯罪仍然对该地区构成普遍威胁。联合国西非和萨赫勒办事处负责人莱昂纳多•桑托斯•西芒向安理会表示,放弃西非经共体 将使三个军方领导的政府放弃关键利益,包括地区一体化、行动自由、安全合作和一体化的地区经济,这既伤害了他们自己,也伤害了西非经共体的其他成员。在高级军官分别于 2021 年、2022 年和 2023 年发动军事接管后,这三个过渡政府断绝了与西非经共体的关系。西芒说,军事领导人因此推迟了恢复宪政的时间,并引发了对长期不确定性的恐惧,因为公民空间继续缩小。\"\"\" Your summary should also be in 简体中文.", + userContent: "Using Simplified-Chinese to summarize the following text: \"\"\"联合国在西非地区的最高官员周五表示,马里、布基纳法索和尼日尔决定退出西非国家经济共同体,将全面破坏地区关系,而此时恐怖主义和跨国有组织犯罪仍然对该地区构成普遍威胁。联合国西非和萨赫勒办事处负责人莱昂纳多•桑托斯•西芒向安理会表示,放弃西非经共体 将使三个军方领导的政府放弃关键利益,包括地区一体化、行动自由、安全合作和一体化的地区经济,这既伤害了他们自己,也伤害了西非经共体的其他成员。在高级军官分别于 2021 年、2022 年和 2023 年发动军事接管后,这三个过渡政府断绝了与西非经共体的关系。西芒说,军事领导人因此推迟了恢复宪政的时间,并引发了对长期不确定性的恐惧,因为公民空间继续缩小。", assistantContent: "马里、布基纳法索和尼日尔退出西非国家经济共同体,将严重破坏地区关系,尤其是在恐怖主义和跨国有组织犯罪仍威胁该地区的情况下。联合国官员西芒指出,这一决定将使这三个国家失去地区一体化、安全合作和经济利益,推迟恢复宪政,并加剧长期不确定性。" ), - chatMessagePair( - userContent: "Summarize the following 简体中文 text: \"\"\"联合国秘书长古特雷斯在为世界人口日的致辞中表示,为了实现社会边缘人群的权利和选择,我们必须将他们算在内——因为每个人都很重要。他说:“我们丰富多彩的人类织锦的强度取决于它最薄弱的丝线。当数据和其他系统为边缘人群服务时,它们就为所有人服务了。这就是我们加速所有人进步的方式。” 为了更深入研究这些人口数据,自1951年起,联合国经济和社会事务部已经出版了28版《世界人口展望》报告,该报告提供了237个国家从1950年至2024年的最新人口数据,以及直至2100年的预测数据。《世界人口展望》对监测可持续发展目标至关重要,大约四分之一的指标依赖于其数据。报告指出,世界总体生育率正在下降,妇女平均生育子女数比1990年左右减少了一个。超过半数的国家和地区,女性平均生育子女数低于2.1个,这是维持人口稳定的水平。 与此同时,将近五分之一的国家和地区,包括中国、意大利、韩国和西班牙,现在面临“超低生育率”,女性一生平均生育子女数少于1.4个。\"\"\" Your summary should also be in 简体中文.", - assistantContent: "联合国秘书长古特雷斯在世界人口日致辞中强调,包容社会边缘人群至关重要。自1951年以来,联合国经济和社会事务部发布了28版《世界人口展望》,提供237个国家从1950年至2024年的数据及至2100年的预测。报告显示,全球生育率下降,女性平均生育子女数比1990年减少一个。超过半数国家和地区生育率低于2.1,近五分之一(如中国、意大利、韩国、西班牙)面临“超低生育率”,生育率低于1.4。" - ), - chatMessagePair( - userContent: "Summarize the following 简体中文 text: \"\"\"新数据显示,全球近三分之一(31%)的成年人(约18亿人)在2022年未达到所建议的身体活动水平。研究结果指出,成年人缺乏身体活动的趋势令人担忧。2010年至2022年期间,成年人缺乏身体活动百分比增加了大约5个百分点。如果这一趋势继续下去,预计到2030年,缺乏身体活动百分比将进一步上升到35%。目前全世界距离实现到2030年减少缺乏身体活动率的全球目标还有很大差距。世界卫生组织(世卫组织)建议成年人每周进行150分钟的中等强度身体活动或75分钟的高强度身体活动。缺乏身体活动会加剧成年人患心血管疾病(如心脏病和中风)、2型糖尿病、痴呆症以及乳腺癌和结肠癌的风险。这项研究由世卫组织研究人员与学术界同事共同开展,研究结果发表在《柳叶刀全球健康》杂志上。世卫组织总干事谭德塞博士说,“这些新研究成果显示,由于未能增加身体活动,人们未能抓住机会减少癌症和心脏病以及改善精神健康和福祉。我们必须重申承诺,努力提高身体活动水平,大力采取果断行动,包括加强政策和增加资金,以扭转这一令人担忧的趋势”。高收入亚太地区(48%)和南亚(45%)缺乏身体活动率最高。其他地区的缺乏身体活动水平从高收入西方国家的28%到大洋洲的14%不等。令人关切的是,在不同性别之间和不同年龄之间仍然存在差距。与男性相比,全球女性缺乏身体活动情况仍较普遍,缺乏活动率为34%,男性为29%。在一些国家,这一差距达20个百分点。此外,与其他成年人群相比,60岁以上的人身体活动较少,因此,我们需要促进老年人开展更多身体活动。\"\"\" Your summary should also be in 简体中文.", - assistantContent: "2022年,全球31%(约18亿人)的成年人未达到建议的身体活动水平,2010年至2022年间增加了5个百分点。如果持续下去,2030年将升至35%。世卫组织建议每周150分钟中等强度或75分钟高强度活动,缺乏活动增加多种疾病风险。世卫组织总干事谭德塞博士呼吁加强政策和资金投入以提高身体活动水平。高收入亚太地区(48%)和南亚(45%)的缺乏活动率最高,其他地区从高收入西方国家的28%到大洋洲的14%不等。女性(34%)和老年人缺乏活动较多,男性为29%。性别差距在一些国家达20个百分点,60岁以上人群活动较少。" - ), + ].flatMap { $0 } let systemMessages = [chatMessage( @@ -112,7 +102,7 @@ extension LLMStreamService { )] var messages = systemMessages - messages.append(contentsOf: englishFewShot) + messages.append(contentsOf: fewShot) let userMessages = [ [ From 91ca4c077a8c6fb01487921d3e4637a905fac47f Mon Sep 17 00:00:00 2001 From: tisfeng Date: Sat, 13 Jul 2024 22:53:14 +0800 Subject: [PATCH 14/18] feat: set AI tool service usage status to alway off by default --- Easydict/Swift/Service/AITool/AIToolService.swift | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Easydict/Swift/Service/AITool/AIToolService.swift b/Easydict/Swift/Service/AITool/AIToolService.swift index 62d2f1046..c047a5552 100644 --- a/Easydict/Swift/Service/AITool/AIToolService.swift +++ b/Easydict/Swift/Service/AITool/AIToolService.swift @@ -6,11 +6,13 @@ // Copyright © 2024 izual. All rights reserved. // +import Defaults import Foundation /// A class used for AI Tools such as summary and polishing -/// Based on `BuiltInAIService` and takes `llama3-70b-8192` as the LLM class AIToolService: BuiltInAIService { + // MARK: Public + public override func configurationListItems() -> Any { StreamConfigurationView( service: self, @@ -25,4 +27,10 @@ class AIToolService: BuiltInAIService { showUsageStatusPicker: true ) } + + // MARK: Internal + + override var serviceUsageStatusKey: Defaults.Key { + serviceDefaultsKey(.serviceUsageStatus, defaultValue: .alwaysOff) + } } From 0208daa9a13468a39d9e66d96391de494c3a330c Mon Sep 17 00:00:00 2001 From: tisfeng Date: Sun, 14 Jul 2024 12:34:41 +0800 Subject: [PATCH 15/18] fix: add missing en localization --- Easydict/App/Localizable.xcstrings | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Easydict/App/Localizable.xcstrings b/Easydict/App/Localizable.xcstrings index 2551207a0..e82e2da19 100644 --- a/Easydict/App/Localizable.xcstrings +++ b/Easydict/App/Localizable.xcstrings @@ -3852,6 +3852,12 @@ }, "summary_service" : { "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Summary" + } + }, "zh-Hans" : { "stringUnit" : { "state" : "translated", From 881f9f0f80689da1bc71912ed2ada4de1cfd6a32 Mon Sep 17 00:00:00 2001 From: Jerry <89069957+Jerry23011@users.noreply.github.com> Date: Mon, 15 Jul 2024 09:49:01 +0800 Subject: [PATCH 16/18] fix: icon size for polishing and grammar service --- .../Polishing.imageset/Polishing.png | Bin 4599 -> 6279 bytes .../Polishing.imageset/Polishing@2x.png | Bin 11251 -> 15487 bytes .../service-icon/Summary.imageset/Grammar.png | Bin 4837 -> 6264 bytes .../Summary.imageset/Grammar@2x.png | Bin 12528 -> 16752 bytes 4 files changed, 0 insertions(+), 0 deletions(-) diff --git a/Easydict/App/Assets.xcassets/service-icon/Polishing.imageset/Polishing.png b/Easydict/App/Assets.xcassets/service-icon/Polishing.imageset/Polishing.png index f88e31c501cb90c95cd3b787663b7f84221eb296..ebfc2afd763f9f548f29b856fb4ef13927a7b15a 100644 GIT binary patch delta 5239 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 U$>^uCKmY&$07*qoM6N<$g6PKD$p8QV diff --git a/Easydict/App/Assets.xcassets/service-icon/Polishing.imageset/Polishing@2x.png b/Easydict/App/Assets.xcassets/service-icon/Polishing.imageset/Polishing@2x.png index 6468746cf6b73f63b4695cf4ddcfc002bf491a08..ef5da483c66890cb76206149a68656ce43c0ad09 100644 GIT binary patch delta 14518 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 delta 10248 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 IWvwFrAM6P#umAu6 diff --git a/Easydict/App/Assets.xcassets/service-icon/Summary.imageset/Grammar.png b/Easydict/App/Assets.xcassets/service-icon/Summary.imageset/Grammar.png index 1870dd5a2948534f1f1e273d5a7f940e3adfecd9..34b499938968c5620dda4f200584b29d3a0fcc87 100644 GIT binary patch delta 5224 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 i=XGGZ^efRN+y4XF_~Sh36r^qd0000MdRTRO- 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 A@Bjb+ diff --git a/Easydict/App/Assets.xcassets/service-icon/Summary.imageset/Grammar@2x.png b/Easydict/App/Assets.xcassets/service-icon/Summary.imageset/Grammar@2x.png index b8afd763d0a6c8e2499774c278670544f55551e5..c579c34bf724ef68167c7b080277ee35d4a2524f 100644 GIT binary patch delta 15793 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 z Date: Mon, 15 Jul 2024 10:01:42 +0800 Subject: [PATCH 17/18] fix: format fewShots to conform to original prompt --- Easydict/Swift/Service/OpenAI/Prompt.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Easydict/Swift/Service/OpenAI/Prompt.swift b/Easydict/Swift/Service/OpenAI/Prompt.swift index 4e942ff86..cf356f524 100644 --- a/Easydict/Swift/Service/OpenAI/Prompt.swift +++ b/Easydict/Swift/Service/OpenAI/Prompt.swift @@ -86,11 +86,11 @@ extension LLMStreamService { let fewShot = [ chatMessagePair( - userContent: "Using English to summarize the following English text: \"\"\"The quick brown fox jumps over the lazy dog. The fox is very quick and agile, making it difficult for the dog to catch up. Despite several attempts, the dog remains lazy and doesn't put in much effort to chase the fox.\"\"\" Your summary should also be in English.", + userContent: "Using English to summarize the following English text: \"\"\"The quick brown fox jumps over the lazy dog. The fox is very quick and agile, making it difficult for the dog to catch up. Despite several attempts, the dog remains lazy and doesn't put in much effort to chase the fox.\"\"\".", assistantContent: "The quick and agile fox jumps over the lazy dog, who remains lazy and doesn't put in much effort to chase the fox." ), chatMessagePair( - userContent: "Using Simplified-Chinese to summarize the following text: \"\"\"联合国在西非地区的最高官员周五表示,马里、布基纳法索和尼日尔决定退出西非国家经济共同体,将全面破坏地区关系,而此时恐怖主义和跨国有组织犯罪仍然对该地区构成普遍威胁。联合国西非和萨赫勒办事处负责人莱昂纳多•桑托斯•西芒向安理会表示,放弃西非经共体 将使三个军方领导的政府放弃关键利益,包括地区一体化、行动自由、安全合作和一体化的地区经济,这既伤害了他们自己,也伤害了西非经共体的其他成员。在高级军官分别于 2021 年、2022 年和 2023 年发动军事接管后,这三个过渡政府断绝了与西非经共体的关系。西芒说,军事领导人因此推迟了恢复宪政的时间,并引发了对长期不确定性的恐惧,因为公民空间继续缩小。", + userContent: "Using Simplified-Chinese to summarize the following text: \"\"\"联合国在西非地区的最高官员周五表示,马里、布基纳法索和尼日尔决定退出西非国家经济共同体,将全面破坏地区关系,而此时恐怖主义和跨国有组织犯罪仍然对该地区构成普遍威胁。联合国西非和萨赫勒办事处负责人莱昂纳多•桑托斯•西芒向安理会表示,放弃西非经共体 将使三个军方领导的政府放弃关键利益,包括地区一体化、行动自由、安全合作和一体化的地区经济,这既伤害了他们自己,也伤害了西非经共体的其他成员。在高级军官分别于 2021 年、2022 年和 2023 年发动军事接管后,这三个过渡政府断绝了与西非经共体的关系。西芒说,军事领导人因此推迟了恢复宪政的时间,并引发了对长期不确定性的恐惧,因为公民空间继续缩小。\"\"\".", assistantContent: "马里、布基纳法索和尼日尔退出西非国家经济共同体,将严重破坏地区关系,尤其是在恐怖主义和跨国有组织犯罪仍威胁该地区的情况下。联合国官员西芒指出,这一决定将使这三个国家失去地区一体化、安全合作和经济利益,推迟恢复宪政,并加剧长期不确定性。" ), From 393144546d9404d6ad54a3a1108cee989b2489e6 Mon Sep 17 00:00:00 2001 From: Jerry <89069957+Jerry23011@users.noreply.github.com> Date: Tue, 16 Jul 2024 14:50:56 +0800 Subject: [PATCH 18/18] perf(UI): add new icon for summary service --- .../service-icon/Summary.imageset/Contents.json | 4 ++-- .../service-icon/Summary.imageset/Grammar.png | Bin 6264 -> 0 bytes .../Summary.imageset/Grammar@2x.png | Bin 16752 -> 0 bytes .../service-icon/Summary.imageset/Summary.png | Bin 0 -> 5568 bytes .../Summary.imageset/Summary@2x.png | Bin 0 -> 14709 bytes 5 files changed, 2 insertions(+), 2 deletions(-) delete mode 100644 Easydict/App/Assets.xcassets/service-icon/Summary.imageset/Grammar.png delete mode 100644 Easydict/App/Assets.xcassets/service-icon/Summary.imageset/Grammar@2x.png create mode 100644 Easydict/App/Assets.xcassets/service-icon/Summary.imageset/Summary.png create mode 100644 Easydict/App/Assets.xcassets/service-icon/Summary.imageset/Summary@2x.png diff --git a/Easydict/App/Assets.xcassets/service-icon/Summary.imageset/Contents.json b/Easydict/App/Assets.xcassets/service-icon/Summary.imageset/Contents.json index 3404b6480..477ea0224 100644 --- a/Easydict/App/Assets.xcassets/service-icon/Summary.imageset/Contents.json +++ b/Easydict/App/Assets.xcassets/service-icon/Summary.imageset/Contents.json @@ -1,12 +1,12 @@ { "images" : [ { - "filename" : "Grammar.png", + "filename" : "Summary.png", "idiom" : "universal", "scale" : "1x" }, { - "filename" : "Grammar@2x.png", + "filename" : "Summary@2x.png", "idiom" : "universal", "scale" : "2x" }, diff --git a/Easydict/App/Assets.xcassets/service-icon/Summary.imageset/Grammar.png b/Easydict/App/Assets.xcassets/service-icon/Summary.imageset/Grammar.png deleted file mode 100644 index 34b499938968c5620dda4f200584b29d3a0fcc87..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6264 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 diff --git a/Easydict/App/Assets.xcassets/service-icon/Summary.imageset/Grammar@2x.png b/Easydict/App/Assets.xcassets/service-icon/Summary.imageset/Grammar@2x.png deleted file mode 100644 index c579c34bf724ef68167c7b080277ee35d4a2524f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16752 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 T+S=-)e=qf6S9G3h+eZEisPC#R literal 0 HcmV?d00001 diff --git a/Easydict/App/Assets.xcassets/service-icon/Summary.imageset/Summary@2x.png b/Easydict/App/Assets.xcassets/service-icon/Summary.imageset/Summary@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..436603235bc7b071b617e1b539815cfde17ff073 GIT binary patch literal 14709 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 Z8tgeFYJ^#q_V+J`(&F-BH6n(A{|D5v(=Px3 literal 0 HcmV?d00001