using AIStudio.Components;
using AIStudio.Settings;
using AIStudio.Settings.DataModel;
using AIStudio.Tools.ToolCallingSystem;
using Microsoft.AspNetCore.Components;
namespace AIStudio.Assistants.ModelComparison;
///
/// One line with the setup both models of a comparison series work with: the profile, the tools, the data sources, and
/// how both chats search them.
///
///
/// The user needs this when deciding which chat helped more: unneeded sources in an answer may come from classic RAG,
/// which searches with every message, rather than from the model. A part which no longer exists is named as such, so
/// that the line still tells what the series began with.
///
public partial class ModelComparisonSeriesSetupLine : MSGComponentBase
{
///
/// Gets or sets the series.
///
[Parameter, EditorRequired]
public ModelComparisonSeries Series { get; set; } = null!;
///
/// Gets or sets the classes of the line.
///
[Parameter]
public string Class { get; set; } = string.Empty;
[Inject]
private ToolRegistry ToolRegistry { get; init; } = null!;
///
/// The series which the texts below were built from.
///
private ModelComparisonSeries? shownSeries;
private string profileText = string.Empty;
private string toolsText = string.Empty;
private string dataSourcesText = string.Empty;
#region Overrides of ComponentBase
protected override async Task OnParametersSetAsync()
{
await base.OnParametersSetAsync();
if (ReferenceEquals(this.shownSeries, this.Series))
return;
this.shownSeries = this.Series;
this.profileText = this.ProfileText();
this.toolsText = await this.ToolsTextAsync();
this.dataSourcesText = this.DataSourcesText();
}
#endregion
private string ProfileText()
{
if (string.IsNullOrWhiteSpace(this.Series.ProfileId) || string.Equals(this.Series.ProfileId, Profile.NO_PROFILE.Id, StringComparison.OrdinalIgnoreCase))
return T("No profile");
var profile = this.SettingsManager.GetProfileById(this.Series.ProfileId);
return profile == Profile.NO_PROFILE
? T("Profile: no longer available")
: string.Format(T("Profile: {0}"), profile.Name);
}
private async Task ToolsTextAsync()
{
var toolIds = this.Series.ToolIds.Distinct(StringComparer.Ordinal).ToList();
if (toolIds.Count == 0)
return T("No tools");
List names = [];
foreach (var toolId in toolIds)
if (await this.ToolRegistry.GetCatalogItemAsync(toolId) is { } item)
names.Add(item.DisplayName);
return string.Format(T("Tools: {0}"), this.ListOf(names, toolIds.Count - names.Count));
}
private string DataSourcesText()
{
if (this.Series.DataSourceIds.Count == 0)
return T("No data sources");
var names = this.Series.DataSourceIds
.Select(dataSourceId => this.SettingsManager.ConfigurationData.DataSources.FirstOrDefault(dataSource => dataSource.Id == dataSourceId)?.Name)
.OfType()
.ToList();
var retrieval = this.Series.RetrievalMode is DataSourceRetrievalMode.EVERY_MESSAGE ? T("classic RAG") : T("Semantic Search");
return string.Format(T("Data sources: {0} ({1})"), this.ListOf(names, this.Series.DataSourceIds.Count - names.Count), retrieval);
}
///
/// Lists names, followed by how many no longer exist.
///
private string ListOf(List names, int missingCount)
{
if (missingCount > 0)
names.Add(string.Format(T("{0} no longer available"), missingCount));
return string.Join(", ", names);
}
}