Added a prompt optimization assistant (#709)
Build and Release / Determine run mode (push) Waiting to run
Build and Release / Read metadata (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-apple-darwin, osx-arm64, macos-latest, aarch64-apple-darwin, dmg,updater, dmg) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-pc-windows-msvc.exe, win-arm64, windows-latest, aarch64-pc-windows-msvc, nsis,updater, nsis) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-unknown-linux-gnu, linux-arm64, ubuntu-22.04-arm, aarch64-unknown-linux-gnu, appimage,deb,updater, appimage,deb) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-apple-darwin, osx-x64, macos-latest, x86_64-apple-darwin, dmg,updater, dmg) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-pc-windows-msvc.exe, win-x64, windows-latest, x86_64-pc-windows-msvc, nsis,updater, nsis) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-unknown-linux-gnu, linux-x64, ubuntu-22.04, x86_64-unknown-linux-gnu, appimage,deb,updater, appimage,deb) (push) Blocked by required conditions
Build and Release / Prepare & create release (push) Blocked by required conditions
Build and Release / Publish release (push) Blocked by required conditions

This commit is contained in:
Peer Schütt authored and GitHub committed 2026-04-15 19:40:53 +02:00
1 parent a02c53a8b5
commit 4b98cd57b0
26 files changed
+1565 -7

No files matched your search

