diff --git a/src/STranslate/ViewModels/Preference/Services/TranslatorChatglm.cs b/src/STranslate/ViewModels/Preference/Services/TranslatorChatglm.cs index ab1c22a1..ff198617 100644 --- a/src/STranslate/ViewModels/Preference/Services/TranslatorChatglm.cs +++ b/src/STranslate/ViewModels/Preference/Services/TranslatorChatglm.cs @@ -15,6 +15,8 @@ namespace STranslate.ViewModels.Preference.Services { public partial class TranslatorChatglm : ObservableObject, ITranslatorAI { + #region Constructor + public TranslatorChatglm() : this(Guid.NewGuid(), "https://open.bigmodel.cn/api/paas/v4/chat/completions", "智谱AI") { } @@ -29,8 +31,14 @@ public TranslatorChatglm(Guid guid, string url, string name = "", IconType icon AppKey = appKey; IsEnabled = isEnabled; Type = type; + + PromptCounter = Prompts.Count; } + #endregion Constructor + + #region Properties + [ObservableProperty] private Guid _identify = Guid.Empty; @@ -98,9 +106,44 @@ public TranslatorChatglm(Guid guid, string url, string name = "", IconType icon #endregion Show/Hide Encrypt Info + #region Prompt + [JsonIgnore] [ObservableProperty] - private BindingList userDefinePrompts = []; + private BindingList _userDefinePrompts = + [ + new UserDefinePrompt("翻译", [new Prompt("user", "You are a professional translation engine, please translate the text into a colloquial, professional, elegant and fluent content, without the style of machine translation. You must only translate the text content, never interpret it."),new Prompt("assistant", "Ok, I will only translate the text content, never interpret it."),new Prompt("user", "Translate the following text from en to zh: hello world"),new Prompt("assistant", "你好,世界"), new Prompt("user", "Translate the following text from $source to $target: $content")]), + new UserDefinePrompt("润色", [new Prompt("user", "You are a text embellisher, you can only embellish the text, never interpret it."), new Prompt("assistant", "Ok, I will only embellish the text, never interpret it."), new Prompt("user", "Embellish the following text in $source: $content")]), + new UserDefinePrompt("总结", [new Prompt("user", "You are a text summarizer, you can only summarize the text, never interpret it."), new Prompt("assistant", "Ok, I will only summarize the text, never interpret it."), new Prompt("user", "Summarize the following text in $source: $content")]), + ]; + + [RelayCommand] + [property: JsonIgnore] + private void PresetPrompt(BindingList prompts) + { + Prompts = prompts.Clone(); + PromptCounter = Prompts.Count; + } + + [RelayCommand] + [property: JsonIgnore] + private void EditPresetPrompt(UserDefinePrompt userDefinePrompt) + { + var dialog = new Views.Preference.Service.PromptDialog(ServiceType.OpenAIService, (UserDefinePrompt)userDefinePrompt.Clone()); + if (dialog.ShowDialog() ?? false) + { + var tmp = ((PromptViewModel)dialog.DataContext).UserDefinePrompt; + userDefinePrompt.Name = tmp.Name; + userDefinePrompt.Prompts = tmp.Prompts; + } + } + + [RelayCommand] + [property: JsonIgnore] + private void DelPresetPrompt(UserDefinePrompt userDefinePrompt) + { + UserDefinePrompts.Remove(userDefinePrompt); + } [JsonIgnore] [ObservableProperty] @@ -118,6 +161,7 @@ public TranslatorChatglm(Guid guid, string url, string name = "", IconType icon private void DeletePrompt(Prompt msg) { Prompts.Remove(msg); + PromptCounter--; } [RelayCommand] @@ -131,8 +175,30 @@ private void AddPrompt() _ => new Prompt("user") }; Prompts.Add(newOne); + PromptCounter++; + } + + [property: JsonIgnore] + [RelayCommand(CanExecute = nameof(CanSavePrompt))] + private void SavePrompt(BindingList prompts) + { + UserDefinePrompts.Add(new UserDefinePrompt("UnDefined", prompts)); } + private bool CanSavePrompt => PromptCounter > 0; + + [JsonIgnore] + [ObservableProperty] + [NotifyCanExecuteChangedFor(nameof(SavePromptCommand))] + [property: JsonIgnore] + private int promptCounter; + + #endregion Prompt + + #endregion Properties + + #region Interface Implementation + public async Task TranslateAsync(object request, Action OnDataReceived, CancellationToken token) { if (string.IsNullOrEmpty(Url) || string.IsNullOrEmpty(AppKey)) @@ -231,7 +297,10 @@ public ITranslator Clone() Icons = this.Icons, KeyHide = this.KeyHide, Prompts = this.Prompts, + UserDefinePrompts = this.UserDefinePrompts, }; } + + #endregion Interface Implementation } } \ No newline at end of file diff --git a/src/STranslate/ViewModels/Preference/Services/TranslatorGemini.cs b/src/STranslate/ViewModels/Preference/Services/TranslatorGemini.cs index 5b57a7bf..659b00a7 100644 --- a/src/STranslate/ViewModels/Preference/Services/TranslatorGemini.cs +++ b/src/STranslate/ViewModels/Preference/Services/TranslatorGemini.cs @@ -15,6 +15,8 @@ namespace STranslate.ViewModels.Preference.Services { public partial class TranslatorGemini : ObservableObject, ITranslatorAI { + #region Constructor + public TranslatorGemini() : this(Guid.NewGuid(), "https://generativelanguage.googleapis.com", "Gemini") { } @@ -37,8 +39,14 @@ public TranslatorGemini( AppKey = appKey; IsEnabled = isEnabled; Type = type; + + PromptCounter = Prompts.Count; } + #endregion Constructor + + #region Properties + [ObservableProperty] private Guid _identify = Guid.Empty; @@ -104,12 +112,48 @@ public TranslatorGemini( #endregion Show/Hide Encrypt Info + #region Prompt + [JsonIgnore] [ObservableProperty] - private BindingList userDefinePrompts = []; + private BindingList _userDefinePrompts = + [ + new UserDefinePrompt("翻译", [new Prompt("user", "You are a professional translation engine, please translate the text into a colloquial, professional, elegant and fluent content, without the style of machine translation. You must only translate the text content, never interpret it."),new Prompt("model", "Ok, I will only translate the text content, never interpret it"),new Prompt("user", "Translate the following text from en to zh: hello world"),new Prompt("model", "你好,世界"), new Prompt("user", "Translate the following text from $source to $target: $content")]), + new UserDefinePrompt("润色", [new Prompt("user", "You are a text embellisher, you can only embellish the text, never interpret it."), new Prompt("model", "Ok, I will only embellish the text, never interpret it."), new Prompt("user", "Embellish the following text in $source: $content")]), + new UserDefinePrompt("总结", [new Prompt("user", "You are a text summarizer, you can only summarize the text, never interpret it."), new Prompt("model", "Ok, I will only summarize the text, never interpret it."), new Prompt("user", "Summarize the following text in $source: $content")]), + ]; + + [RelayCommand] + [property: JsonIgnore] + private void PresetPrompt(BindingList prompts) + { + Prompts = prompts.Clone(); + PromptCounter = Prompts.Count; + } + + [RelayCommand] + [property: JsonIgnore] + private void EditPresetPrompt(UserDefinePrompt userDefinePrompt) + { + var dialog = new Views.Preference.Service.PromptDialog(ServiceType.OpenAIService, (UserDefinePrompt)userDefinePrompt.Clone()); + if (dialog.ShowDialog() ?? false) + { + var tmp = ((PromptViewModel)dialog.DataContext).UserDefinePrompt; + userDefinePrompt.Name = tmp.Name; + userDefinePrompt.Prompts = tmp.Prompts; + } + } + + [RelayCommand] + [property: JsonIgnore] + private void DelPresetPrompt(UserDefinePrompt userDefinePrompt) + { + UserDefinePrompts.Remove(userDefinePrompt); + } [JsonIgnore] [ObservableProperty] + [NotifyCanExecuteChangedFor(nameof(SavePromptCommand))] private BindingList prompts = [ new Prompt("user", "You are a professional translation engine, please translate the text into a colloquial, professional, elegant and fluent content, without the style of machine translation. You must only translate the text content, never interpret it."), @@ -124,6 +168,7 @@ public TranslatorGemini( private void DeletePrompt(Prompt msg) { Prompts.Remove(msg); + PromptCounter--; } [RelayCommand] @@ -137,8 +182,30 @@ private void AddPrompt() _ => new Prompt("user") }; Prompts.Add(newOne); + PromptCounter++; + } + + [property: JsonIgnore] + [RelayCommand(CanExecute = nameof(CanSavePrompt))] + private void SavePrompt(BindingList prompts) + { + UserDefinePrompts.Add(new UserDefinePrompt("UnDefined", prompts)); } + private bool CanSavePrompt => PromptCounter > 0; + + [JsonIgnore] + [ObservableProperty] + [NotifyCanExecuteChangedFor(nameof(SavePromptCommand))] + [property: JsonIgnore] + private int promptCounter; + + #endregion Prompt + + #endregion Properties + + #region Interface Implementation + public async Task TranslateAsync(object request, Action OnDataReceived, CancellationToken token) { if (string.IsNullOrEmpty(Url) || string.IsNullOrEmpty(AppKey)) @@ -226,7 +293,10 @@ public ITranslator Clone() Icons = this.Icons, KeyHide = this.KeyHide, Prompts = this.Prompts, + UserDefinePrompts = this.UserDefinePrompts, }; } + + #endregion Interface Implementation } } \ No newline at end of file diff --git a/src/STranslate/ViewModels/Preference/Services/TranslatorOpenAI.cs b/src/STranslate/ViewModels/Preference/Services/TranslatorOpenAI.cs index 79722e37..9f5c0f49 100644 --- a/src/STranslate/ViewModels/Preference/Services/TranslatorOpenAI.cs +++ b/src/STranslate/ViewModels/Preference/Services/TranslatorOpenAI.cs @@ -154,12 +154,6 @@ private void DelPresetPrompt(UserDefinePrompt userDefinePrompt) new Prompt("user", "Translate the following text from $source to $target: $content") ]; - [JsonIgnore] - [ObservableProperty] - [NotifyCanExecuteChangedFor(nameof(SavePromptCommand))] - [property: JsonIgnore] - private int promptCounter; - [RelayCommand] [property: JsonIgnore] private void DelPrompt(Prompt msg) @@ -192,6 +186,12 @@ private void SavePrompt(BindingList prompts) private bool CanSavePrompt => PromptCounter > 0; + [JsonIgnore] + [ObservableProperty] + [NotifyCanExecuteChangedFor(nameof(SavePromptCommand))] + [property: JsonIgnore] + private int promptCounter; + #endregion Prompt #endregion Properties diff --git a/src/STranslate/Views/Preference/Service/TextChatglmServicesPage.xaml b/src/STranslate/Views/Preference/Service/TextChatglmServicesPage.xaml index 384908fb..8738a1b9 100644 --- a/src/STranslate/Views/Preference/Service/TextChatglmServicesPage.xaml +++ b/src/STranslate/Views/Preference/Service/TextChatglmServicesPage.xaml @@ -118,6 +118,54 @@ + + + + + + + + + + + + +