Skip to content

Commit 3e59f23

Browse files
Added a rewrite and text improvement assistant (#73)
1 parent 05a7e44 commit 3e59f23

15 files changed

+302
-11
lines changed

app/MindWork AI Studio/Components/AssistantBase.razor

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
</MudForm>
1818
<Issues IssuesData="@this.inputIssues"/>
1919

20-
@if (this.isProcessing)
20+
@if (this.ShowDedicatedProgress && this.isProcessing)
2121
{
2222
<MudProgressLinear Color="Color.Primary" Indeterminate="true" Class="mb-6" />
2323
}

app/MindWork AI Studio/Components/AssistantBase.razor.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ public abstract partial class AssistantBase : ComponentBase
3636
private protected virtual RenderFragment? Body => null;
3737

3838
protected virtual bool ShowResult => true;
39+
40+
protected virtual bool ShowDedicatedProgress => false;
3941

4042
protected virtual IReadOnlyList<ButtonData> FooterButtons => [];
4143

@@ -143,6 +145,11 @@ protected async Task<string> AddAIResponseAsync(DateTimeOffset time)
143145
return aiText.Text;
144146
}
145147

148+
protected async Task CopyToClipboard(string text)
149+
{
150+
await this.Rust.CopyText2Clipboard(this.JsRuntime, this.Snackbar, text);
151+
}
152+
146153
private static string? GetButtonIcon(string icon)
147154
{
148155
if(string.IsNullOrWhiteSpace(icon))

app/MindWork AI Studio/Components/Pages/Assistants.razor

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
<AssistantBlock Name="Text Summarizer" Description="Using a LLM to summarize a given text." Icon="@Icons.Material.Filled.TextSnippet" Link="/assistant/summarizer"/>
1414
<AssistantBlock Name="Translation" Description="Translate text into another language." Icon="@Icons.Material.Filled.Translate" Link="/assistant/translation"/>
1515
<AssistantBlock Name="Grammar & Spelling" Description="Check grammar and spelling of a given text." Icon="@Icons.Material.Filled.Edit" Link="/assistant/grammar-spelling"/>
16+
<AssistantBlock Name="Rewrite & Improve" Description="Rewrite and improve a given text for a chosen style." Icon="@Icons.Material.Filled.Edit" Link="/assistant/rewrite-improve"/>
1617
</MudStack>
1718

1819
<MudText Typo="Typo.h4" Class="mb-2 mr-3 mt-6">

app/MindWork AI Studio/Components/Pages/GrammarSpelling/AssistantGrammarSpelling.razor.cs

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ namespace AIStudio.Components.Pages.GrammarSpelling;
44

55
public partial class AssistantGrammarSpelling : AssistantBaseCore
66
{
7-
protected override string Title => "Grammar and Spelling Checker";
7+
protected override string Title => "Grammar & Spelling Checker";
88

99
protected override string Description =>
1010
"""
@@ -23,10 +23,28 @@ Germany and German in Austria differ. You receive text as input. You check the s
2323

2424
protected override bool ShowResult => false;
2525

26+
protected override bool ShowDedicatedProgress => true;
27+
2628
protected override IReadOnlyList<ButtonData> FooterButtons => new[]
2729
{
28-
new ButtonData("Copy corrected text", Icons.Material.Filled.ContentCopy, Color.Default, string.Empty, this.CopyToClipboard),
30+
new ButtonData("Copy result", Icons.Material.Filled.ContentCopy, Color.Default, string.Empty, () => this.CopyToClipboard(this.correctedText)),
2931
};
32+
33+
#region Overrides of ComponentBase
34+
35+
protected override async Task OnInitializedAsync()
36+
{
37+
if (this.SettingsManager.ConfigurationData.GrammarSpelling.PreselectOptions)
38+
{
39+
this.selectedTargetLanguage = this.SettingsManager.ConfigurationData.GrammarSpelling.PreselectedTargetLanguage;
40+
this.customTargetLanguage = this.SettingsManager.ConfigurationData.GrammarSpelling.PreselectedOtherLanguage;
41+
this.providerSettings = this.SettingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == this.SettingsManager.ConfigurationData.GrammarSpelling.PreselectedProvider);
42+
}
43+
44+
await base.OnInitializedAsync();
45+
}
46+
47+
#endregion
3048

3149
private string inputText = string.Empty;
3250
private CommonLanguages selectedTargetLanguage;
@@ -67,6 +85,7 @@ private string SystemPromptLanguage()
6785

6886
private async Task ProofreadText()
6987
{
88+
await this.form!.Validate();
7089
if (!this.inputIsValid)
7190
return;
7291

@@ -76,9 +95,4 @@ private async Task ProofreadText()
7695
this.correctedText = await this.AddAIResponseAsync(time);
7796
await this.JsRuntime.GenerateAndShowDiff(this.inputText, this.correctedText);
7897
}
79-
80-
private async Task CopyToClipboard()
81-
{
82-
await this.Rust.CopyText2Clipboard(this.JsRuntime, this.Snackbar, this.correctedText);
83-
}
8498
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
@using AIStudio.Tools
2+
@page "/assistant/rewrite-improve"
3+
@inherits AssistantBaseCore
4+
5+
<MudTextField T="string" @bind-Text="@this.inputText" Validation="@this.ValidateText" AdornmentIcon="@Icons.Material.Filled.DocumentScanner" Adornment="Adornment.Start" Label="Your input to improve" Variant="Variant.Outlined" Lines="6" AutoGrow="@true" MaxLines="12" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
6+
<EnumSelection T="CommonLanguages" NameFunc="@(language => language.NameSelectingOptional())" @bind-Value="@this.selectedTargetLanguage" Icon="@Icons.Material.Filled.Translate" Label="Language" AllowOther="@true" OtherValue="CommonLanguages.OTHER" @bind-OtherInput="@this.customTargetLanguage" ValidateOther="@this.ValidateCustomLanguage" LabelOther="Custom language" />
7+
<EnumSelection T="WritingStyles" NameFunc="@(style => style.Name())" @bind-Value="@this.selectedWritingStyle" Icon="@Icons.Material.Filled.Edit" Label="Writing style" AllowOther="@false" />
8+
<ProviderSelection @bind-ProviderSettings="@this.providerSettings" ValidateProvider="@this.ValidatingProvider"/>
9+
10+
<MudButton Variant="Variant.Filled" Class="mb-3" OnClick="() => this.RewriteText()">
11+
Improve
12+
</MudButton>
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
using AIStudio.Tools;
2+
3+
namespace AIStudio.Components.Pages.RewriteImprove;
4+
5+
public partial class AssistantRewriteImprove : AssistantBaseCore
6+
{
7+
protected override string Title => "Rewrite & Improve Text";
8+
9+
protected override string Description =>
10+
"""
11+
Rewrite and improve your text. Please note, that the capabilities of the different LLM providers will vary.
12+
""";
13+
14+
protected override string SystemPrompt =>
15+
$"""
16+
You are an expert in language and style. You receive a text as input. First, you review the text. If no
17+
changes are needed, you return the text without modifications. If a change is necessary, you improve the
18+
text. You can also correct spelling and grammar issues. You never add additional information. You never
19+
ask the user for additional information. Your response only contains the improved text. You do not explain
20+
your changes. If no changes are needed, you return the text unchanged.
21+
The style of the text: {this.selectedWritingStyle.Prompt()}. You follow the rules according
22+
to {this.SystemPromptLanguage()} in all your changes.
23+
""";
24+
25+
protected override bool ShowResult => false;
26+
27+
#region Overrides of AssistantBase
28+
29+
protected override bool ShowDedicatedProgress => true;
30+
31+
#endregion
32+
33+
protected override IReadOnlyList<ButtonData> FooterButtons => new[]
34+
{
35+
new ButtonData("Copy result", Icons.Material.Filled.ContentCopy, Color.Default, string.Empty, () => this.CopyToClipboard(this.rewrittenText)),
36+
};
37+
38+
#region Overrides of ComponentBase
39+
40+
protected override async Task OnInitializedAsync()
41+
{
42+
if (this.SettingsManager.ConfigurationData.RewriteImprove.PreselectOptions)
43+
{
44+
this.selectedTargetLanguage = this.SettingsManager.ConfigurationData.RewriteImprove.PreselectedTargetLanguage;
45+
this.customTargetLanguage = this.SettingsManager.ConfigurationData.RewriteImprove.PreselectedOtherLanguage;
46+
this.providerSettings = this.SettingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == this.SettingsManager.ConfigurationData.RewriteImprove.PreselectedProvider);
47+
this.selectedWritingStyle = this.SettingsManager.ConfigurationData.RewriteImprove.PreselectedWritingStyle;
48+
}
49+
50+
await base.OnInitializedAsync();
51+
}
52+
53+
#endregion
54+
55+
private string inputText = string.Empty;
56+
private CommonLanguages selectedTargetLanguage;
57+
private string customTargetLanguage = string.Empty;
58+
private string rewrittenText = string.Empty;
59+
private WritingStyles selectedWritingStyle;
60+
61+
private string? ValidateText(string text)
62+
{
63+
if(string.IsNullOrWhiteSpace(text))
64+
return "Please provide a text as input. You might copy the desired text from a document or a website.";
65+
66+
return null;
67+
}
68+
69+
private string? ValidateCustomLanguage(string language)
70+
{
71+
if(this.selectedTargetLanguage == CommonLanguages.OTHER && string.IsNullOrWhiteSpace(language))
72+
return "Please provide a custom language.";
73+
74+
return null;
75+
}
76+
77+
private string SystemPromptLanguage()
78+
{
79+
var lang = this.selectedTargetLanguage switch
80+
{
81+
CommonLanguages.AS_IS => "the source language",
82+
CommonLanguages.OTHER => this.customTargetLanguage,
83+
84+
_ => $"{this.selectedTargetLanguage.Name()}",
85+
};
86+
87+
if (string.IsNullOrWhiteSpace(lang))
88+
return "the source language";
89+
90+
return lang;
91+
}
92+
93+
private async Task RewriteText()
94+
{
95+
await this.form!.Validate();
96+
if (!this.inputIsValid)
97+
return;
98+
99+
this.CreateChatThread();
100+
var time = this.AddUserRequest(this.inputText);
101+
102+
this.rewrittenText = await this.AddAIResponseAsync(time);
103+
await this.JsRuntime.GenerateAndShowDiff(this.inputText, this.rewrittenText);
104+
}
105+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
namespace AIStudio.Components.Pages.RewriteImprove;
2+
3+
public enum WritingStyles
4+
{
5+
NOT_SPECIFIED = 0,
6+
7+
EVERYDAY,
8+
BUSINESS,
9+
SCIENTIFIC,
10+
JOURNALISTIC,
11+
LITERARY,
12+
TECHNICAL,
13+
MARKETING,
14+
ACADEMIC,
15+
LEGAL,
16+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
namespace AIStudio.Components.Pages.RewriteImprove;
2+
3+
public static class WritingStylesExtensions
4+
{
5+
public static string Name(this WritingStyles style)
6+
{
7+
return style switch
8+
{
9+
WritingStyles.EVERYDAY => "Everyday (personal texts, social media)",
10+
WritingStyles.BUSINESS => "Business (business emails, reports, presentations)",
11+
WritingStyles.SCIENTIFIC => "Scientific (scientific papers, research reports)",
12+
WritingStyles.JOURNALISTIC => "Journalistic (magazines, newspapers, news)",
13+
WritingStyles.LITERARY => "Literary (fiction, poetry)",
14+
WritingStyles.TECHNICAL => "Technical (manuals, documentation)",
15+
WritingStyles.MARKETING => "Marketing (advertisements, sales texts)",
16+
WritingStyles.ACADEMIC => "Academic (essays, seminar papers)",
17+
WritingStyles.LEGAL => "Legal (legal texts, contracts)",
18+
19+
_ => "Not specified",
20+
};
21+
}
22+
23+
public static string Prompt(this WritingStyles style)
24+
{
25+
return style switch
26+
{
27+
WritingStyles.EVERYDAY => "Use a everyday style like for personal texts, social media, and informal communication.",
28+
WritingStyles.BUSINESS => "Use a business style like for business emails, reports, and presentations. Most important is clarity and professionalism.",
29+
WritingStyles.SCIENTIFIC => "Use a scientific style like for scientific papers, research reports, and academic writing. Most important is precision and objectivity.",
30+
WritingStyles.JOURNALISTIC => "Use a journalistic style like for magazines, newspapers, and news. Most important is readability and engaging content.",
31+
WritingStyles.LITERARY => "Use a literary style like for fiction, poetry, and creative writing. Most important is creativity and emotional impact.",
32+
WritingStyles.TECHNICAL => "Use a technical style like for manuals, documentation, and technical writing. Most important is clarity and precision.",
33+
WritingStyles.MARKETING => "Use a marketing style like for advertisements, sales texts, and promotional content. Most important is persuasiveness and engagement.",
34+
WritingStyles.ACADEMIC => "Use a academic style like for essays, seminar papers, and academic writing. Most important is clarity and objectivity.",
35+
WritingStyles.LEGAL => "Use a legal style like for legal texts, contracts, and official documents. Most important is precision and legal correctness. Use formal legal language.",
36+
37+
_ => "Keep the style of the text as it is.",
38+
};
39+
}
40+
}

0 commit comments

Comments
 (0)