Skip to content

Add an information view to all data sources #273

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
9ce140c
Formatting
SommerEngineering Jan 23, 2025
094daed
Added file info extensions
SommerEngineering Jan 23, 2025
e9b6bd8
Added local file information view
SommerEngineering Jan 23, 2025
bf7cf13
Updated readme
SommerEngineering Jan 23, 2025
fa849d3
Added long extensions
SommerEngineering Jan 23, 2025
d3bc838
Refactored to use the long extension
SommerEngineering Jan 23, 2025
d56690b
Add DirectoryInfoExtensions to calculate directory size and file coun…
SommerEngineering Jan 23, 2025
90683a5
Refactored & added the text info line component
SommerEngineering Jan 23, 2025
1e32ae6
Added the spellchecking attribute
SommerEngineering Jan 23, 2025
be8fd18
Added a text info lines component
SommerEngineering Jan 23, 2025
6ac122b
Added a done callback
SommerEngineering Jan 23, 2025
7dcf7a1
Implemented the local directory info dialog
SommerEngineering Jan 23, 2025
5426434
Added comment about disposing the response object
SommerEngineering Jan 29, 2025
abaa4fa
Improved the resource handling when loading models.
SommerEngineering Jan 29, 2025
da76be2
Added a ERI ((E)xternal (R)etrieval (I)nterface) client for communica…
SommerEngineering Jan 29, 2025
5c4103f
Optimized documentation
SommerEngineering Jan 29, 2025
c6050e6
Migration to use the new ERI client
SommerEngineering Jan 29, 2025
c73a49d
Fixed property naming policy for ERI JSON messages
SommerEngineering Jan 29, 2025
6c1981e
Added provider type extensions to explain the different options
SommerEngineering Jan 29, 2025
8f5010d
Add periodic UI refresh using a timer and ensure proper disposal when…
SommerEngineering Feb 5, 2025
0e390f0
Implemented the ERI v1 info dialog
SommerEngineering Feb 9, 2025
676597e
Relocate the progress bar to the footer
SommerEngineering Feb 9, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Things we are currently working on:
- [x] ~~App: Add an option to show preview features (PR [#222](https://github.com/MindWorkAI/AI-Studio/pull/222))~~
- [x] ~~App: Configure embedding providers (PR [#224](https://github.com/MindWorkAI/AI-Studio/pull/224))~~
- [x] ~~App: Implement an [ERI](https://github.com/MindWorkAI/ERI) server coding assistant (PR [#231](https://github.com/MindWorkAI/AI-Studio/pull/231))~~
- [x] ~~App: Management of data sources (local & external data via [ERI](https://github.com/MindWorkAI/ERI)) (PR [#259](https://github.com/MindWorkAI/AI-Studio/pull/259))~~
- [x] ~~App: Management of data sources (local & external data via [ERI](https://github.com/MindWorkAI/ERI)) (PR [#259](https://github.com/MindWorkAI/AI-Studio/pull/259), [#273](https://github.com/MindWorkAI/AI-Studio/pull/273))~~
- [ ] Runtime: Extract data from txt / md / pdf / docx / xlsx files
- [ ] (*Optional*) Runtime: Implement internal embedding provider through [fastembed-rs](https://github.com/Anush008/fastembed-rs)
- [ ] App: Implement external embedding providers
Expand Down
1,277 changes: 0 additions & 1,277 deletions app/ERIClientV1/Client.Generated.cs

This file was deleted.

10 changes: 0 additions & 10 deletions app/ERIClientV1/ERIClientV1.csproj

This file was deleted.

9 changes: 0 additions & 9 deletions app/MindWork AI Studio.sln
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,6 @@
Microsoft Visual Studio Solution File, Format Version 12.00
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MindWork AI Studio", "MindWork AI Studio\MindWork AI Studio.csproj", "{059FDFCC-7D0B-474E-9F20-B9C437DF1CDD}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ERIClients", "ERIClients", "{5C2AF789-287B-4FCB-B675-7273D8CD4579}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ERIClientV1", "ERIClientV1\ERIClientV1.csproj", "{9E35A273-0FA6-4BD5-8880-A1DDAC106926}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -16,12 +12,7 @@ Global
{059FDFCC-7D0B-474E-9F20-B9C437DF1CDD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{059FDFCC-7D0B-474E-9F20-B9C437DF1CDD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{059FDFCC-7D0B-474E-9F20-B9C437DF1CDD}.Release|Any CPU.Build.0 = Release|Any CPU
{9E35A273-0FA6-4BD5-8880-A1DDAC106926}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9E35A273-0FA6-4BD5-8880-A1DDAC106926}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9E35A273-0FA6-4BD5-8880-A1DDAC106926}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9E35A273-0FA6-4BD5-8880-A1DDAC106926}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{9E35A273-0FA6-4BD5-8880-A1DDAC106926} = {5C2AF789-287B-4FCB-B675-7273D8CD4579}
EndGlobalSection
EndGlobal
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ public static async Task<string> ReadSpecification(this ERIVersion version, Http
try
{
var url = version.SpecificationURL();
var response = await httpClient.GetAsync(url);
using var response = await httpClient.GetAsync(url);
return await response.Content.ReadAsStringAsync();
}
catch
Expand Down
2 changes: 1 addition & 1 deletion app/MindWork AI Studio/Components/Changelog.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ protected override async Task OnInitializedAsync()

private async Task ReadLogAsync()
{
var response = await this.HttpClient.GetAsync($"changelog/{this.SelectedLog.Filename}");
using var response = await this.HttpClient.GetAsync($"changelog/{this.SelectedLog.Filename}");
this.LogContent = await response.Content.ReadAsStringAsync();
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
@using AIStudio.Settings
@using AIStudio.Settings.DataModel
@inherits SettingsPanelBase

Expand Down Expand Up @@ -37,12 +36,7 @@
<MudTd>@this.GetEmbeddingName(context)</MudTd>

<MudTd Style="text-align: left;">
@if (context is IERIDataSource)
{
@* <MudButton Variant="Variant.Filled" Color="Color.Info" StartIcon="@Icons.Material.Filled.Info" Class="ma-2" OnClick="() => this.ShowInformation(context)"> *@
@* Show Information *@
@* </MudButton> *@
}
<MudIconButton Variant="Variant.Filled" Color="Color.Info" Icon="@Icons.Material.Filled.Info" Class="ma-2" OnClick="() => this.ShowInformation(context)"/>
<MudButton Variant="Variant.Filled" Color="Color.Info" StartIcon="@Icons.Material.Filled.Edit" Class="ma-2" OnClick="() => this.EditDataSource(context)">
Edit
</MudButton>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
using AIStudio.Dialogs;
using AIStudio.Settings;
using AIStudio.Settings.DataModel;

using ERI_Client.V1;
using AIStudio.Tools.ERIClient.DataModel;

using Microsoft.AspNetCore.Components;

Expand Down Expand Up @@ -216,10 +215,37 @@ private async Task DeleteDataSource(IDataSource dataSource)
}
}

private Task ShowInformation(IDataSource dataSource)
private async Task ShowInformation(IDataSource dataSource)
{
#warning Implement the information dialog for ERI data sources.
return Task.CompletedTask;
switch (dataSource)
{
case DataSourceLocalFile localFile:
var localFileDialogParameters = new DialogParameters<DataSourceLocalFileInfoDialog>
{
{ x => x.DataSource, localFile },
};

await this.DialogService.ShowAsync<DataSourceLocalFileInfoDialog>("Local File Data Source Information", localFileDialogParameters, DialogOptions.FULLSCREEN);
break;

case DataSourceLocalDirectory localDirectory:
var localDirectoryDialogParameters = new DialogParameters<DataSourceLocalDirectoryInfoDialog>
{
{ x => x.DataSource, localDirectory },
};

await this.DialogService.ShowAsync<DataSourceLocalDirectoryInfoDialog>("Local Directory Data Source Information", localDirectoryDialogParameters, DialogOptions.FULLSCREEN);
break;

case DataSourceERI_V1 eriV1DataSource:
var eriV1DialogParameters = new DialogParameters<DataSourceERI_V1InfoDialog>
{
{ x => x.DataSource, eriV1DataSource },
};

await this.DialogService.ShowAsync<DataSourceERI_V1InfoDialog>("ERI v1 Data Source Information", eriV1DialogParameters, DialogOptions.FULLSCREEN);
break;
}
}

private async Task UpdateDataSources()
Expand Down
19 changes: 19 additions & 0 deletions app/MindWork AI Studio/Components/TextInfoLine.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<MudStack Row="@true" AlignItems="AlignItems.Center">
<MudTextField
T="string"
ReadOnly="@true"
Label="@this.Label"
Text="@this.Value"
Variant="Variant.Outlined"
Margin="Margin.Dense"
Adornment="Adornment.Start"
AdornmentIcon="@this.Icon"
UserAttributes="@USER_INPUT_ATTRIBUTES" />

@if (this.ShowingCopyButton)
{
<MudTooltip Text="@this.ClipboardTooltip">
<MudIconButton Icon="@Icons.Material.Filled.ContentCopy" Size="Size.Medium" OnClick="@(() => this.CopyToClipboard(this.Value))"/>
</MudTooltip>
}
</MudStack>
50 changes: 50 additions & 0 deletions app/MindWork AI Studio/Components/TextInfoLine.razor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
using AIStudio.Settings;

using Microsoft.AspNetCore.Components;

namespace AIStudio.Components;

public partial class TextInfoLine : ComponentBase
{
[Parameter]
public string Label { get; set; } = string.Empty;

[Parameter]
public string Icon { get; set; } = Icons.Material.Filled.Info;

[Parameter]
public string Value { get; set; } = string.Empty;

[Parameter]
public string ClipboardTooltipSubject { get; set; } = "the text";

[Parameter]
public bool ShowingCopyButton { get; set; } = true;

[Inject]
private RustService RustService { get; init; } = null!;

[Inject]
private ISnackbar Snackbar { get; init; } = null!;

[Inject]
private SettingsManager SettingsManager { get; init; } = null!;

#region Overrides of ComponentBase

protected override async Task OnInitializedAsync()
{
// Configure the spellchecking for the user input:
this.SettingsManager.InjectSpellchecking(USER_INPUT_ATTRIBUTES);

await base.OnInitializedAsync();
}

#endregion

private static readonly Dictionary<string, object?> USER_INPUT_ATTRIBUTES = new();

private string ClipboardTooltip => $"Copy {this.ClipboardTooltipSubject} to the clipboard";

private async Task CopyToClipboard(string content) => await this.RustService.CopyText2Clipboard(this.Snackbar, content);
}
20 changes: 20 additions & 0 deletions app/MindWork AI Studio/Components/TextInfoLines.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<MudStack Row="@true" AlignItems="AlignItems.Start">
<MudTextField
T="string"
ReadOnly="@true"
Label="@this.Label"
Text="@this.Value"
Variant="Variant.Outlined"
Margin="Margin.Dense"
Lines="3"
MaxLines="@this.MaxLines"
AutoGrow="@true"
UserAttributes="@USER_INPUT_ATTRIBUTES" />

@if (this.ShowingCopyButton)
{
<MudTooltip Text="@this.ClipboardTooltip">
<MudIconButton Icon="@Icons.Material.Filled.ContentCopy" Size="Size.Medium" OnClick="@(() => this.CopyToClipboard(this.Value))"/>
</MudTooltip>
}
</MudStack>
50 changes: 50 additions & 0 deletions app/MindWork AI Studio/Components/TextInfoLines.razor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
using AIStudio.Settings;

using Microsoft.AspNetCore.Components;

namespace AIStudio.Components;

public partial class TextInfoLines : ComponentBase
{
[Parameter]
public string Label { get; set; } = string.Empty;

[Parameter]
public string Value { get; set; } = string.Empty;

[Parameter]
public string ClipboardTooltipSubject { get; set; } = "the text";

[Parameter]
public int MaxLines { get; set; } = 30;

[Parameter]
public bool ShowingCopyButton { get; set; } = true;

[Inject]
private RustService RustService { get; init; } = null!;

[Inject]
private ISnackbar Snackbar { get; init; } = null!;

[Inject]
private SettingsManager SettingsManager { get; init; } = null!;

#region Overrides of ComponentBase

protected override async Task OnInitializedAsync()
{
// Configure the spellchecking for the user input:
this.SettingsManager.InjectSpellchecking(USER_INPUT_ATTRIBUTES);

await base.OnInitializedAsync();
}

#endregion

private static readonly Dictionary<string, object?> USER_INPUT_ATTRIBUTES = new();

private string ClipboardTooltip => $"Copy {this.ClipboardTooltipSubject} to the clipboard";

private async Task CopyToClipboard(string content) => await this.RustService.CopyText2Clipboard(this.Snackbar, content);
}
101 changes: 101 additions & 0 deletions app/MindWork AI Studio/Dialogs/DataSourceERI-V1InfoDialog.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
@using AIStudio.Tools.ERIClient.DataModel
<MudDialog>
<DialogContent>

<MudText Typo="Typo.h5">
Common data source information
</MudText>

<TextInfoLine Icon="@Icons.Material.Filled.Tag" Label="Data source name" Value="@this.DataSource.Name" ClipboardTooltipSubject="the data source name"/>
<TextInfoLine Icon="@Icons.Material.Filled.NetworkCheck" Label="ERI server hostname" Value="@this.DataSource.Hostname" ClipboardTooltipSubject="the ERI server hostname"/>
<TextInfoLine Icon="@Icons.Material.Filled.Tag" Label="ERI server port" Value="@this.Port" ClipboardTooltipSubject="the ERI server port"/>

@if (!this.IsConnectionEncrypted())
{
<MudJustifiedText Typo="Typo.body1" Color="Color.Error" Class="mb-3">
Please note: the connection to the ERI v1 server is not encrypted. This means that all
data sent to the server is transmitted in plain text. Please ask the ERI server administrator
to enable encryption.
</MudJustifiedText>
}

@if (this.DataSource.AuthMethod is AuthMethod.USERNAME_PASSWORD)
{
<TextInfoLine Icon="@Icons.Material.Filled.Person2" Label="Username" Value="@this.DataSource.Username" ClipboardTooltipSubject="the username"/>
}

<TextInfoLines Label="Server description" MaxLines="14" Value="@this.serverDescription" ClipboardTooltipSubject="the server description"/>
<TextInfoLines Label="Security requirements" MaxLines="3" Value="@this.securityRequirements.Explain()" ClipboardTooltipSubject="the security requirements"/>

<MudText Typo="Typo.h5" Class="mt-6">
Retrieval information
</MudText>
@if (!this.retrievalInfoformation.Any())
{
<MudJustifiedText Typo="Typo.body1" Color="Color.Info" Class="mb-3">
The data source does not provide any retrieval information.
</MudJustifiedText>
}
else
{
<MudExpansionPanels Class="mb-3">
@for (var index = 0; index < this.retrievalInfoformation.Count; index++)
{
var info = this.retrievalInfoformation[index];
<ExpansionPanel HeaderText="@this.RetrievalName(info)" HeaderIcon="@Icons.Material.Filled.Info" IsExpanded="index == 0">
<TextInfoLines Label="Description" MaxLines="14" Value="@info.Description" ClipboardTooltipSubject="the retrieval description"/>
<TextInfoLines Label="Parameters" MaxLines="14" Value="@this.RetrievalParameters(info)" ClipboardTooltipSubject="the retrieval parameters"/>

@if (!string.IsNullOrWhiteSpace(info.Link))
{
<MudButton Href="@info.Link" Target="_blank" Class="mt-3" Color="Color.Primary" StartIcon="@Icons.Material.Filled.OpenInNew">
Open web link, show more information
</MudButton>
}

<MudText Typo="Typo.h6" Class="mt-3">
Embeddings
</MudText>
@if (!info.Embeddings.Any())
{
<MudJustifiedText Typo="Typo.body1" Color="Color.Info" Class="mb-3">
The data source does not provide any embedding information.
</MudJustifiedText>
}
else
{
<MudExpansionPanels>
@for (var embeddingIndex = 0; embeddingIndex < info.Embeddings.Count; embeddingIndex++)
{
var embedding = info.Embeddings[embeddingIndex];
<ExpansionPanel HeaderText="@embedding.EmbeddingName" HeaderIcon="@Icons.Material.Filled.Info" IsExpanded="embeddingIndex == 0">
<TextInfoLine Icon="@Icons.Material.Filled.FormatShapes" Label="Type" Value="@embedding.EmbeddingType" ClipboardTooltipSubject="the embedding type"/>
<TextInfoLines Label="Description" MaxLines="14" Value="@embedding.Description" ClipboardTooltipSubject="the embedding description"/>
<TextInfoLines Label="When to use" MaxLines="3" Value="@embedding.UsedWhen" ClipboardTooltipSubject="when is the embedding used"/>

@if (!string.IsNullOrWhiteSpace(embedding.Link))
{
<MudButton Href="@embedding.Link" Target="_blank" Class="mt-3" Color="Color.Primary" StartIcon="@Icons.Material.Filled.OpenInNew">
Open web link, show more information
</MudButton>
}
</ExpansionPanel>
}
</MudExpansionPanels>
}
</ExpansionPanel>
}
</MudExpansionPanels>
}

<Issues IssuesData="@this.dataIssues"/>
</DialogContent>
<DialogActions>
@if (this.IsOperationInProgress)
{
<MudProgressLinear Color="Color.Primary" Indeterminate="true" Class="ml-5 mr-5"/>
}
<MudButton OnClick="@this.GetERIMetadata" Variant="Variant.Filled" Color="Color.Info">Reload</MudButton>
<MudButton OnClick="@this.Close" Variant="Variant.Filled">Close</MudButton>
</DialogActions>
</MudDialog>
Loading