AI-Studio/app/MindWork AI Studio/Components/Pages/IconFinder/AssistantIconFinder.razor.cs

134 lines
4.3 KiB
C#
Raw Normal View History

2024-07-14 13:15:15 +00:00
using AIStudio.Chat;
using AIStudio.Provider;
using AIStudio.Settings;
using Microsoft.AspNetCore.Components;
namespace AIStudio.Components.Pages.IconFinder;
public partial class AssistantIconFinder : ComponentBase
{
[Inject]
private SettingsManager SettingsManager { get; set; } = null!;
[Inject]
public IJSRuntime JsRuntime { get; init; } = null!;
[Inject]
public Random RNG { get; set; } = null!;
private ChatThread? chatThread;
private ContentBlock? resultingContentBlock;
private AIStudio.Settings.Provider selectedProvider;
private MudForm form = null!;
private bool inputIsValid;
private string[] inputIssues = [];
private string inputContext = string.Empty;
private IconSources selectedIconSource;
#region Overrides of ComponentBase
protected override async Task OnAfterRenderAsync(bool firstRender)
{
// Reset the validation when not editing and on the first render.
// We don't want to show validation errors when the user opens the dialog.
if(firstRender)
this.form.ResetValidation();
await base.OnAfterRenderAsync(firstRender);
}
#endregion
private string? ValidatingContext(string context)
{
if(string.IsNullOrWhiteSpace(context))
return "Please provide a context. This will help the AI to find the right icon. You might type just a keyword or copy a sentence from your text, e.g., from a slide where you want to use the icon.";
return null;
}
private string? ValidatingProvider(AIStudio.Settings.Provider provider)
{
if(provider.UsedProvider == Providers.NONE)
return "Please select a provider.";
return null;
}
private async Task FindIcon()
{
await this.form.Validate();
if (!this.inputIsValid)
return;
//
// Create a new chat thread:
//
this.chatThread = new()
{
WorkspaceId = Guid.Empty,
ChatId = Guid.NewGuid(),
Name = string.Empty,
Seed = this.RNG.Next(),
SystemPrompt = SYSTEM_PROMPT,
Blocks = [],
};
//
// Add the user's request to the thread:
//
var time = DateTimeOffset.Now;
this.chatThread.Blocks.Add(new ContentBlock
{
Time = time,
ContentType = ContentType.TEXT,
Role = ChatRole.USER,
Content = new ContentText
{
Text =
$"""
{this.selectedIconSource.Prompt()} I search for an icon for the following context:
```
{this.inputContext}
```
""",
},
});
//
// Add the AI response to the thread:
//
var aiText = new ContentText
{
// We have to wait for the remote
// for the content stream:
InitialRemoteWait = true,
};
this.resultingContentBlock = new ContentBlock
{
Time = time,
ContentType = ContentType.TEXT,
Role = ChatRole.AI,
Content = aiText,
};
this.chatThread?.Blocks.Add(this.resultingContentBlock);
// Use the selected provider to get the AI response.
// By awaiting this line, we wait for the entire
// content to be streamed.
await aiText.CreateFromProviderAsync(this.selectedProvider.UsedProvider.CreateProvider(this.selectedProvider.InstanceName, this.selectedProvider.Hostname), this.JsRuntime, this.SettingsManager, this.selectedProvider.Model, this.chatThread);
}
private const string SYSTEM_PROMPT =
"""
I can search for icons using US English keywords. Please help me come up with the right search queries.
I don't want you to translate my requests word-for-word into US English. Instead, you should provide keywords
that are likely to yield suitable icons. For example, I might ask for an icon about departments, but icons
related to the keyword "buildings" might be the best match. Provide your keywords in a Markdown list without
quotation marks.
""";
}