Skip to content

Commit 2494ee2

Browse files
Create I18N data, part 2 (#429)
1 parent 90bd450 commit 2494ee2

File tree

90 files changed

+4649
-1111
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

90 files changed

+4649
-1111
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ Things we are currently working on:
3131
- [x] ~~Plan & implement the base plugin system ([PR #322](https://github.com/MindWorkAI/AI-Studio/pull/322))~~
3232
- [x] ~~Start the plugin system ([PR #372](https://github.com/MindWorkAI/AI-Studio/pull/372))~~
3333
- [x] ~~Added hot-reload support for plugins ([PR #377](https://github.com/MindWorkAI/AI-Studio/pull/377), [PR #391](https://github.com/MindWorkAI/AI-Studio/pull/391))~~
34-
- [ ] Add support for other languages (I18N) to AI Studio (~~[PR #381](https://github.com/MindWorkAI/AI-Studio/pull/381), [PR #400](https://github.com/MindWorkAI/AI-Studio/pull/400), [PR #404](https://github.com/MindWorkAI/AI-Studio/pull/404))~~
34+
- [ ] Add support for other languages (I18N) to AI Studio (~~[PR #381](https://github.com/MindWorkAI/AI-Studio/pull/381), [PR #400](https://github.com/MindWorkAI/AI-Studio/pull/400), [PR #404](https://github.com/MindWorkAI/AI-Studio/pull/404), [PR #429](https://github.com/MindWorkAI/AI-Studio/pull/429))~~
3535
- [x] ~~Add an I18N assistant to translate all AI Studio texts to a certain language & culture ([PR #422](https://github.com/MindWorkAI/AI-Studio/pull/422))~~
3636
- [ ] Provide MindWork AI Studio in German ([#31](https://github.com/MindWorkAI/Planning/issues/31))
3737
- [ ] Add configuration plugins, which allow pre-defining some LLM providers in organizations

app/Build/Commands/CollectI18NKeysCommand.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,14 +146,23 @@ private List<string> FindAllTextTags(ReadOnlySpan<char> fileContent)
146146
var content = fileContent;
147147
while (startIdx > -1)
148148
{
149+
//
150+
// In some cases, after the initial " there follow more " characters.
151+
// We need to skip them:
152+
//
149153
content = content[(startIdx + START_TAG.Length)..];
154+
while(content[0] == '"')
155+
content = content[1..];
156+
150157
var endIdx = content.IndexOf(END_TAG);
151158
if (endIdx == -1)
152159
break;
153160

154161
var match = content[..endIdx];
155-
matches.Add(match.ToString());
162+
while (match[^1] == '"')
163+
match = match[..^1];
156164

165+
matches.Add(match.ToString());
157166
startIdx = content.IndexOf(START_TAG);
158167
}
159168

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

Lines changed: 4 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,8 @@
1313

1414
namespace AIStudio.Assistants;
1515

16-
public abstract partial class AssistantBase<TSettings> : AssistantLowerBase, IMessageBusReceiver, IDisposable where TSettings : IComponent
16+
public abstract partial class AssistantBase<TSettings> : AssistantLowerBase where TSettings : IComponent
1717
{
18-
[Inject]
19-
protected SettingsManager SettingsManager { get; init; } = null!;
20-
2118
[Inject]
2219
private IDialogService DialogService { get; init; } = null!;
2320

@@ -42,9 +39,6 @@ public abstract partial class AssistantBase<TSettings> : AssistantLowerBase, IMe
4239
[Inject]
4340
private MudTheme ColorTheme { get; init; } = null!;
4441

45-
[Inject]
46-
private MessageBus MessageBus { get; init; } = null!;
47-
4842
protected abstract string Title { get; }
4943

5044
protected abstract string Description { get; }
@@ -119,10 +113,6 @@ protected override async Task OnInitializedAsync()
119113
this.MightPreselectValues();
120114
this.providerSettings = this.SettingsManager.GetPreselectedProvider(this.Component);
121115
this.currentProfile = this.SettingsManager.GetPreselectedProfile(this.Component);
122-
123-
this.MessageBus.RegisterComponent(this);
124-
this.MessageBus.ApplyFilters(this, [], [ Event.COLOR_THEME_CHANGED ]);
125-
126116
await base.OnInitializedAsync();
127117
}
128118

@@ -144,29 +134,6 @@ protected override async Task OnAfterRenderAsync(bool firstRender)
144134
await base.OnAfterRenderAsync(firstRender);
145135
}
146136

147-
#endregion
148-
149-
#region Implementation of IMessageBusReceiver
150-
151-
public string ComponentName => nameof(AssistantBase<TSettings>);
152-
153-
public Task ProcessMessage<T>(ComponentBase? sendingComponent, Event triggeredEvent, T? data)
154-
{
155-
switch (triggeredEvent)
156-
{
157-
case Event.COLOR_THEME_CHANGED:
158-
this.StateHasChanged();
159-
break;
160-
}
161-
162-
return Task.CompletedTask;
163-
}
164-
165-
public Task<TResult?> ProcessMessageWithResult<TPayload, TResult>(ComponentBase? sendingComponent, Event triggeredEvent, TPayload? data)
166-
{
167-
return Task.FromResult<TResult?>(default);
168-
}
169-
170137
#endregion
171138

172139
private string SubmitButtonStyle => this.SettingsManager.ConfigurationData.LLMProviders.ShowProviderConfidence ? this.providerSettings.UsedLLMProvider.GetConfidence(this.SettingsManager).StyleBorder(this.SettingsManager) : string.Empty;
@@ -226,7 +193,7 @@ protected void CreateChatThread()
226193
SystemPrompt = this.SystemPrompt,
227194
WorkspaceId = Guid.Empty,
228195
ChatId = Guid.NewGuid(),
229-
Name = $"Assistant - {this.Title}",
196+
Name = string.Format(T("Assistant - {0}"), this.Title),
230197
Seed = this.RNG.Next(),
231198
Blocks = [],
232199
};
@@ -399,11 +366,10 @@ private async Task InnerResetForm()
399366
false => $"background-color: {this.ColorTheme.GetCurrentPalette(this.SettingsManager).InfoLighten}",
400367
};
401368

402-
#region Implementation of IDisposable
369+
#region Overrides of MSGComponentBase
403370

404-
public void Dispose()
371+
protected override void DisposeResources()
405372
{
406-
this.MessageBus.Unregister(this);
407373
this.formChangeTimer.Dispose();
408374
}
409375

app/MindWork AI Studio/Assistants/AssistantLowerBase.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
using Microsoft.AspNetCore.Components;
1+
using AIStudio.Components;
22

33
namespace AIStudio.Assistants;
44

5-
public abstract class AssistantLowerBase : ComponentBase
5+
public abstract class AssistantLowerBase : MSGComponentBase
66
{
77
protected static readonly Dictionary<string, object?> USER_INPUT_ATTRIBUTES = new();
88

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,25 @@
11
@attribute [Route(Routes.ASSISTANT_EMAIL)]
22
@inherits AssistantBaseCore<AIStudio.Dialogs.Settings.SettingsDialogWritingEMails>
33

4-
<MudTextSwitch Label="Is there a history, a previous conversation?" @bind-Value="@this.provideHistory" LabelOn="Yes, I provide the previous conversation" LabelOff="No, I don't provide a previous conversation" />
4+
<MudTextSwitch Label="@T("Is there a history, a previous conversation?")" @bind-Value="@this.provideHistory" LabelOn="@T("Yes, I provide the previous conversation")" LabelOff="@T("No, I don't provide a previous conversation")" />
55
@if (this.provideHistory)
66
{
77
<MudPaper Class="pa-3 mb-8 border-dashed border rounded-lg">
8-
<MudTextField T="string" @bind-Text="@this.inputHistory" Validation="@this.ValidateHistory" Label="Previous conversation" Variant="Variant.Outlined" Lines="6" AutoGrow="@true" MaxLines="12" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES" HelperText="Provide the previous conversation, e.g., the last e-mail, the last chat, etc." Class="mb-3" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.DocumentScanner"/>
8+
<MudTextField T="string" @bind-Text="@this.inputHistory" Validation="@this.ValidateHistory" Label="@T("Previous conversation")" Variant="Variant.Outlined" Lines="6" AutoGrow="@true" MaxLines="12" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES" HelperText="@T("Provide the previous conversation, e.g., the last e-mail, the last chat, etc.")" Class="mb-3" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.DocumentScanner"/>
99
</MudPaper>
1010
}
1111
12-
<MudTextField T="string" @bind-Text="@this.inputGreeting" Label="(Optional) The greeting phrase to use" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Person" Variant="Variant.Outlined" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES" Placeholder="Dear Colleagues" Class="mb-3"/>
13-
<MudTextField T="string" @bind-Text="@this.inputBulletPoints" Validation="@this.ValidateBulletPoints" AdornmentIcon="@Icons.Material.Filled.ListAlt" Adornment="Adornment.Start" Label="Your bullet points" Variant="Variant.Outlined" Lines="6" AutoGrow="@true" MaxLines="12" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES" HelperText="Bullet list the content of the e-mail roughly. Use dashes (-) to separate the items." Immediate="@false" DebounceInterval="1_000" OnDebounceIntervalElapsed="@this.OnContentChanged" Placeholder="@PLACEHOLDER_BULLET_POINTS"/>
14-
<MudSelect T="string" Label="(Optional) Are any of your points particularly important?" MultiSelection="@true" @bind-SelectedValues="@this.selectedFoci" Variant="Variant.Outlined" Class="mb-3" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.ListAlt">
12+
<MudTextField T="string" @bind-Text="@this.inputGreeting" Label="@T("(Optional) The greeting phrase to use")" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Person" Variant="Variant.Outlined" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES" Placeholder="@T("Dear Colleagues")" Class="mb-3"/>
13+
<MudTextField T="string" @bind-Text="@this.inputBulletPoints" Validation="@this.ValidateBulletPoints" AdornmentIcon="@Icons.Material.Filled.ListAlt" Adornment="Adornment.Start" Label="@T("Your bullet points")" Variant="Variant.Outlined" Lines="6" AutoGrow="@true" MaxLines="12" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES" HelperText="@T("Bullet list the content of the e-mail roughly. Use dashes (-) to separate the items.")" Immediate="@false" DebounceInterval="1_000" OnDebounceIntervalElapsed="@this.OnContentChanged" Placeholder="@PLACEHOLDER_BULLET_POINTS"/>
14+
<MudSelect T="string" Label="@T("(Optional) Are any of your points particularly important?")" MultiSelection="@true" @bind-SelectedValues="@this.selectedFoci" Variant="Variant.Outlined" Class="mb-3" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.ListAlt">
1515
@foreach (var contentLine in this.bulletPointsLines)
1616
{
17-
<MudSelectItem T="string" Value="@contentLine">@contentLine</MudSelectItem>
17+
<MudSelectItem T="string" Value="@contentLine">
18+
@contentLine
19+
</MudSelectItem>
1820
}
1921
</MudSelect>
20-
<MudTextField T="string" @bind-Text="@this.inputName" Label="(Optional) Your name for the closing salutation" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Person" Variant="Variant.Outlined" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES" HelperText="Your name for the closing salutation of your e-mail." Class="mb-3"/>
21-
<EnumSelection T="WritingStyles" NameFunc="@(style => style.Name())" @bind-Value="@this.selectedWritingStyle" Icon="@Icons.Material.Filled.Edit" Label="Select the writing style" ValidateSelection="@this.ValidateWritingStyle"/>
22-
<EnumSelection T="CommonLanguages" NameFunc="@(language => language.NameSelecting())" @bind-Value="@this.selectedTargetLanguage" ValidateSelection="@this.ValidateTargetLanguage" Icon="@Icons.Material.Filled.Translate" Label="Target language" AllowOther="@true" OtherValue="CommonLanguages.OTHER" @bind-OtherInput="@this.customTargetLanguage" ValidateOther="@this.ValidateCustomLanguage" LabelOther="Custom target language" />
22+
<MudTextField T="string" @bind-Text="@this.inputName" Label="@T("(Optional) Your name for the closing salutation")" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Person" Variant="Variant.Outlined" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES" HelperText="@T("Your name for the closing salutation of your e-mail.")" Class="mb-3"/>
23+
<EnumSelection T="WritingStyles" NameFunc="@(style => style.Name())" @bind-Value="@this.selectedWritingStyle" Icon="@Icons.Material.Filled.Edit" Label="@T("Select the writing style")" ValidateSelection="@this.ValidateWritingStyle"/>
24+
<EnumSelection T="CommonLanguages" NameFunc="@(language => language.NameSelecting())" @bind-Value="@this.selectedTargetLanguage" ValidateSelection="@this.ValidateTargetLanguage" Icon="@Icons.Material.Filled.Translate" Label="@T("Target language")" AllowOther="@true" OtherValue="CommonLanguages.OTHER" @bind-OtherInput="@this.customTargetLanguage" ValidateOther="@this.ValidateCustomLanguage" LabelOther="@T("Custom target language")" />
2325
<ProviderSelection @bind-ProviderSettings="@this.providerSettings" ValidateProvider="@this.ValidatingProvider"/>

app/MindWork AI Studio/Assistants/EMail/AssistantEMail.razor.cs

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,9 @@ public partial class AssistantEMail : AssistantBaseCore<SettingsDialogWritingEMa
99
{
1010
public override Tools.Components Component => Tools.Components.EMAIL_ASSISTANT;
1111

12-
protected override string Title => "E-Mail";
12+
protected override string Title => T("E-Mail");
1313

14-
protected override string Description =>
15-
"""
16-
Provide a list of bullet points and some basic information for an e-mail. The assistant will generate an e-mail based on that input.
17-
""";
14+
protected override string Description => T("Provide a list of bullet points and some basic information for an e-mail. The assistant will generate an e-mail based on that input.");
1815

1916
protected override string SystemPrompt =>
2017
$"""
@@ -25,7 +22,7 @@ public partial class AssistantEMail : AssistantBaseCore<SettingsDialogWritingEMa
2522

2623
protected override IReadOnlyList<IButtonData> FooterButtons => [];
2724

28-
protected override string SubmitText => "Create email";
25+
protected override string SubmitText => T("Create email");
2926

3027
protected override Func<Task> SubmitAction => this.CreateMail;
3128

@@ -100,44 +97,44 @@ protected override async Task OnInitializedAsync()
10097
private string? ValidateBulletPoints(string content)
10198
{
10299
if(string.IsNullOrWhiteSpace(content))
103-
return "Please provide some content for the e-mail.";
100+
return T("Please provide some content for the e-mail.");
104101

105102
var lines = content.Split('\n', StringSplitOptions.RemoveEmptyEntries);
106103
foreach (var line in lines)
107104
if(!line.TrimStart().StartsWith('-'))
108-
return "Please start each line of your content list with a dash (-) to create a bullet point list.";
105+
return T("Please start each line of your content list with a dash (-) to create a bullet point list.");
109106

110107
return null;
111108
}
112109

113110
private string? ValidateTargetLanguage(CommonLanguages language)
114111
{
115112
if(language is CommonLanguages.AS_IS)
116-
return "Please select a target language for the e-mail.";
113+
return T("Please select a target language for the e-mail.");
117114

118115
return null;
119116
}
120117

121118
private string? ValidateCustomLanguage(string language)
122119
{
123120
if(this.selectedTargetLanguage == CommonLanguages.OTHER && string.IsNullOrWhiteSpace(language))
124-
return "Please provide a custom language.";
121+
return T("Please provide a custom language.");
125122

126123
return null;
127124
}
128125

129126
private string? ValidateWritingStyle(WritingStyles style)
130127
{
131128
if(style == WritingStyles.NONE)
132-
return "Please select a writing style for the e-mail.";
129+
return T("Please select a writing style for the e-mail.");
133130

134131
return null;
135132
}
136133

137134
private string? ValidateHistory(string history)
138135
{
139136
if(this.provideHistory && string.IsNullOrWhiteSpace(history))
140-
return "Please provide some history for the e-mail.";
137+
return T("Please provide some history for the e-mail.");
141138

142139
return null;
143140
}
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
@attribute [Route(Routes.ASSISTANT_GRAMMAR_SPELLING)]
22
@inherits AssistantBaseCore<AIStudio.Dialogs.Settings.SettingsDialogGrammarSpelling>
33

4-
<MudTextField T="string" @bind-Text="@this.inputText" Validation="@this.ValidateText" AdornmentIcon="@Icons.Material.Filled.DocumentScanner" Adornment="Adornment.Start" Label="Your input to check" Variant="Variant.Outlined" Lines="6" AutoGrow="@true" MaxLines="12" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
5-
<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" />
4+
<MudTextField T="string" @bind-Text="@this.inputText" Validation="@this.ValidateText" AdornmentIcon="@Icons.Material.Filled.DocumentScanner" Adornment="Adornment.Start" Label="@T("Your input to check")" Variant="Variant.Outlined" Lines="6" AutoGrow="@true" MaxLines="12" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
5+
<EnumSelection T="CommonLanguages" NameFunc="@(language => language.NameSelectingOptional())" @bind-Value="@this.selectedTargetLanguage" Icon="@Icons.Material.Filled.Translate" Label="@T("Language")" AllowOther="@true" OtherValue="CommonLanguages.OTHER" @bind-OtherInput="@this.customTargetLanguage" ValidateOther="@this.ValidateCustomLanguage" LabelOther="@T("Custom language")" />
66
<ProviderSelection @bind-ProviderSettings="@this.providerSettings" ValidateProvider="@this.ValidatingProvider"/>

app/MindWork AI Studio/Assistants/GrammarSpelling/AssistantGrammarSpelling.razor.cs

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,9 @@ public partial class AssistantGrammarSpelling : AssistantBaseCore<SettingsDialog
77
{
88
public override Tools.Components Component => Tools.Components.GRAMMAR_SPELLING_ASSISTANT;
99

10-
protected override string Title => "Grammar & Spelling Checker";
10+
protected override string Title => T("Grammar & Spelling Checker");
1111

12-
protected override string Description =>
13-
"""
14-
Check the grammar and spelling of a text.
15-
""";
12+
protected override string Description => T("Check the grammar and spelling of a text.");
1613

1714
protected override string SystemPrompt =>
1815
$"""
@@ -40,7 +37,7 @@ Germany and German in Austria differ. You receive text as input. You check the s
4037
},
4138
];
4239

43-
protected override string SubmitText => "Proofread";
40+
protected override string SubmitText => T("Proofread");
4441

4542
protected override Func<Task> SubmitAction => this.ProofreadText;
4643

@@ -93,15 +90,15 @@ protected override async Task OnInitializedAsync()
9390
private string? ValidateText(string text)
9491
{
9592
if(string.IsNullOrWhiteSpace(text))
96-
return "Please provide a text as input. You might copy the desired text from a document or a website.";
93+
return T("Please provide a text as input. You might copy the desired text from a document or a website.");
9794

9895
return null;
9996
}
10097

10198
private string? ValidateCustomLanguage(string language)
10299
{
103100
if(this.selectedTargetLanguage == CommonLanguages.OTHER && string.IsNullOrWhiteSpace(language))
104-
return "Please provide a custom language.";
101+
return T("Please provide a custom language.");
105102

106103
return null;
107104
}

app/MindWork AI Studio/Assistants/I18N/AssistantI18N.razor.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,5 +351,10 @@ private void Phase2CreateLuaCode()
351351
this.finalLuaCode.Clear();
352352
var commentContent = this.addedContent.Concat(PluginFactory.BaseLanguage.Content).ToDictionary();
353353
LuaTable.Create(ref this.finalLuaCode, "UI_TEXT_CONTENT", this.localizedContent, commentContent, this.cancellationTokenSource!.Token);
354+
355+
// Next, we must remove the `root::` prefix from the keys:
356+
this.finalLuaCode.Replace("""UI_TEXT_CONTENT["root::""", """
357+
UI_TEXT_CONTENT["
358+
""");
354359
}
355360
}

0 commit comments

Comments
 (0)