using AIStudio.Dialogs.Settings; using AIStudio.Tools.AssistantLaunch; using AIStudio.Tools.AssistantSessions; namespace AIStudio.Assistants.Synonym; public partial class AssistantSynonyms : AssistantBaseCore { protected override Tools.Components Component => Tools.Components.SYNONYMS_ASSISTANT; protected override string Title => T("Synonyms"); protected override string Description => T("Find synonyms for words or phrases."); // The prompt of this assistant asks for a list of synonyms only, so the chat gets a prompt of its own, which keeps the language: protected override ChatSystemPromptChoice ChatSystemPrompt => ChatSystemPromptChoice.Custom(this.CreateChatSystemPrompt); protected override string SystemPrompt => $""" You have a PhD in linguistics. Therefore, you are an expert in the {this.SystemPromptLanguage()} language. You receive a word or phrase as input. You might also receive some context. You then provide a list of synonyms as a Markdown list. First, derive possible meanings from the word, phrase, and context, when available. Then, provide possible synonyms for each meaning. Example for the word "learn" and the language English (US): Derive possible meanings (*this list is not part of the output*): - Meaning "to learn" - Meaning "to retain" Next, provide possible synonyms for each meaning, which is your output: # Meaning "to learn" - absorb - study - acquire - advance - practice # Meaning "to retain" - remember - note - realize You do not ask follow-up questions and never repeat the task instructions. When you do not know any synonyms for the given word or phrase, you state this. Your output is always in the {this.SystemPromptLanguage()} language. """; /// /// Creates the system prompt of a chat which continues a search for synonyms, for follow-up questions about them. /// private string CreateChatSystemPrompt() => $""" You have a PhD in linguistics. Therefore, you are an expert in the {this.SystemPromptLanguage()} language. The user looked for synonyms of a word or phrase: the conversation so far holds the word or phrase, its context when the user gave one, and your synonyms for each of its meanings. Now you answer the user's follow-up questions, e.g., how two synonyms differ, which one suits a certain sentence, or which register a word belongs to, and you find further synonyms when the user asks for them. Synonyms are always in the {this.SystemPromptLanguage()} language. Answer questions in the language the user writes in. """; protected override bool AllowProfiles => false; protected override IReadOnlyList FooterButtons => []; protected override string SubmitText => T("Find synonyms"); protected override Func SubmitAction => this.FindSynonyms; protected override string SendToChatVisibleUserPromptText { get { if (string.IsNullOrWhiteSpace(this.inputContext)) { return $""" {T("Find synonyms for the following word or phrase:")} {this.inputText} """; } return $""" {T("Find synonyms for the following word or phrase:")} {this.inputText} {T("Context:")} {this.inputContext} """; } } protected override void ResetForm() { this.inputText = string.Empty; this.inputContext = string.Empty; if (!this.MightPreselectValues()) { this.selectedLanguage = CommonLanguages.AS_IS; this.customTargetLanguage = string.Empty; } } protected override bool MightPreselectValues() { if (this.SettingsManager.ConfigurationData.Synonyms.PreselectOptions) { this.selectedLanguage = this.SettingsManager.ConfigurationData.Synonyms.PreselectedLanguage; this.customTargetLanguage = this.SettingsManager.ConfigurationData.Synonyms.PreselectedOtherLanguage; return true; } return false; } private string inputText = string.Empty; private string inputContext = string.Empty; private CommonLanguages selectedLanguage; private string customTargetLanguage = string.Empty; private static readonly AssistantSessionStateKey INPUT_TEXT_STATE_KEY = new(nameof(inputText)); private static readonly AssistantSessionStateKey INPUT_CONTEXT_STATE_KEY = new(nameof(inputContext)); private static readonly AssistantSessionStateKey SELECTED_LANGUAGE_STATE_KEY = new(nameof(selectedLanguage)); private static readonly AssistantSessionStateKey CUSTOM_TARGET_LANGUAGE_STATE_KEY = new(nameof(customTargetLanguage)); /// protected override void CaptureCustomAssistantSessionState(AssistantSessionStateWriter state) { state.Set(INPUT_TEXT_STATE_KEY, this.inputText); state.Set(INPUT_CONTEXT_STATE_KEY, this.inputContext); state.Set(SELECTED_LANGUAGE_STATE_KEY, this.selectedLanguage); state.Set(CUSTOM_TARGET_LANGUAGE_STATE_KEY, this.customTargetLanguage); } /// protected override void RestoreCustomAssistantSessionState(AssistantSessionStateReader state) { state.Restore(INPUT_TEXT_STATE_KEY, value => this.inputText = value); state.Restore(INPUT_CONTEXT_STATE_KEY, value => this.inputContext = value); state.Restore(SELECTED_LANGUAGE_STATE_KEY, value => this.selectedLanguage = value); state.Restore(CUSTOM_TARGET_LANGUAGE_STATE_KEY, value => this.customTargetLanguage = value); } #region Overrides of AssistantBase protected override void ApplyTextLaunchPayload(TextLaunchPayload payload) => this.inputContext = payload.Text; #endregion private string? ValidatingText(string text) { if(string.IsNullOrWhiteSpace(text)) return T("Please provide a word or phrase as input."); return null; } private string? ValidateCustomLanguage(string language) { if(this.selectedLanguage == CommonLanguages.OTHER && string.IsNullOrWhiteSpace(language)) return T("Please provide a custom language."); return null; } private string SystemPromptLanguage() { var lang = this.selectedLanguage switch { CommonLanguages.AS_IS => "source", CommonLanguages.OTHER => this.customTargetLanguage, _ => $"{this.selectedLanguage.Name}", }; if (string.IsNullOrWhiteSpace(lang)) return "source"; return lang; } private string UserPromptContext() { if(string.IsNullOrWhiteSpace(this.inputContext)) return string.Empty; return $""" The given context is: ``` {this.inputContext} ``` """; } private async Task FindSynonyms() { await this.Form!.ValidateAsync(); if (!this.InputIsValid) return; this.CreateChatThread(); var time = this.AddUserRequest( $""" {this.UserPromptContext()} The given word or phrase is: ``` {this.inputText} ``` """); await this.AddAIResponseAsync(time); } }