@@ -8,6 +8,13 @@
<MudText Typo="Typo.h3">
@this.Title
</MudText>
<MudSpacer/>
@if (this.HeaderActions is not null)
{
@this.HeaderActions
}
@if (this.HasSettingsPanel)
{
@@ -31,7 +38,7 @@
</CascadingValue>
<MudStack Row="true" AlignItems="AlignItems.Center" StretchItems="StretchItems.Start" Class="mb-3">
<MudButton Disabled="@this.SubmitDisabled" Variant="Variant.Filled" OnClick="@(async () => await this.Start())" Style="@this.SubmitButtonStyle">
<MudButton Disabled="@(this.SubmitDisabled || this.isProcessing)" Variant="Variant.Filled" OnClick="@(async () => await this.Start())" Style="@this.SubmitButtonStyle">
@this.SubmitText
</MudButton>
@if (this.isProcessing && this.cancellationTokenSource is not null)
@@ -71,6 +78,11 @@
}
}
}
@if (this.ShowResult && this.AfterResultContent is not null)
{
@this.AfterResultContent
}
<div id="@AFTER_RESULT_DIV_ID" class="mt-3">
</div>
@@ -81,6 +81,10 @@ public abstract partial class AssistantBase<TSettings> : AssistantLowerBase wher
protected virtual ChatThread ConvertToChatThread => this.chatThread ?? new();
private protected virtual RenderFragment? HeaderActions => null;
private protected virtual RenderFragment? AfterResultContent => null;
protected virtual IReadOnlyList<IButtonData> FooterButtons => [];
protected virtual bool HasSettingsPanel => typeof(TSettings) != typeof(NoSettingsPanel);
@@ -368,9 +372,14 @@ public abstract partial class AssistantBase<TSettings> : AssistantLowerBase wher
switch (destination)
{
case Tools.Components.CHAT:
var convertedChatThread = this.ConvertToChatThread;
convertedChatThread = convertedChatThread with { SelectedProvider = this.providerSettings.Id };
MessageBus.INSTANCE.DeferMessage(this, sendToData.Event, convertedChatThread);
if (sendToButton.SendToChatAsInput)
MessageBus.INSTANCE.DeferMessage(this, Event.SEND_TO_CHAT_INPUT, contentToSend);
else
{
var convertedChatThread = this.ConvertToChatThread;
convertedChatThread = convertedChatThread with { SelectedProvider = this.providerSettings.Id };
MessageBus.INSTANCE.DeferMessage(this, sendToData.Event, convertedChatThread);
}
break;
default:
@@ -1324,6 +1324,150 @@ UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::MYTASKS::ASSISTANTMYTASKS::T534887559"] =
-- Please provide a custom language.
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::MYTASKS::ASSISTANTMYTASKS::T656744944"] = "Please provide a custom language."
-- The custom prompt guide file is empty or could not be read.
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::PROMPTOPTIMIZER::ASSISTANTPROMPTOPTIMIZER::T1173408044"] = "The custom prompt guide file is empty or could not be read."
-- Use English for complex prompts and explicitly request response language if needed.
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::PROMPTOPTIMIZER::ASSISTANTPROMPTOPTIMIZER::T119999744"] = "Use English for complex prompts and explicitly request response language if needed."
-- The selected custom prompt guide file could not be found.
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::PROMPTOPTIMIZER::ASSISTANTPROMPTOPTIMIZER::T1300996373"] = "The selected custom prompt guide file could not be found."
-- Define a role for the model to focus output style and expertise.
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::PROMPTOPTIMIZER::ASSISTANTPROMPTOPTIMIZER::T1316122151"] = "Define a role for the model to focus output style and expertise."
-- Use headings or markers to separate context, task, and constraints.
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::PROMPTOPTIMIZER::ASSISTANTPROMPTOPTIMIZER::T1435532298"] = "Use headings or markers to separate context, task, and constraints."
-- Custom Prompt Guide Preview
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::PROMPTOPTIMIZER::ASSISTANTPROMPTOPTIMIZER::T1526658372"] = "Custom Prompt Guide Preview"
-- The model response was not in the expected JSON format. The raw response is shown as optimized prompt.
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::PROMPTOPTIMIZER::ASSISTANTPROMPTOPTIMIZER::T1548376553"] = "The model response was not in the expected JSON format. The raw response is shown as optimized prompt."
-- View
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::PROMPTOPTIMIZER::ASSISTANTPROMPTOPTIMIZER::T1582017048"] = "View"
-- Separate context, task, constraints, and output format with headings or markers.
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::PROMPTOPTIMIZER::ASSISTANTPROMPTOPTIMIZER::T1626024580"] = "Separate context, task, constraints, and output format with headings or markers."
-- Add short examples and background context for your specific use case.
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::PROMPTOPTIMIZER::ASSISTANTPROMPTOPTIMIZER::T1666841672"] = "Add short examples and background context for your specific use case."
-- Assign a role to shape tone, expertise, and focus.
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::PROMPTOPTIMIZER::ASSISTANTPROMPTOPTIMIZER::T1679211785"] = "Assign a role to shape tone, expertise, and focus."
-- Structure with markers
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::PROMPTOPTIMIZER::ASSISTANTPROMPTOPTIMIZER::T1695758233"] = "Structure with markers"
-- Please attach and load a valid custom prompt guide file.
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::PROMPTOPTIMIZER::ASSISTANTPROMPTOPTIMIZER::T1760468309"] = "Please attach and load a valid custom prompt guide file."
-- Prompt Optimizer
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::PROMPTOPTIMIZER::ASSISTANTPROMPTOPTIMIZER::T1777666968"] = "Prompt Optimizer"
-- Add clearer goals and explicit quality expectations.
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::PROMPTOPTIMIZER::ASSISTANTPROMPTOPTIMIZER::T1833795299"] = "Add clearer goals and explicit quality expectations."
-- Optimize prompt
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::PROMPTOPTIMIZER::ASSISTANTPROMPTOPTIMIZER::T1857716344"] = "Optimize prompt"
-- Break the task into numbered steps if order matters.
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::PROMPTOPTIMIZER::ASSISTANTPROMPTOPTIMIZER::T2185953360"] = "Break the task into numbered steps if order matters."
-- Please provide a prompt or prompt description.
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::PROMPTOPTIMIZER::ASSISTANTPROMPTOPTIMIZER::T2228130444"] = "Please provide a prompt or prompt description."
-- Add examples and context
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::PROMPTOPTIMIZER::ASSISTANTPROMPTOPTIMIZER::T2386806593"] = "Add examples and context"
-- Custom prompt guide file
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::PROMPTOPTIMIZER::ASSISTANTPROMPTOPTIMIZER::T2458417590"] = "Custom prompt guide file"
-- Use an LLM to optimize your prompt by following either the default or your individual prompt guidelines and get targeted recommendations for future versions of the prompt.
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::PROMPTOPTIMIZER::ASSISTANTPROMPTOPTIMIZER::T2466607250"] = "Use an LLM to optimize your prompt by following either the default or your individual prompt guidelines and get targeted recommendations for future versions of the prompt."
-- Replaced the previously selected custom prompt guide file.
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::PROMPTOPTIMIZER::ASSISTANTPROMPTOPTIMIZER::T2698103422"] = "Replaced the previously selected custom prompt guide file."
-- (Optional) Important Aspects for the prompt
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::PROMPTOPTIMIZER::ASSISTANTPROMPTOPTIMIZER::T2713431429"] = "(Optional) Important Aspects for the prompt"
-- Use the prompt recommendations from the custom prompt guide.
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::PROMPTOPTIMIZER::ASSISTANTPROMPTOPTIMIZER::T2830307837"] = "Use the prompt recommendations from the custom prompt guide."
-- Be clear and direct
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::PROMPTOPTIMIZER::ASSISTANTPROMPTOPTIMIZER::T2880063041"] = "Be clear and direct"
-- The prompting guideline file could not be loaded. Please verify 'prompting_guideline.md' in Assistants/PromptOptimizer.
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::PROMPTOPTIMIZER::ASSISTANTPROMPTOPTIMIZER::T30321193"] = "The prompting guideline file could not be loaded. Please verify 'prompting_guideline.md' in Assistants/PromptOptimizer."
-- Custom language
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::PROMPTOPTIMIZER::ASSISTANTPROMPTOPTIMIZER::T3032662264"] = "Custom language"
-- Give the model a role
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::PROMPTOPTIMIZER::ASSISTANTPROMPTOPTIMIZER::T3420218291"] = "Give the model a role"
-- Failed to load custom prompt guide content.
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::PROMPTOPTIMIZER::ASSISTANTPROMPTOPTIMIZER::T3488117809"] = "Failed to load custom prompt guide content."
-- No file selected
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::PROMPTOPTIMIZER::ASSISTANTPROMPTOPTIMIZER::T3522202289"] = "No file selected"
-- Use custom prompt guide
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::PROMPTOPTIMIZER::ASSISTANTPROMPTOPTIMIZER::T3528575759"] = "Use custom prompt guide"
-- Prefer numbered steps when task order matters.
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::PROMPTOPTIMIZER::ASSISTANTPROMPTOPTIMIZER::T3558299393"] = "Prefer numbered steps when task order matters."
-- Recommendations for your prompt
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::PROMPTOPTIMIZER::ASSISTANTPROMPTOPTIMIZER::T3577149599"] = "Recommendations for your prompt"
-- (Optional) Specify aspects the optimizer should emphasize in the resulting prompt, such as output structure, or constraints.
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::PROMPTOPTIMIZER::ASSISTANTPROMPTOPTIMIZER::T3686962588"] = "(Optional) Specify aspects the optimizer should emphasize in the resulting prompt, such as output structure, or constraints."
-- View default prompt guide
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::PROMPTOPTIMIZER::ASSISTANTPROMPTOPTIMIZER::T4017099405"] = "View default prompt guide"
-- Prompt or prompt description
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::PROMPTOPTIMIZER::ASSISTANTPROMPTOPTIMIZER::T4058791116"] = "Prompt or prompt description"
-- Include short examples and context that explain the purpose behind your requirements.
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::PROMPTOPTIMIZER::ASSISTANTPROMPTOPTIMIZER::T4143206140"] = "Include short examples and context that explain the purpose behind your requirements."
-- Prompting Guideline
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::PROMPTOPTIMIZER::ASSISTANTPROMPTOPTIMIZER::T4250996615"] = "Prompting Guideline"
-- Use sequential steps
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::PROMPTOPTIMIZER::ASSISTANTPROMPTOPTIMIZER::T487578804"] = "Use sequential steps"
-- Use clear, explicit instructions and directly state quality expectations.
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::PROMPTOPTIMIZER::ASSISTANTPROMPTOPTIMIZER::T596557540"] = "Use clear, explicit instructions and directly state quality expectations."
-- Choose prompt language deliberately
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::PROMPTOPTIMIZER::ASSISTANTPROMPTOPTIMIZER::T616613304"] = "Choose prompt language deliberately"
-- Prompt recommendations were updated based on your latest optimization.
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::PROMPTOPTIMIZER::ASSISTANTPROMPTOPTIMIZER::T633382478"] = "Prompt recommendations were updated based on your latest optimization."
-- Please provide a custom language.
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::PROMPTOPTIMIZER::ASSISTANTPROMPTOPTIMIZER::T656744944"] = "Please provide a custom language."
-- No further recommendation in this area.
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::PROMPTOPTIMIZER::ASSISTANTPROMPTOPTIMIZER::T659636347"] = "No further recommendation in this area."
-- The prompting guideline file could not be loaded.
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::PROMPTOPTIMIZER::ASSISTANTPROMPTOPTIMIZER::T666817418"] = "The prompting guideline file could not be loaded."
-- Language for the optimized prompt
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::PROMPTOPTIMIZER::ASSISTANTPROMPTOPTIMIZER::T773621440"] = "Language for the optimized prompt"
-- Use these recommendations, that are based on the default prompt guide, to improve your prompts. The suggestions are updated based on your latest prompt optimization.
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::PROMPTOPTIMIZER::ASSISTANTPROMPTOPTIMIZER::T805885769"] = "Use these recommendations, that are based on the default prompt guide, to improve your prompts. The suggestions are updated based on your latest prompt optimization."
-- For complex tasks, write prompts in English.
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::PROMPTOPTIMIZER::ASSISTANTPROMPTOPTIMIZER::T85710437"] = "For complex tasks, write prompts in English."
-- Please provide a text as input. You might copy the desired text from a document or a website.
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::REWRITEIMPROVE::ASSISTANTREWRITEIMPROVE::T137304886"] = "Please provide a text as input. You might copy the desired text from a document or a website."
@@ -4033,6 +4177,15 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::PROFILEDIALOG::T900713019"] = "Cancel"
-- The profile name must be unique; the chosen name is already in use.
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::PROFILEDIALOG::T911748898"] = "The profile name must be unique; the chosen name is already in use."
-- Close
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::PROMPTINGGUIDELINEDIALOG::T3448155331"] = "Close"
-- The full prompting guideline used by the Prompt Optimizer.
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::PROMPTINGGUIDELINEDIALOG::T384594633"] = "The full prompting guideline used by the Prompt Optimizer."
-- Prompting Guideline
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::PROMPTINGGUIDELINEDIALOG::T4250996615"] = "Prompting Guideline"
-- Please be aware: This section is for experts only. You are responsible for verifying the correctness of the additional parameters you provide to the API call. By default, AI Studio uses the OpenAI-compatible chat completions API, when that it is supported by the underlying service and model.
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::PROVIDERDIALOG::T1017509792"] = "Please be aware: This section is for experts only. You are responsible for verifying the correctness of the additional parameters you provide to the API call. By default, AI Studio uses the OpenAI-compatible chat completions API, when that it is supported by the underlying service and model."
@@ -4960,6 +5113,39 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGPROFILES::T55364659"
-- Are you a project manager in a research facility? You might want to create a profile for your project management activities, one for your scientific work, and a profile for when you need to write program code. In these profiles, you can record how much experience you have or which methods you like or dislike using. Later, you can choose when and where you want to use each profile.
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGPROFILES::T56359901"] = "Are you a project manager in a research facility? You might want to create a profile for your project management activities, one for your scientific work, and a profile for when you need to write program code. In these profiles, you can record how much experience you have or which methods you like or dislike using. Later, you can choose when and where you want to use each profile."
-- Preselect the target language
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGPROMPTOPTIMIZER::T1417990312"] = "Preselect the target language"
-- Preselect another target language
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGPROMPTOPTIMIZER::T1462295644"] = "Preselect another target language"
-- Assistant: Prompt Optimizer Options
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGPROMPTOPTIMIZER::T2309650422"] = "Assistant: Prompt Optimizer Options"
-- Preselect aspects the optimizer should emphasize, such as role clarity, structure, or output constraints.
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGPROMPTOPTIMIZER::T2365571378"] = "Preselect aspects the optimizer should emphasize, such as role clarity, structure, or output constraints."
-- No prompt optimizer options are preselected
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGPROMPTOPTIMIZER::T2506620531"] = "No prompt optimizer options are preselected"
-- Prompt optimizer options are preselected
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGPROMPTOPTIMIZER::T2576287692"] = "Prompt optimizer options are preselected"
-- Preselect prompt optimizer options?
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGPROMPTOPTIMIZER::T3159686278"] = "Preselect prompt optimizer options?"
-- Close
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGPROMPTOPTIMIZER::T3448155331"] = "Close"
-- Which target language should be preselected?
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGPROMPTOPTIMIZER::T3547337928"] = "Which target language should be preselected?"
-- When enabled, you can preselect target language, important aspects, and provider defaults for the prompt optimizer assistant.
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGPROMPTOPTIMIZER::T3570338905"] = "When enabled, you can preselect target language, important aspects, and provider defaults for the prompt optimizer assistant."
-- Preselect important aspects
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGPROMPTOPTIMIZER::T3705987833"] = "Preselect important aspects"
-- Which writing style should be preselected?
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGREWRITE::T1173034744"] = "Which writing style should be preselected?"
@@ -5497,9 +5683,15 @@ UI_TEXT_CONTENT["AISTUDIO::PAGES::ASSISTANTS::T1614176092"] = "Assistants"
-- Coding
UI_TEXT_CONTENT["AISTUDIO::PAGES::ASSISTANTS::T1617786407"] = "Coding"
-- Optimize your prompt using a structured guideline.
UI_TEXT_CONTENT["AISTUDIO::PAGES::ASSISTANTS::T1709976267"] = "Optimize your prompt using a structured guideline."
-- Analyze a text or an email for tasks you need to complete.
UI_TEXT_CONTENT["AISTUDIO::PAGES::ASSISTANTS::T1728590051"] = "Analyze a text or an email for tasks you need to complete."
-- Prompt Optimizer
UI_TEXT_CONTENT["AISTUDIO::PAGES::ASSISTANTS::T1777666968"] = "Prompt Optimizer"
-- Text Summarizer
UI_TEXT_CONTENT["AISTUDIO::PAGES::ASSISTANTS::T1907192403"] = "Text Summarizer"
@@ -6529,6 +6721,9 @@ UI_TEXT_CONTENT["AISTUDIO::TOOLS::COMPONENTSEXTENSIONS::T166453786"] = "Grammar
-- Legal Check Assistant
UI_TEXT_CONTENT["AISTUDIO::TOOLS::COMPONENTSEXTENSIONS::T1886447798"] = "Legal Check Assistant"
-- Prompt Optimizer Assistant
UI_TEXT_CONTENT["AISTUDIO::TOOLS::COMPONENTSEXTENSIONS::T1993795352"] = "Prompt Optimizer Assistant"
-- Job Posting Assistant
UI_TEXT_CONTENT["AISTUDIO::TOOLS::COMPONENTSEXTENSIONS::T2212811874"] = "Job Posting Assistant"
@@ -0,0 +1,124 @@
@attribute [Route(Routes.ASSISTANT_PROMPT_OPTIMIZER)]
@inherits AssistantBaseCore<AIStudio.Dialogs.Settings.SettingsDialogPromptOptimizer>
<MudTextField T="string"
@bind-Text="@this.inputPrompt"
Validation="@this.ValidateInputPrompt"
AdornmentIcon="@Icons.Material.Filled.AutoFixHigh"
Adornment="Adornment.Start"
Label="@T("Prompt or prompt description")"
Variant="Variant.Outlined"
Lines="8"
AutoGrow="@true"
MaxLines="20"
Class="mb-3"
UserAttributes="@USER_INPUT_ATTRIBUTES"/>
<EnumSelection T="CommonLanguages"
NameFunc="@(language => language.NameSelectingOptional())"
@bind-Value="@this.selectedTargetLanguage"
Icon="@Icons.Material.Filled.Translate"
Label="@T("Language for the optimized prompt")"
AllowOther="@true"
OtherValue="CommonLanguages.OTHER"
@bind-OtherInput="@this.customTargetLanguage"
ValidateOther="@this.ValidateCustomLanguage"
LabelOther="@T("Custom language")"/>
<MudTextField T="string"
AutoGrow="true"
Lines="2"
@bind-Text="@this.importantAspects"
Class="mb-3"
Label="@T("(Optional) Important Aspects for the prompt")"
HelperText="@T("(Optional) Specify aspects the optimizer should emphasize in the resulting prompt, such as output structure, or constraints.")"
ShrinkLabel="true"
Variant="Variant.Outlined"
AdornmentIcon="@Icons.Material.Filled.List"
Adornment="Adornment.Start"/>
<MudStack Row="true" AlignItems="AlignItems.Center" Class="mb-2">
<MudText Typo="Typo.h6">@T("Recommendations for your prompt")</MudText>
</MudStack>
@if (this.ShowUpdatedPromptGuidelinesIndicator)
{
<MudAlert Severity="Severity.Info" Dense="true" Variant="Variant.Outlined" Class="mb-3">
<MudStack Row="true" AlignItems="AlignItems.Center" Wrap="Wrap.Wrap">
<MudText Typo="Typo.body2">@T("Prompt recommendations were updated based on your latest optimization.")</MudText>
</MudStack>
</MudAlert>
}
@if (!this.useCustomPromptGuide)
{
<MudJustifiedText Class="mb-3">@T("Use these recommendations, that are based on the default prompt guide, to improve your prompts. The suggestions are updated based on your latest prompt optimization.")</MudJustifiedText>
<MudGrid Class="mb-3">
<MudItem xs="12" sm="6" md="4">
<MudTextField T="string" Value="@this.recClarityDirectness" Label="@T("Be clear and direct")" ReadOnly="true" Variant="Variant.Outlined" Lines="2" AutoGrow="@true" />
</MudItem>
<MudItem xs="12" sm="6" md="4">
<MudTextField T="string" Value="@this.recExamplesContext" Label="@T("Add examples and context")" ReadOnly="true" Variant="Variant.Outlined" Lines="2" AutoGrow="@true" />
</MudItem>
<MudItem xs="12" sm="6" md="4">
<MudTextField T="string" Value="@this.recSequentialSteps" Label="@T("Use sequential steps")" ReadOnly="true" Variant="Variant.Outlined" Lines="2" AutoGrow="@true" />
</MudItem>
<MudItem xs="12" sm="6" md="4">
<MudTextField T="string" Value="@this.recStructureMarkers" Label="@T("Structure with markers")" ReadOnly="true" Variant="Variant.Outlined" Lines="2" AutoGrow="@true" />
</MudItem>
<MudItem xs="12" sm="6" md="4">
<MudTextField T="string" Value="@this.recRoleDefinition" Label="@T("Give the model a role")" ReadOnly="true" Variant="Variant.Outlined" Lines="2" AutoGrow="@true" />
</MudItem>
<MudItem xs="12" sm="6" md="4">
<MudTextField T="string" Value="@this.recLanguageChoice" Label="@T("Choose prompt language deliberately")" ReadOnly="true" Variant="Variant.Outlined" Lines="2" AutoGrow="@true" />
</MudItem>
</MudGrid>
}
@if (this.useCustomPromptGuide)
{
<MudJustifiedText Class="mb-3">@T("Use the prompt recommendations from the custom prompt guide.")</MudJustifiedText>
}
<MudStack Row="true" AlignItems="AlignItems.Center" Wrap="Wrap.Wrap" StretchItems="StretchItems.None" Class="mb-3">
<MudButton Variant="Variant.Outlined"
StartIcon="@Icons.Material.Filled.MenuBook"
OnClick="@(async () => await this.OpenPromptingGuidelineDialog())">
@T("View default prompt guide")
</MudButton>
<MudSwitch T="bool" Value="@this.useCustomPromptGuide" ValueChanged="@this.SetUseCustomPromptGuide" Color="Color.Primary" Class="mx-1">
@T("Use custom prompt guide")
</MudSwitch>
@if (this.useCustomPromptGuide)
{
<AttachDocuments Name="Custom Prompt Guide"
Layer="@DropLayers.ASSISTANTS"
@bind-DocumentPaths="@this.customPromptGuideFiles"
OnChange="@this.OnCustomPromptGuideFilesChanged"
CatchAllDocuments="false"
UseSmallForm="true"
ValidateMediaFileTypes="false"
Provider="@this.providerSettings"/>
}
<MudTextField T="string"
Text="@this.CustomPromptGuideFileName"
Label="@T("Custom prompt guide file")"
ReadOnly="true"
Disabled="@(!this.useCustomPromptGuide)"
Variant="Variant.Outlined"
Class="mx-2"
Style="min-width: 18rem;"/>
<MudButton Variant="Variant.Outlined"
StartIcon="@Icons.Material.Filled.Visibility"
Disabled="@(!this.CanPreviewCustomPromptGuide)"
OnClick="@(async () => await this.OpenCustomPromptGuideDialog())">
@T("View")
</MudButton>
</MudStack>
<ProviderSelection @bind-ProviderSettings="@this.providerSettings" ValidateProvider="@this.ValidatingProvider"/>
@@ -0,0 +1,572 @@
using System.Text.Json;
using System.Text.RegularExpressions;
using AIStudio.Chat;
using AIStudio.Dialogs;
using AIStudio.Dialogs.Settings;
using Microsoft.AspNetCore.Components;
#if !DEBUG
using System.Reflection;
using Microsoft.Extensions.FileProviders;
#endif
namespace AIStudio.Assistants.PromptOptimizer;
public partial class AssistantPromptOptimizer : AssistantBaseCore<SettingsDialogPromptOptimizer>
{
private static readonly Regex JSON_CODE_FENCE_REGEX = new(
pattern: """```(?:json)?\s*(?<json>\{[\s\S]*\})\s*```""",
options: RegexOptions.Compiled | RegexOptions.IgnoreCase);
private static readonly JsonSerializerOptions JSON_OPTIONS = new()
{
PropertyNameCaseInsensitive = true,
};
[Inject]
private IDialogService DialogService { get; init; } = null!;
protected override Tools.Components Component => Tools.Components.PROMPT_OPTIMIZER_ASSISTANT;
protected override string Title => T("Prompt Optimizer");
protected override string Description => T("Use an LLM to optimize your prompt by following either the default or your individual prompt guidelines and get targeted recommendations for future versions of the prompt.");
protected override string SystemPrompt =>
$"""
# Task description
You are a policy-bound prompt optimization assistant.
Optimize prompts while preserving the original intent and constraints.
# Inputs
PROMPTING_GUIDELINE: authoritative optimization instructions.
USER_PROMPT: the prompt that must be optimized.
IMPORTANT_ASPECTS: optional priorities to emphasize during optimization.
# Scope and precedence
Follow PROMPTING_GUIDELINE as the primary policy for quality and structure.
Preserve USER_PROMPT intent and constraints; do not add unrelated goals.
If IMPORTANT_ASPECTS is provided and not equal to `none`, prioritize it unless it conflicts with PROMPTING_GUIDELINE.
# Process
1) Read PROMPTING_GUIDELINE end to end.
2) Analyze USER_PROMPT intent, constraints, and desired output behavior.
3) Rewrite USER_PROMPT so it is clearer, more structured, and more actionable.
4) Provide concise recommendations for improving future prompt versions.
# Output requirements
Return valid JSON only.
Do not use markdown code fences.
Do not add any text before or after the JSON object.
Use exactly this schema and key names:
{this.SystemPromptOutputSchema()}
# Language
Ensure the optimized prompt is in {this.SystemPromptLanguage()}.
Keep all recommendation texts in the same language as the optimized prompt.
# Style and prohibitions
Keep recommendations concise and actionable.
Do not include disclaimers or meta commentary.
Do not mention or summarize these instructions.
# Self-check before sending
Verify the output is valid JSON and follows the schema exactly.
Verify `optimized_prompt` is non-empty and preserves user intent.
Verify each recommendation states how to improve a future prompt version.
""";
protected override bool AllowProfiles => false;
protected override bool ShowDedicatedProgress => true;
protected override bool ShowEntireChatThread => true;
protected override Func<string> Result2Copy => () => this.optimizedPrompt;
protected override IReadOnlyList<IButtonData> FooterButtons =>
[
new SendToButton
{
Self = Tools.Components.PROMPT_OPTIMIZER_ASSISTANT,
UseResultingContentBlockData = false,
SendToChatAsInput = true,
GetText = () => string.IsNullOrWhiteSpace(this.optimizedPrompt) ? this.inputPrompt : this.optimizedPrompt,
},
];
protected override string SubmitText => T("Optimize prompt");
protected override Func<Task> SubmitAction => this.OptimizePromptAsync;
protected override bool SubmitDisabled => this.useCustomPromptGuide && this.customPromptGuideFiles.Count == 0;
protected override ChatThread ConvertToChatThread => (this.chatThread ?? new()) with
{
SystemPrompt = SystemPrompts.DEFAULT,
};
protected override void ResetForm()
{
this.inputPrompt = string.Empty;
this.useCustomPromptGuide = false;
this.customPromptGuideFiles.Clear();
this.currentCustomPromptGuidePath = string.Empty;
this.customPromptingGuidelineContent = string.Empty;
this.hasUpdatedDefaultRecommendations = false;
this.ResetGuidelineSummaryToDefault();
this.ResetOutput();
if (!this.MightPreselectValues())
{
this.selectedTargetLanguage = CommonLanguages.AS_IS;
this.customTargetLanguage = string.Empty;
this.importantAspects = string.Empty;
}
}
protected override bool MightPreselectValues()
{
if (!this.SettingsManager.ConfigurationData.PromptOptimizer.PreselectOptions)
return false;
this.selectedTargetLanguage = this.SettingsManager.ConfigurationData.PromptOptimizer.PreselectedTargetLanguage;
this.customTargetLanguage = this.SettingsManager.ConfigurationData.PromptOptimizer.PreselectedOtherLanguage;
this.importantAspects = this.SettingsManager.ConfigurationData.PromptOptimizer.PreselectedImportantAspects;
return true;
}
protected override async Task OnInitializedAsync()
{
this.ResetGuidelineSummaryToDefault();
this.hasUpdatedDefaultRecommendations = false;
var deferredContent = MessageBus.INSTANCE.CheckDeferredMessages<string>(Event.SEND_TO_PROMPT_OPTIMIZER_ASSISTANT).FirstOrDefault();
if (deferredContent is not null)
this.inputPrompt = deferredContent;
await base.OnInitializedAsync();
}
private string inputPrompt = string.Empty;
private CommonLanguages selectedTargetLanguage = CommonLanguages.AS_IS;
private string customTargetLanguage = string.Empty;
private string importantAspects = string.Empty;
private bool useCustomPromptGuide;
private HashSet<FileAttachment> customPromptGuideFiles = [];
private string currentCustomPromptGuidePath = string.Empty;
private string customPromptingGuidelineContent = string.Empty;
private bool isLoadingCustomPromptGuide;
private bool hasUpdatedDefaultRecommendations;
private string optimizedPrompt = string.Empty;
private string recClarityDirectness = string.Empty;
private string recExamplesContext = string.Empty;
private string recSequentialSteps = string.Empty;
private string recStructureMarkers = string.Empty;
private string recRoleDefinition = string.Empty;
private string recLanguageChoice = string.Empty;
private bool ShowUpdatedPromptGuidelinesIndicator => !this.useCustomPromptGuide && this.hasUpdatedDefaultRecommendations;
private bool CanPreviewCustomPromptGuide => this.useCustomPromptGuide && this.customPromptGuideFiles.Count > 0;
private string CustomPromptGuideFileName => this.customPromptGuideFiles.Count switch
{
0 => T("No file selected"),
_ => this.customPromptGuideFiles.First().FileName
};
private string? ValidateInputPrompt(string text)
{
if (string.IsNullOrWhiteSpace(text))
return T("Please provide a prompt or prompt description.");
return null;
}
private string? ValidateCustomLanguage(string language)
{
if (this.selectedTargetLanguage == CommonLanguages.OTHER && string.IsNullOrWhiteSpace(language))
return T("Please provide a custom language.");
return null;
}
private string SystemPromptLanguage()
{
var language = this.selectedTargetLanguage switch
{
CommonLanguages.AS_IS => "the source language of the input prompt",
CommonLanguages.OTHER => this.customTargetLanguage,
_ => this.selectedTargetLanguage.Name(),
};
if (string.IsNullOrWhiteSpace(language))
return "the source language of the input prompt";
return language;
}
private async Task OptimizePromptAsync()
{
await this.form!.Validate();
if (!this.inputIsValid)
return;
this.ClearInputIssues();
this.ResetOutput();
this.hasUpdatedDefaultRecommendations = false;
var promptingGuideline = await this.GetPromptingGuidelineForOptimizationAsync();
if (string.IsNullOrWhiteSpace(promptingGuideline))
{
if (this.useCustomPromptGuide)
this.AddInputIssue(T("Please attach and load a valid custom prompt guide file."));
else
this.AddInputIssue(T("The prompting guideline file could not be loaded. Please verify 'prompting_guideline.md' in Assistants/PromptOptimizer."));
return;
}
this.CreateChatThread();
var requestTime = this.AddUserRequest(this.BuildOptimizationRequest(promptingGuideline), hideContentFromUser: true);
var aiResponse = await this.AddAIResponseAsync(requestTime, hideContentFromUser: true);
if (!TryParseOptimizationResult(aiResponse, out var parsedResult))
{
this.optimizedPrompt = aiResponse.Trim();
if (!this.useCustomPromptGuide)
{
this.ApplyFallbackRecommendations();
this.MarkRecommendationsUpdated();
}
this.AddInputIssue(T("The model response was not in the expected JSON format. The raw response is shown as optimized prompt."));
this.AddVisibleOptimizedPromptBlock();
return;
}
this.ApplyOptimizationResult(parsedResult);
this.AddVisibleOptimizedPromptBlock();
}
private string BuildOptimizationRequest(string promptingGuideline)
{
return
$$"""
# PROMPTING_GUIDELINE
<GUIDELINE>
{{promptingGuideline}}
</GUIDELINE>
# USER_PROMPT
<USER_PROMPT>
{{this.inputPrompt}}
</USER_PROMPT>
{{this.PromptImportantAspects()}}
""";
}
private string PromptImportantAspects()
{
return string.IsNullOrWhiteSpace(this.importantAspects) ? string.Empty : $"""
# IMPORTANT_ASPECTS
<IMPORTANT_ASPECTS>
{this.importantAspects}
</IMPORTANT_ASPECTS>
""";
}
private string SystemPromptOutputSchema() =>
"""
{
"optimized_prompt": "string",
"recommendations": {
"clarity_and_directness": "string",
"examples_and_context": "string",
"sequential_steps": "string",
"structure_with_markers": "string",
"role_definition": "string",
"language_choice": "string"
}
}
""";
private static bool TryParseOptimizationResult(string rawResponse, out PromptOptimizationResult parsedResult)
{
parsedResult = new();
if (TryDeserialize(rawResponse, out parsedResult))
return true;
var codeFenceMatch = JSON_CODE_FENCE_REGEX.Match(rawResponse);
if (codeFenceMatch.Success)
{
var codeFenceJson = codeFenceMatch.Groups["json"].Value;
if (TryDeserialize(codeFenceJson, out parsedResult))
return true;
}
var firstBrace = rawResponse.IndexOf('{');
var lastBrace = rawResponse.LastIndexOf('}');
if (firstBrace >= 0 && lastBrace > firstBrace)
{
var objectText = rawResponse[firstBrace..(lastBrace + 1)];
if (TryDeserialize(objectText, out parsedResult))
return true;
}
return false;
}
private static bool TryDeserialize(string json, out PromptOptimizationResult parsedResult)
{
parsedResult = new();
if (string.IsNullOrWhiteSpace(json))
return false;
try
{
var probe = JsonSerializer.Deserialize<PromptOptimizationResult>(json, JSON_OPTIONS);
if (probe is null || string.IsNullOrWhiteSpace(probe.OptimizedPrompt))
return false;
probe.Recommendations ??= new PromptOptimizationRecommendations();
parsedResult = probe;
return true;
}
catch
{
return false;
}
}
private void ApplyOptimizationResult(PromptOptimizationResult optimizationResult)
{
this.optimizedPrompt = optimizationResult.OptimizedPrompt.Trim();
if (this.useCustomPromptGuide)
return;
this.ApplyRecommendations(optimizationResult.Recommendations);
this.MarkRecommendationsUpdated();
}
private void MarkRecommendationsUpdated()
{
this.hasUpdatedDefaultRecommendations = true;
}
private void ApplyRecommendations(PromptOptimizationRecommendations recommendations)
{
this.recClarityDirectness = this.EmptyFallback(recommendations.ClarityAndDirectness);
this.recExamplesContext = this.EmptyFallback(recommendations.ExamplesAndContext);
this.recSequentialSteps = this.EmptyFallback(recommendations.SequentialSteps);
this.recStructureMarkers = this.EmptyFallback(recommendations.StructureWithMarkers);
this.recRoleDefinition = this.EmptyFallback(recommendations.RoleDefinition);
this.recLanguageChoice = this.EmptyFallback(recommendations.LanguageChoice);
}
private void ApplyFallbackRecommendations()
{
this.recClarityDirectness = T("Add clearer goals and explicit quality expectations.");
this.recExamplesContext = T("Add short examples and background context for your specific use case.");
this.recSequentialSteps = T("Break the task into numbered steps if order matters.");
this.recStructureMarkers = T("Use headings or markers to separate context, task, and constraints.");
this.recRoleDefinition = T("Define a role for the model to focus output style and expertise.");
this.recLanguageChoice = T("Use English for complex prompts and explicitly request response language if needed.");
}
private string EmptyFallback(string text)
{
if (string.IsNullOrWhiteSpace(text))
return T("No further recommendation in this area.");
return text.Trim();
}
private void ResetOutput()
{
this.optimizedPrompt = string.Empty;
}
private void ResetGuidelineSummaryToDefault()
{
this.recClarityDirectness = T("Use clear, explicit instructions and directly state quality expectations.");
this.recExamplesContext = T("Include short examples and context that explain the purpose behind your requirements.");
this.recSequentialSteps = T("Prefer numbered steps when task order matters.");
this.recStructureMarkers = T("Separate context, task, constraints, and output format with headings or markers.");
this.recRoleDefinition = T("Assign a role to shape tone, expertise, and focus.");
this.recLanguageChoice = T("For complex tasks, write prompts in English.");
}
private void AddVisibleOptimizedPromptBlock()
{
if (string.IsNullOrWhiteSpace(this.optimizedPrompt))
return;
if (this.chatThread is null)
return;
var visibleResponseContent = new ContentText
{
Text = this.optimizedPrompt,
};
this.chatThread.Blocks.Add(new ContentBlock
{
Time = DateTimeOffset.Now,
ContentType = ContentType.TEXT,
Role = ChatRole.AI,
HideFromUser = false,
Content = visibleResponseContent,
});
}
private static async Task<string> ReadPromptingGuidelineAsync()
{
#if DEBUG
var guidelinePath = Path.Join(Environment.CurrentDirectory, "Assistants", "PromptOptimizer", "prompting_guideline.md");
return File.Exists(guidelinePath)
? await File.ReadAllTextAsync(guidelinePath)
: string.Empty;
#else
var resourceFileProvider = new ManifestEmbeddedFileProvider(Assembly.GetAssembly(type: typeof(Program))!, "Assistants/PromptOptimizer");
var file = resourceFileProvider.GetFileInfo("prompting_guideline.md");
if (!file.Exists)
return string.Empty;
await using var fileStream = file.CreateReadStream();
using var reader = new StreamReader(fileStream);
return await reader.ReadToEndAsync();
#endif
}
private async Task<string> GetPromptingGuidelineForOptimizationAsync()
{
if (!this.useCustomPromptGuide)
return await ReadPromptingGuidelineAsync();
if (this.customPromptGuideFiles.Count == 0)
return string.Empty;
if (!string.IsNullOrWhiteSpace(this.customPromptingGuidelineContent))
return this.customPromptingGuidelineContent;
var fileAttachment = this.customPromptGuideFiles.First();
await this.LoadCustomPromptGuidelineContentAsync(fileAttachment);
return this.customPromptingGuidelineContent;
}
private async Task SetUseCustomPromptGuide(bool useCustom)
{
this.useCustomPromptGuide = useCustom;
if (!useCustom)
return;
if (this.customPromptGuideFiles.Count == 0)
return;
var fileAttachment = this.customPromptGuideFiles.First();
if (string.IsNullOrWhiteSpace(this.customPromptingGuidelineContent))
await this.LoadCustomPromptGuidelineContentAsync(fileAttachment);
}
private async Task OnCustomPromptGuideFilesChanged(HashSet<FileAttachment> files)
{
if (files.Count == 0)
{
this.customPromptGuideFiles.Clear();
this.currentCustomPromptGuidePath = string.Empty;
this.customPromptingGuidelineContent = string.Empty;
return;
}
var selected = files.FirstOrDefault(file => !string.Equals(file.FilePath, this.currentCustomPromptGuidePath, StringComparison.OrdinalIgnoreCase))
?? files.First();
var replacedPrevious = !string.IsNullOrWhiteSpace(this.currentCustomPromptGuidePath) &&
!string.Equals(this.currentCustomPromptGuidePath, selected.FilePath, StringComparison.OrdinalIgnoreCase);
this.customPromptGuideFiles = [ selected ];
this.currentCustomPromptGuidePath = selected.FilePath;
if (files.Count > 1 || replacedPrevious)
this.Snackbar.Add(T("Replaced the previously selected custom prompt guide file."), Severity.Info);
await this.LoadCustomPromptGuidelineContentAsync(selected);
}
private async Task LoadCustomPromptGuidelineContentAsync(FileAttachment fileAttachment)
{
if (!fileAttachment.Exists)
{
this.customPromptingGuidelineContent = string.Empty;
this.Snackbar.Add(T("The selected custom prompt guide file could not be found."), Severity.Warning);
return;
}
try
{
this.isLoadingCustomPromptGuide = true;
this.customPromptingGuidelineContent = await UserFile.LoadFileData(fileAttachment.FilePath, this.RustService, this.DialogService);
if (string.IsNullOrWhiteSpace(this.customPromptingGuidelineContent))
this.Snackbar.Add(T("The custom prompt guide file is empty or could not be read."), Severity.Warning);
}
catch
{
this.customPromptingGuidelineContent = string.Empty;
this.Snackbar.Add(T("Failed to load custom prompt guide content."), Severity.Error);
}
finally
{
this.isLoadingCustomPromptGuide = false;
this.StateHasChanged();
}
}
private async Task OpenPromptingGuidelineDialog()
{
var promptingGuideline = await ReadPromptingGuidelineAsync();
if (string.IsNullOrWhiteSpace(promptingGuideline))
{
this.Snackbar.Add(T("The prompting guideline file could not be loaded."), Severity.Warning);
return;
}
var dialogParameters = new DialogParameters<PromptingGuidelineDialog>
{
{ x => x.GuidelineMarkdown, promptingGuideline }
};
var dialogReference = await this.DialogService.ShowAsync<PromptingGuidelineDialog>(T("Prompting Guideline"), dialogParameters, AIStudio.Dialogs.DialogOptions.FULLSCREEN);
await dialogReference.Result;
}
private async Task OpenCustomPromptGuideDialog()
{
if (this.customPromptGuideFiles.Count == 0)
return;
var fileAttachment = this.customPromptGuideFiles.First();
if (string.IsNullOrWhiteSpace(this.customPromptingGuidelineContent) && !this.isLoadingCustomPromptGuide)
await this.LoadCustomPromptGuidelineContentAsync(fileAttachment);
var dialogParameters = new DialogParameters<DocumentCheckDialog>
{
{ x => x.Document, fileAttachment },
{ x => x.FileContent, this.customPromptingGuidelineContent },
};
await this.DialogService.ShowAsync<DocumentCheckDialog>(T("Custom Prompt Guide Preview"), dialogParameters, AIStudio.Dialogs.DialogOptions.FULLSCREEN);
}
}
@@ -0,0 +1,33 @@
using System.Text.Json.Serialization;
namespace AIStudio.Assistants.PromptOptimizer;
public sealed class PromptOptimizationResult
{
[JsonPropertyName("optimized_prompt")]
public string OptimizedPrompt { get; set; } = string.Empty;
[JsonPropertyName("recommendations")]
public PromptOptimizationRecommendations Recommendations { get; set; } = new();
}
public sealed class PromptOptimizationRecommendations
{
[JsonPropertyName("clarity_and_directness")]
public string ClarityAndDirectness { get; set; } = string.Empty;
[JsonPropertyName("examples_and_context")]
public string ExamplesAndContext { get; set; } = string.Empty;
[JsonPropertyName("sequential_steps")]
public string SequentialSteps { get; set; } = string.Empty;
[JsonPropertyName("structure_with_markers")]
public string StructureWithMarkers { get; set; } = string.Empty;
[JsonPropertyName("role_definition")]
public string RoleDefinition { get; set; } = string.Empty;
[JsonPropertyName("language_choice")]
public string LanguageChoice { get; set; } = string.Empty;
}
@@ -0,0 +1,85 @@
# 1 – Be Clear and Direct
LLMs respond best to clear, explicit instructions. Being specific about your desired output improves results. If you want high-quality work, ask for it directly rather than expecting the model to guess.
Think of the LLM as a skilled new employee: They do not know your specific workflows yet. The more precisely you explain what you want, the better the result.
**Golden Rule:** If a colleague would be confused by your prompt without extra context, the LLM will be too.
**Less Effective:**
```text
Create an analytics dashboard
```
**More Effective:**
```text
Create an analytics dashboard. Include relevant features and interactions. Go beyond the basics to create a fully-featured implementation.
```
# 2 – Add Examples and Context to Improve Performance
Providing examples, context, or the reason behind your instructions helps the model understand your goals.
**Less Effective:**
```text
NEVER use ellipses
```
**More Effective:**
```text
Your response will be read aloud by a text-to-speech engine, so never use ellipses since the engine will not know how to pronounce them.
```
The model can generalize from the explanation.
# 3 – Use Sequential Steps
When the order of tasks matters, provide instructions as a numbered list.
**Example:**
```text
1. Analyze the provided text for key themes.
2. Extract the top 5 most frequent terms.
3. Format the output as a table with columns: Term, Frequency, Context.
```
# 4 – Structure Prompts with Markers
Headings (e.g., `#` or `###`) or backticks (` `````` `) help the model parse complex prompts, especially when mixing instructions, context, and data.
**Less Effective:**
```text
{text input here}
Summarize the text above as a bullet point list of the most important points.
```
**More Effective:**
```text
# Text:
```{text input here}```
# Task:
Summarize the text above as a bullet point list of the most important points.
```
# 5 – Give the LLM a Role
Setting a role in your prompt focuses the LLM's behavior and tone. Even a single sentence makes a difference.
**Example:**
```text
You are a helpful coding assistant specializing in Python.
```
```text
You are a senior marketing expert with 10 years of experience in the aerospace industry.
```
# 6 – Prompt Language
LLMs are primarily trained on English text. They generally perform best with prompts written in **English**, especially for complex tasks.
* **Recommendation:** Write your prompts in English.
* **If needed:** You can ask the LLM to respond in your native language (e.g., "Answer in German").
* **Note:** This is especially important for smaller models, which may have limited multilingual capabilities.