mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2025-04-28 10:39:47 +00:00
parent
a6b7357385
commit
8ac40a489b
@ -302,7 +302,7 @@ public abstract partial class AssistantBase<TSettings> : ComponentBase, IMessage
|
|||||||
// Use the selected provider to get the AI response.
|
// Use the selected provider to get the AI response.
|
||||||
// By awaiting this line, we wait for the entire
|
// By awaiting this line, we wait for the entire
|
||||||
// content to be streamed.
|
// content to be streamed.
|
||||||
this.chatThread = await aiText.CreateFromProviderAsync(this.providerSettings.CreateProvider(this.Logger), this.providerSettings.Model, this.lastUserPrompt, this.chatThread);
|
await aiText.CreateFromProviderAsync(this.providerSettings.CreateProvider(this.Logger), this.providerSettings.Model, this.lastUserPrompt, this.chatThread);
|
||||||
|
|
||||||
this.isProcessing = false;
|
this.isProcessing = false;
|
||||||
this.StateHasChanged();
|
this.StateHasChanged();
|
||||||
|
@ -292,7 +292,6 @@ public partial class AssistantERI : AssistantBaseCore<SettingsDialogERIServer>
|
|||||||
- You consider the security of the implementation by applying the Security by Design principle.
|
- You consider the security of the implementation by applying the Security by Design principle.
|
||||||
- Your output is formatted as Markdown. Code is formatted as code blocks. For every file, you
|
- Your output is formatted as Markdown. Code is formatted as code blocks. For every file, you
|
||||||
create a separate code block with its file path and name as chapter title.
|
create a separate code block with its file path and name as chapter title.
|
||||||
- Important: The JSON objects of the API messages use camel case for the data field names.
|
|
||||||
""");
|
""");
|
||||||
|
|
||||||
return sb.ToString();
|
return sb.ToString();
|
||||||
|
@ -12,6 +12,7 @@ public enum ChatRole
|
|||||||
USER,
|
USER,
|
||||||
AI,
|
AI,
|
||||||
AGENT,
|
AGENT,
|
||||||
|
RAG,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -40,16 +40,6 @@ public sealed record ChatThread
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public IReadOnlyList<DataSourceAgentSelected> AISelectedDataSources { get; set; } = [];
|
public IReadOnlyList<DataSourceAgentSelected> AISelectedDataSources { get; set; } = [];
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The augmented data for this chat thread. Will be inserted into the system prompt.
|
|
||||||
/// </summary>
|
|
||||||
public string AugmentedData { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The data security to use, derived from the data sources used so far.
|
|
||||||
/// </summary>
|
|
||||||
public DataSourceSecurity DataSecurity { get; set; } = DataSourceSecurity.NOT_SPECIFIED;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The name of the chat thread. Usually generated by an AI model or manually edited by the user.
|
/// The name of the chat thread. Usually generated by an AI model or manually edited by the user.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -84,48 +74,31 @@ public sealed record ChatThread
|
|||||||
/// <returns>The prepared system prompt.</returns>
|
/// <returns>The prepared system prompt.</returns>
|
||||||
public string PrepareSystemPrompt(SettingsManager settingsManager, ChatThread chatThread, ILogger logger)
|
public string PrepareSystemPrompt(SettingsManager settingsManager, ChatThread chatThread, ILogger logger)
|
||||||
{
|
{
|
||||||
var isAugmentedDataAvailable = !string.IsNullOrWhiteSpace(chatThread.AugmentedData);
|
|
||||||
var systemPromptWithAugmentedData = isAugmentedDataAvailable switch
|
|
||||||
{
|
|
||||||
true => $"""
|
|
||||||
{chatThread.SystemPrompt}
|
|
||||||
|
|
||||||
{chatThread.AugmentedData}
|
|
||||||
""",
|
|
||||||
|
|
||||||
false => chatThread.SystemPrompt,
|
|
||||||
};
|
|
||||||
|
|
||||||
if(isAugmentedDataAvailable)
|
|
||||||
logger.LogInformation("Augmented data is available for the chat thread.");
|
|
||||||
else
|
|
||||||
logger.LogInformation("No augmented data is available for the chat thread.");
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Prepare the system prompt:
|
// Prepare the system prompt:
|
||||||
//
|
//
|
||||||
string systemPromptText;
|
string systemPromptText;
|
||||||
var logMessage = $"Using no profile for chat thread '{chatThread.Name}'.";
|
var logMessage = $"Using no profile for chat thread '{chatThread.Name}'.";
|
||||||
if (string.IsNullOrWhiteSpace(chatThread.SelectedProfile))
|
if (string.IsNullOrWhiteSpace(chatThread.SelectedProfile))
|
||||||
systemPromptText = systemPromptWithAugmentedData;
|
systemPromptText = chatThread.SystemPrompt;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(!Guid.TryParse(chatThread.SelectedProfile, out var profileId))
|
if(!Guid.TryParse(chatThread.SelectedProfile, out var profileId))
|
||||||
systemPromptText = systemPromptWithAugmentedData;
|
systemPromptText = chatThread.SystemPrompt;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(chatThread.SelectedProfile == Profile.NO_PROFILE.Id || profileId == Guid.Empty)
|
if(chatThread.SelectedProfile == Profile.NO_PROFILE.Id || profileId == Guid.Empty)
|
||||||
systemPromptText = systemPromptWithAugmentedData;
|
systemPromptText = chatThread.SystemPrompt;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var profile = settingsManager.ConfigurationData.Profiles.FirstOrDefault(x => x.Id == chatThread.SelectedProfile);
|
var profile = settingsManager.ConfigurationData.Profiles.FirstOrDefault(x => x.Id == chatThread.SelectedProfile);
|
||||||
if(profile == default)
|
if(profile == default)
|
||||||
systemPromptText = systemPromptWithAugmentedData;
|
systemPromptText = chatThread.SystemPrompt;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
logMessage = $"Using profile '{profile.Name}' for chat thread '{chatThread.Name}'.";
|
logMessage = $"Using profile '{profile.Name}' for chat thread '{chatThread.Name}'.";
|
||||||
systemPromptText = $"""
|
systemPromptText = $"""
|
||||||
{systemPromptWithAugmentedData}
|
{chatThread.SystemPrompt}
|
||||||
|
|
||||||
{profile.ToSystemPrompt()}
|
{profile.ToSystemPrompt()}
|
||||||
""";
|
""";
|
||||||
|
@ -1,58 +0,0 @@
|
|||||||
using AIStudio.Provider.SelfHosted;
|
|
||||||
using AIStudio.Settings.DataModel;
|
|
||||||
|
|
||||||
namespace AIStudio.Chat;
|
|
||||||
|
|
||||||
public static class ChatThreadExtensions
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Checks if the specified provider is allowed for the chat thread.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// We don't check if the provider is allowed to use the data sources of the chat thread.
|
|
||||||
/// That kind of check is done in the RAG process itself.<br/><br/>
|
|
||||||
///
|
|
||||||
/// One thing which is not so obvious: after RAG was used on this thread, the entire chat
|
|
||||||
/// thread is kind of a data source by itself. Why? Because the augmentation data collected
|
|
||||||
/// from the data sources is stored in the chat thread. This means we must check if the
|
|
||||||
/// selected provider is allowed to use this thread's data.
|
|
||||||
/// </remarks>
|
|
||||||
/// <param name="chatThread">The chat thread to check.</param>
|
|
||||||
/// <param name="provider">The provider to check.</param>
|
|
||||||
/// <returns>True, when the provider is allowed for the chat thread. False, otherwise.</returns>
|
|
||||||
public static bool IsLLMProviderAllowed<T>(this ChatThread? chatThread, T provider)
|
|
||||||
{
|
|
||||||
// No chat thread available means we have a new chat. That's fine:
|
|
||||||
if (chatThread is null)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
// The chat thread is available, but the data security is not specified.
|
|
||||||
// Means, we never used RAG or RAG was enabled, but no data sources were selected.
|
|
||||||
// That's fine as well:
|
|
||||||
if (chatThread.DataSecurity is DataSourceSecurity.NOT_SPECIFIED)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Is the provider self-hosted?
|
|
||||||
//
|
|
||||||
var isSelfHostedProvider = provider switch
|
|
||||||
{
|
|
||||||
ProviderSelfHosted => true,
|
|
||||||
AIStudio.Settings.Provider p => p.IsSelfHosted,
|
|
||||||
|
|
||||||
_ => false,
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
|
||||||
// Check the chat data security against the selected provider:
|
|
||||||
//
|
|
||||||
return isSelfHostedProvider switch
|
|
||||||
{
|
|
||||||
// The provider is self-hosted -- we can use any data source:
|
|
||||||
true => true,
|
|
||||||
|
|
||||||
// The provider is not self-hosted -- it depends on the data security of the chat thread:
|
|
||||||
false => chatThread.DataSecurity is not DataSourceSecurity.SELF_HOSTED,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
@ -27,7 +27,7 @@
|
|||||||
@if (this.IsLastContentBlock && this.Role is ChatRole.AI && this.RegenerateFunc is not null)
|
@if (this.IsLastContentBlock && this.Role is ChatRole.AI && this.RegenerateFunc is not null)
|
||||||
{
|
{
|
||||||
<MudTooltip Text="Regenerate" Placement="Placement.Bottom">
|
<MudTooltip Text="Regenerate" Placement="Placement.Bottom">
|
||||||
<MudIconButton Icon="@Icons.Material.Filled.Recycling" Color="Color.Default" Disabled="@(!this.RegenerateEnabled())" OnClick="@this.RegenerateBlock"/>
|
<MudIconButton Icon="@Icons.Material.Filled.Recycling" Color="Color.Default" OnClick="@this.RegenerateBlock"/>
|
||||||
</MudTooltip>
|
</MudTooltip>
|
||||||
}
|
}
|
||||||
@if (this.RemoveBlockFunc is not null)
|
@if (this.RemoveBlockFunc is not null)
|
||||||
|
@ -28,7 +28,7 @@ public sealed class ContentImage : IContent, IImageSource
|
|||||||
public Func<Task> StreamingEvent { get; set; } = () => Task.CompletedTask;
|
public Func<Task> StreamingEvent { get; set; } = () => Task.CompletedTask;
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public Task<ChatThread> CreateFromProviderAsync(IProvider provider, Model chatModel, IContent? lastPrompt, ChatThread? chatChatThread, CancellationToken token = default)
|
public Task CreateFromProviderAsync(IProvider provider, Model chatModel, IContent? lastPrompt, ChatThread? chatChatThread, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
@ -36,31 +36,16 @@ public sealed class ContentText : IContent
|
|||||||
public Func<Task> StreamingEvent { get; set; } = () => Task.CompletedTask;
|
public Func<Task> StreamingEvent { get; set; } = () => Task.CompletedTask;
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public async Task<ChatThread> CreateFromProviderAsync(IProvider provider, Model chatModel, IContent? lastPrompt, ChatThread? chatThread, CancellationToken token = default)
|
public async Task CreateFromProviderAsync(IProvider provider, Model chatModel, IContent? lastPrompt, ChatThread? chatThread, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
if(chatThread is null)
|
if(chatThread is null)
|
||||||
return new();
|
return;
|
||||||
|
|
||||||
if(!chatThread.IsLLMProviderAllowed(provider))
|
|
||||||
{
|
|
||||||
var logger = Program.SERVICE_PROVIDER.GetService<ILogger<ContentText>>()!;
|
|
||||||
logger.LogError("The provider is not allowed for this chat thread due to data security reasons. Skipping the AI process.");
|
|
||||||
return chatThread;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Call the RAG process. Right now, we only have one RAG process:
|
// Call the RAG process. Right now, we only have one RAG process:
|
||||||
if (lastPrompt is not null)
|
if (lastPrompt is not null)
|
||||||
{
|
{
|
||||||
try
|
var rag = new AISrcSelWithRetCtxVal();
|
||||||
{
|
chatThread = await rag.ProcessAsync(provider, lastPrompt, chatThread, token);
|
||||||
var rag = new AISrcSelWithRetCtxVal();
|
|
||||||
chatThread = await rag.ProcessAsync(provider, lastPrompt, chatThread, token);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
var logger = Program.SERVICE_PROVIDER.GetService<ILogger<ContentText>>()!;
|
|
||||||
logger.LogError(e, "Skipping the RAG process due to an error.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store the last time we got a response. We use this later
|
// Store the last time we got a response. We use this later
|
||||||
@ -122,7 +107,6 @@ public sealed class ContentText : IContent
|
|||||||
|
|
||||||
// Inform the UI that the streaming is done:
|
// Inform the UI that the streaming is done:
|
||||||
await this.StreamingDone();
|
await this.StreamingDone();
|
||||||
return chatThread;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -41,7 +41,7 @@ public interface IContent
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Uses the provider to create the content.
|
/// Uses the provider to create the content.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Task<ChatThread> CreateFromProviderAsync(IProvider provider, Model chatModel, IContent? lastPrompt, ChatThread? chatChatThread, CancellationToken token = default);
|
public Task CreateFromProviderAsync(IProvider provider, Model chatModel, IContent? lastPrompt, ChatThread? chatChatThread, CancellationToken token = default);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns the corresponding ERI content type.
|
/// Returns the corresponding ERI content type.
|
||||||
|
@ -13,7 +13,6 @@ public partial class Changelog
|
|||||||
|
|
||||||
public static readonly Log[] LOGS =
|
public static readonly Log[] LOGS =
|
||||||
[
|
[
|
||||||
new (207, "v0.9.32, build 207 (2025-03-08 20:15 UTC)", "v0.9.32.md"),
|
|
||||||
new (206, "v0.9.31, build 206 (2025-03-03 15:33 UTC)", "v0.9.31.md"),
|
new (206, "v0.9.31, build 206 (2025-03-03 15:33 UTC)", "v0.9.31.md"),
|
||||||
new (205, "v0.9.30, build 205 (2025-02-24 19:55 UTC)", "v0.9.30.md"),
|
new (205, "v0.9.30, build 205 (2025-02-24 19:55 UTC)", "v0.9.30.md"),
|
||||||
new (204, "v0.9.29, build 204 (2025-02-24 13:48 UTC)", "v0.9.29.md"),
|
new (204, "v0.9.29, build 204 (2025-02-24 13:48 UTC)", "v0.9.29.md"),
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
IsLastContentBlock="@isLastBlock"
|
IsLastContentBlock="@isLastBlock"
|
||||||
IsSecondToLastBlock="@isSecondLastBlock"
|
IsSecondToLastBlock="@isSecondLastBlock"
|
||||||
RegenerateFunc="@this.RegenerateBlock"
|
RegenerateFunc="@this.RegenerateBlock"
|
||||||
RegenerateEnabled="@(() => this.IsProviderSelected && this.ChatThread.IsLLMProviderAllowed(this.Provider))"
|
RegenerateEnabled="@(() => this.IsProviderSelected)"
|
||||||
EditLastBlockFunc="@this.EditLastBlock"
|
EditLastBlockFunc="@this.EditLastBlock"
|
||||||
EditLastUserBlockFunc="@this.EditLastUserBlock"/>
|
EditLastUserBlockFunc="@this.EditLastUserBlock"/>
|
||||||
}
|
}
|
||||||
@ -46,7 +46,7 @@
|
|||||||
Adornment="Adornment.End"
|
Adornment="Adornment.End"
|
||||||
AdornmentIcon="@Icons.Material.Filled.Send"
|
AdornmentIcon="@Icons.Material.Filled.Send"
|
||||||
OnAdornmentClick="() => this.SendMessage()"
|
OnAdornmentClick="() => this.SendMessage()"
|
||||||
Disabled="@this.IsInputForbidden()"
|
ReadOnly="!this.IsProviderSelected || this.isStreaming"
|
||||||
Immediate="@true"
|
Immediate="@true"
|
||||||
OnKeyUp="this.InputKeyEvent"
|
OnKeyUp="this.InputKeyEvent"
|
||||||
UserAttributes="@USER_INPUT_ATTRIBUTES"
|
UserAttributes="@USER_INPUT_ATTRIBUTES"
|
||||||
@ -113,14 +113,6 @@
|
|||||||
{
|
{
|
||||||
<DataSourceSelection @ref="@this.dataSourceSelectionComponent" PopoverTriggerMode="PopoverTriggerMode.BUTTON" PopoverButtonClasses="ma-3" LLMProvider="@this.Provider" DataSourceOptions="@this.GetCurrentDataSourceOptions()" DataSourceOptionsChanged="@(async options => await this.SetCurrentDataSourceOptions(options))" DataSourcesAISelected="@this.GetAgentSelectedDataSources()"/>
|
<DataSourceSelection @ref="@this.dataSourceSelectionComponent" PopoverTriggerMode="PopoverTriggerMode.BUTTON" PopoverButtonClasses="ma-3" LLMProvider="@this.Provider" DataSourceOptions="@this.GetCurrentDataSourceOptions()" DataSourceOptionsChanged="@(async options => await this.SetCurrentDataSourceOptions(options))" DataSourcesAISelected="@this.GetAgentSelectedDataSources()"/>
|
||||||
}
|
}
|
||||||
|
|
||||||
@if (!this.ChatThread.IsLLMProviderAllowed(this.Provider))
|
|
||||||
{
|
|
||||||
<MudTooltip Text="The selected provider is not allowed in this chat due to data security reasons." Placement="@TOOLBAR_TOOLTIP_PLACEMENT">
|
|
||||||
<MudIconButton Icon="@Icons.Material.Filled.Error" Color="Color.Error"/>
|
|
||||||
</MudTooltip>
|
|
||||||
}
|
|
||||||
<MudIconButton />
|
|
||||||
</MudToolBar>
|
</MudToolBar>
|
||||||
</FooterContent>
|
</FooterContent>
|
||||||
</InnerScrolling>
|
</InnerScrolling>
|
@ -275,9 +275,6 @@ public partial class ChatComponent : MSGComponentBase, IAsyncDisposable
|
|||||||
{
|
{
|
||||||
var chatDefaultOptions = this.SettingsManager.ConfigurationData.Chat.PreselectedDataSourceOptions.CreateCopy();
|
var chatDefaultOptions = this.SettingsManager.ConfigurationData.Chat.PreselectedDataSourceOptions.CreateCopy();
|
||||||
this.earlyDataSourceOptions = chatDefaultOptions;
|
this.earlyDataSourceOptions = chatDefaultOptions;
|
||||||
if(this.ChatThread is not null)
|
|
||||||
this.ChatThread.DataSourceOptions = chatDefaultOptions;
|
|
||||||
|
|
||||||
this.dataSourceSelectionComponent?.ChangeOptionWithoutSaving(chatDefaultOptions);
|
this.dataSourceSelectionComponent?.ChangeOptionWithoutSaving(chatDefaultOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -340,20 +337,6 @@ public partial class ChatComponent : MSGComponentBase, IAsyncDisposable
|
|||||||
this.earlyDataSourceOptions = updatedOptions;
|
this.earlyDataSourceOptions = updatedOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool IsInputForbidden()
|
|
||||||
{
|
|
||||||
if (!this.IsProviderSelected)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if(this.isStreaming)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if(!this.ChatThread.IsLLMProviderAllowed(this.Provider))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task InputKeyEvent(KeyboardEventArgs keyEvent)
|
private async Task InputKeyEvent(KeyboardEventArgs keyEvent)
|
||||||
{
|
{
|
||||||
if(this.dataSourceSelectionComponent?.IsVisible ?? false)
|
if(this.dataSourceSelectionComponent?.IsVisible ?? false)
|
||||||
@ -388,9 +371,6 @@ public partial class ChatComponent : MSGComponentBase, IAsyncDisposable
|
|||||||
if (!this.IsProviderSelected)
|
if (!this.IsProviderSelected)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(!this.ChatThread.IsLLMProviderAllowed(this.Provider))
|
|
||||||
return;
|
|
||||||
|
|
||||||
// We need to blur the focus away from the input field
|
// We need to blur the focus away from the input field
|
||||||
// to be able to clear the field:
|
// to be able to clear the field:
|
||||||
await this.inputField.BlurAsync();
|
await this.inputField.BlurAsync();
|
||||||
@ -495,7 +475,7 @@ public partial class ChatComponent : MSGComponentBase, IAsyncDisposable
|
|||||||
// Use the selected provider to get the AI response.
|
// Use the selected provider to get the AI response.
|
||||||
// By awaiting this line, we wait for the entire
|
// By awaiting this line, we wait for the entire
|
||||||
// content to be streamed.
|
// content to be streamed.
|
||||||
this.ChatThread = await aiText.CreateFromProviderAsync(this.Provider.CreateProvider(this.Logger), this.Provider.Model, lastUserPrompt, this.ChatThread, this.cancellationTokenSource.Token);
|
await aiText.CreateFromProviderAsync(this.Provider.CreateProvider(this.Logger), this.Provider.Model, lastUserPrompt, this.ChatThread, this.cancellationTokenSource.Token);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.cancellationTokenSource = null;
|
this.cancellationTokenSource = null;
|
||||||
@ -793,9 +773,6 @@ public partial class ChatComponent : MSGComponentBase, IAsyncDisposable
|
|||||||
if(this.ChatThread is null)
|
if(this.ChatThread is null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(!this.ChatThread.IsLLMProviderAllowed(this.Provider))
|
|
||||||
return;
|
|
||||||
|
|
||||||
this.ChatThread.Remove(aiBlock, removeForRegenerate: true);
|
this.ChatThread.Remove(aiBlock, removeForRegenerate: true);
|
||||||
this.hasUnsavedChanges = true;
|
this.hasUnsavedChanges = true;
|
||||||
this.StateHasChanged();
|
this.StateHasChanged();
|
||||||
|
@ -42,49 +42,52 @@
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
<MudExpansionPanels Class="mb-3">
|
<MudExpansionPanels Class="mb-3">
|
||||||
<ExpansionPanel HeaderText="@this.RetrievalName(this.selectedRetrievalInfo)" HeaderIcon="@Icons.Material.Filled.Info">
|
@for (var index = 0; index < this.retrievalInfoformation.Count; index++)
|
||||||
<TextInfoLines Label="Description" MaxLines="14" Value="@this.selectedRetrievalInfo.Description" ClipboardTooltipSubject="the retrieval description"/>
|
{
|
||||||
<TextInfoLines Label="Parameters" MaxLines="14" Value="@this.RetrievalParameters(this.selectedRetrievalInfo)" ClipboardTooltipSubject="the retrieval parameters"/>
|
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(this.selectedRetrievalInfo.Link))
|
@if (!string.IsNullOrWhiteSpace(info.Link))
|
||||||
{
|
{
|
||||||
<MudButton Href="@this.selectedRetrievalInfo.Link" Target="_blank" Class="mt-3" Color="Color.Primary" StartIcon="@Icons.Material.Filled.OpenInNew">
|
<MudButton Href="@info.Link" Target="_blank" Class="mt-3" Color="Color.Primary" StartIcon="@Icons.Material.Filled.OpenInNew">
|
||||||
Open web link, show more information
|
Open web link, show more information
|
||||||
</MudButton>
|
</MudButton>
|
||||||
}
|
}
|
||||||
|
|
||||||
<MudText Typo="Typo.h6" Class="mt-3">
|
<MudText Typo="Typo.h6" Class="mt-3">
|
||||||
Embeddings
|
Embeddings
|
||||||
</MudText>
|
</MudText>
|
||||||
@* ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract *@
|
@if (!info.Embeddings.Any())
|
||||||
@if (this.selectedRetrievalInfo.Embeddings is null || !this.selectedRetrievalInfo.Embeddings.Any())
|
{
|
||||||
{
|
<MudJustifiedText Typo="Typo.body1" Color="Color.Info" Class="mb-3">
|
||||||
<MudJustifiedText Typo="Typo.body1" Color="Color.Info" Class="mb-3">
|
The data source does not provide any embedding information.
|
||||||
The data source does not provide any embedding information.
|
</MudJustifiedText>
|
||||||
</MudJustifiedText>
|
}
|
||||||
}
|
else
|
||||||
else
|
{
|
||||||
{
|
<MudExpansionPanels>
|
||||||
<MudExpansionPanels>
|
@for (var embeddingIndex = 0; embeddingIndex < info.Embeddings.Count; embeddingIndex++)
|
||||||
@for (var embeddingIndex = 0; embeddingIndex < this.selectedRetrievalInfo.Embeddings.Count; embeddingIndex++)
|
{
|
||||||
{
|
var embedding = info.Embeddings[embeddingIndex];
|
||||||
var embedding = this.selectedRetrievalInfo.Embeddings[embeddingIndex];
|
<ExpansionPanel HeaderText="@embedding.EmbeddingName" HeaderIcon="@Icons.Material.Filled.Info" IsExpanded="embeddingIndex == 0">
|
||||||
<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"/>
|
||||||
<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="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"/>
|
||||||
<TextInfoLines Label="When to use" MaxLines="3" Value="@embedding.UsedWhen" ClipboardTooltipSubject="when is the embedding used"/>
|
|
||||||
|
|
||||||
@if (!string.IsNullOrWhiteSpace(embedding.Link))
|
@if (!string.IsNullOrWhiteSpace(embedding.Link))
|
||||||
{
|
{
|
||||||
<MudButton Href="@embedding.Link" Target="_blank" Class="mt-3" Color="Color.Primary" StartIcon="@Icons.Material.Filled.OpenInNew">
|
<MudButton Href="@embedding.Link" Target="_blank" Class="mt-3" Color="Color.Primary" StartIcon="@Icons.Material.Filled.OpenInNew">
|
||||||
Open web link, show more information
|
Open web link, show more information
|
||||||
</MudButton>
|
</MudButton>
|
||||||
}
|
}
|
||||||
</ExpansionPanel>
|
</ExpansionPanel>
|
||||||
}
|
}
|
||||||
</MudExpansionPanels>
|
</MudExpansionPanels>
|
||||||
}
|
}
|
||||||
</ExpansionPanel>
|
</ExpansionPanel>
|
||||||
|
}
|
||||||
</MudExpansionPanels>
|
</MudExpansionPanels>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,7 +42,6 @@ public partial class DataSourceERI_V1InfoDialog : ComponentBase, IAsyncDisposabl
|
|||||||
private string serverDescription = string.Empty;
|
private string serverDescription = string.Empty;
|
||||||
private ProviderType securityRequirements = ProviderType.NONE;
|
private ProviderType securityRequirements = ProviderType.NONE;
|
||||||
private IReadOnlyList<RetrievalInfo> retrievalInfoformation = [];
|
private IReadOnlyList<RetrievalInfo> retrievalInfoformation = [];
|
||||||
private RetrievalInfo selectedRetrievalInfo;
|
|
||||||
|
|
||||||
private bool IsOperationInProgress { get; set; } = true;
|
private bool IsOperationInProgress { get; set; } = true;
|
||||||
|
|
||||||
@ -131,7 +130,7 @@ public partial class DataSourceERI_V1InfoDialog : ComponentBase, IAsyncDisposabl
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.retrievalInfoformation = retrievalInfoResult.Data ?? [];
|
this.retrievalInfoformation = retrievalInfoResult.Data ?? [];
|
||||||
this.selectedRetrievalInfo = this.retrievalInfoformation.FirstOrDefault(x => x.Id == this.DataSource.SelectedRetrievalId);
|
|
||||||
this.StateHasChanged();
|
this.StateHasChanged();
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
@ -110,24 +110,10 @@
|
|||||||
UserAttributes="@SPELLCHECK_ATTRIBUTES"/>
|
UserAttributes="@SPELLCHECK_ATTRIBUTES"/>
|
||||||
}
|
}
|
||||||
|
|
||||||
@if (this.availableRetrievalProcesses.Count > 0)
|
|
||||||
{
|
|
||||||
<MudSelect @bind-Value="@this.dataSelectedRetrievalProcess" Text="@this.dataSelectedRetrievalProcess.Name" Label="Select one retrieval process" Class="mb-3" OpenIcon="@Icons.Material.Filled.ExpandMore" AdornmentColor="Color.Info" Adornment="Adornment.Start" Validation="@this.dataSourceValidation.ValidateRetrievalProcess">
|
|
||||||
@foreach (var retrievalProcess in this.availableRetrievalProcesses)
|
|
||||||
{
|
|
||||||
<MudSelectItem Value="@retrievalProcess">
|
|
||||||
@retrievalProcess.Name
|
|
||||||
</MudSelectItem>
|
|
||||||
}
|
|
||||||
</MudSelect>
|
|
||||||
}
|
|
||||||
|
|
||||||
<MudSelect @bind-Value="@this.dataSecurityPolicy" Text="@this.dataSecurityPolicy.ToSelectionText()" Label="Your security policy" Class="mb-3" OpenIcon="@Icons.Material.Filled.ExpandMore" AdornmentColor="Color.Info" Adornment="Adornment.Start" Validation="@this.dataSourceValidation.ValidateSecurityPolicy">
|
<MudSelect @bind-Value="@this.dataSecurityPolicy" Text="@this.dataSecurityPolicy.ToSelectionText()" Label="Your security policy" Class="mb-3" OpenIcon="@Icons.Material.Filled.ExpandMore" AdornmentColor="Color.Info" Adornment="Adornment.Start" Validation="@this.dataSourceValidation.ValidateSecurityPolicy">
|
||||||
@foreach (var policy in Enum.GetValues<DataSourceSecurity>())
|
@foreach (var policy in Enum.GetValues<DataSourceSecurity>())
|
||||||
{
|
{
|
||||||
<MudSelectItem Value="@policy">
|
<MudSelectItem Value="@policy">@policy.ToSelectionText()</MudSelectItem>
|
||||||
@policy.ToSelectionText()
|
|
||||||
</MudSelectItem>
|
|
||||||
}
|
}
|
||||||
</MudSelect>
|
</MudSelect>
|
||||||
|
|
||||||
|
@ -8,8 +8,6 @@ using AIStudio.Tools.Validation;
|
|||||||
|
|
||||||
using Microsoft.AspNetCore.Components;
|
using Microsoft.AspNetCore.Components;
|
||||||
|
|
||||||
using RetrievalInfo = AIStudio.Tools.ERIClient.DataModel.RetrievalInfo;
|
|
||||||
|
|
||||||
// ReSharper disable InconsistentNaming
|
// ReSharper disable InconsistentNaming
|
||||||
namespace AIStudio.Dialogs;
|
namespace AIStudio.Dialogs;
|
||||||
|
|
||||||
@ -61,8 +59,6 @@ public partial class DataSourceERI_V1Dialog : ComponentBase, ISecretId
|
|||||||
private int dataPort;
|
private int dataPort;
|
||||||
private AuthMethod dataAuthMethod;
|
private AuthMethod dataAuthMethod;
|
||||||
private string dataUsername = string.Empty;
|
private string dataUsername = string.Empty;
|
||||||
private List<RetrievalInfo> availableRetrievalProcesses = [];
|
|
||||||
private RetrievalInfo dataSelectedRetrievalProcess;
|
|
||||||
|
|
||||||
// We get the form reference from Blazor code to validate it manually:
|
// We get the form reference from Blazor code to validate it manually:
|
||||||
private MudForm form = null!;
|
private MudForm form = null!;
|
||||||
@ -95,9 +91,6 @@ public partial class DataSourceERI_V1Dialog : ComponentBase, ISecretId
|
|||||||
// When editing, we need to load the data:
|
// When editing, we need to load the data:
|
||||||
if(this.IsEditing)
|
if(this.IsEditing)
|
||||||
{
|
{
|
||||||
//
|
|
||||||
// Assign the data to the form fields:
|
|
||||||
//
|
|
||||||
this.dataEditingPreviousInstanceName = this.DataSource.Name.ToLowerInvariant();
|
this.dataEditingPreviousInstanceName = this.DataSource.Name.ToLowerInvariant();
|
||||||
this.dataNum = this.DataSource.Num;
|
this.dataNum = this.DataSource.Num;
|
||||||
this.dataId = this.DataSource.Id;
|
this.dataId = this.DataSource.Id;
|
||||||
@ -121,12 +114,6 @@ public partial class DataSourceERI_V1Dialog : ComponentBase, ISecretId
|
|||||||
await this.form.Validate();
|
await this.form.Validate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load the data:
|
|
||||||
await this.TestConnection();
|
|
||||||
|
|
||||||
// Select the retrieval process:
|
|
||||||
this.dataSelectedRetrievalProcess = this.availableRetrievalProcesses.FirstOrDefault(n => n.Id == this.DataSource.SelectedRetrievalId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await base.OnInitializedAsync();
|
await base.OnInitializedAsync();
|
||||||
@ -166,7 +153,6 @@ public partial class DataSourceERI_V1Dialog : ComponentBase, ISecretId
|
|||||||
Username = this.dataUsername,
|
Username = this.dataUsername,
|
||||||
Type = DataSourceType.ERI_V1,
|
Type = DataSourceType.ERI_V1,
|
||||||
SecurityPolicy = this.dataSecurityPolicy,
|
SecurityPolicy = this.dataSecurityPolicy,
|
||||||
SelectedRetrievalId = this.dataSelectedRetrievalProcess.Id,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -238,18 +224,6 @@ public partial class DataSourceERI_V1Dialog : ComponentBase, ISecretId
|
|||||||
|
|
||||||
this.dataSourceSecurityRequirements = securityRequirementsRequest.Data;
|
this.dataSourceSecurityRequirements = securityRequirementsRequest.Data;
|
||||||
|
|
||||||
var retrievalInfoRequest = await client.GetRetrievalInfoAsync(cts.Token);
|
|
||||||
if (!retrievalInfoRequest.Successful)
|
|
||||||
{
|
|
||||||
await this.form.Validate();
|
|
||||||
|
|
||||||
Array.Resize(ref this.dataIssues, this.dataIssues.Length + 1);
|
|
||||||
this.dataIssues[^1] = retrievalInfoRequest.Message;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.availableRetrievalProcesses = retrievalInfoRequest.Data ?? [];
|
|
||||||
|
|
||||||
this.connectionTested = true;
|
this.connectionTested = true;
|
||||||
this.connectionSuccessfulTested = true;
|
this.connectionSuccessfulTested = true;
|
||||||
this.Logger.LogInformation("Connection to the ERI v1 server was successful tested.");
|
this.Logger.LogInformation("Connection to the ERI v1 server was successful tested.");
|
||||||
|
@ -46,7 +46,7 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="CodeBeam.MudBlazor.Extensions" Version="7.1.0" />
|
<PackageReference Include="CodeBeam.MudBlazor.Extensions" Version="7.1.0" />
|
||||||
<PackageReference Include="HtmlAgilityPack" Version="1.11.74" />
|
<PackageReference Include="HtmlAgilityPack" Version="1.11.72" />
|
||||||
<PackageReference Include="Microsoft.Extensions.FileProviders.Embedded" Version="9.0.2" />
|
<PackageReference Include="Microsoft.Extensions.FileProviders.Embedded" Version="9.0.2" />
|
||||||
<PackageReference Include="MudBlazor" Version="7.16.0" />
|
<PackageReference Include="MudBlazor" Version="7.16.0" />
|
||||||
<PackageReference Include="MudBlazor.Markdown" Version="7.14.0" />
|
<PackageReference Include="MudBlazor.Markdown" Version="7.14.0" />
|
||||||
|
@ -78,7 +78,6 @@
|
|||||||
<MudList T="string">
|
<MudList T="string">
|
||||||
<Supporter Name="DevNullx64" Type="SupporterType.INDIVIDUAL" URL="https://github.com/DevNullx64" Acknowledgment="Thanks Luc for your build script contribution."/>
|
<Supporter Name="DevNullx64" Type="SupporterType.INDIVIDUAL" URL="https://github.com/DevNullx64" Acknowledgment="Thanks Luc for your build script contribution."/>
|
||||||
<Supporter Name="SolsticeSpectrum" Type="SupporterType.INDIVIDUAL" URL="https://github.com/SolsticeSpectrum" Acknowledgment="Thanks for your build script contribution."/>
|
<Supporter Name="SolsticeSpectrum" Type="SupporterType.INDIVIDUAL" URL="https://github.com/SolsticeSpectrum" Acknowledgment="Thanks for your build script contribution."/>
|
||||||
<Supporter Name="peerschuett" Type="SupporterType.INDIVIDUAL" URL="https://github.com/peerschuett" Acknowledgment="Thanks for your contributions to the project."/>
|
|
||||||
</MudList>
|
</MudList>
|
||||||
</MudPaper>
|
</MudPaper>
|
||||||
</MudItem>
|
</MudItem>
|
||||||
|
@ -139,7 +139,7 @@ public partial class Writer : MSGComponentBase, IAsyncDisposable
|
|||||||
this.isStreaming = true;
|
this.isStreaming = true;
|
||||||
this.StateHasChanged();
|
this.StateHasChanged();
|
||||||
|
|
||||||
this.chatThread = await aiText.CreateFromProviderAsync(this.providerSettings.CreateProvider(this.Logger), this.providerSettings.Model, lastUserPrompt, this.chatThread);
|
await aiText.CreateFromProviderAsync(this.providerSettings.CreateProvider(this.Logger), this.providerSettings.Model, lastUserPrompt, this.chatThread);
|
||||||
this.suggestion = aiText.Text;
|
this.suggestion = aiText.Text;
|
||||||
|
|
||||||
this.isStreaming = false;
|
this.isStreaming = false;
|
||||||
|
@ -38,6 +38,7 @@ public sealed class ProviderAnthropic(ILogger logger) : BaseProvider("https://ap
|
|||||||
ChatRole.USER => "user",
|
ChatRole.USER => "user",
|
||||||
ChatRole.AI => "assistant",
|
ChatRole.AI => "assistant",
|
||||||
ChatRole.AGENT => "assistant",
|
ChatRole.AGENT => "assistant",
|
||||||
|
ChatRole.RAG => "assistant",
|
||||||
|
|
||||||
_ => "user",
|
_ => "user",
|
||||||
},
|
},
|
||||||
|
@ -49,6 +49,7 @@ public sealed class ProviderDeepSeek(ILogger logger) : BaseProvider("https://api
|
|||||||
ChatRole.USER => "user",
|
ChatRole.USER => "user",
|
||||||
ChatRole.AI => "assistant",
|
ChatRole.AI => "assistant",
|
||||||
ChatRole.AGENT => "assistant",
|
ChatRole.AGENT => "assistant",
|
||||||
|
ChatRole.RAG => "assistant",
|
||||||
ChatRole.SYSTEM => "system",
|
ChatRole.SYSTEM => "system",
|
||||||
|
|
||||||
_ => "user",
|
_ => "user",
|
||||||
|
@ -49,6 +49,7 @@ public class ProviderFireworks(ILogger logger) : BaseProvider("https://api.firew
|
|||||||
ChatRole.AI => "assistant",
|
ChatRole.AI => "assistant",
|
||||||
ChatRole.AGENT => "assistant",
|
ChatRole.AGENT => "assistant",
|
||||||
ChatRole.SYSTEM => "system",
|
ChatRole.SYSTEM => "system",
|
||||||
|
ChatRole.RAG => "assistant",
|
||||||
|
|
||||||
_ => "user",
|
_ => "user",
|
||||||
},
|
},
|
||||||
|
@ -49,6 +49,7 @@ public sealed class ProviderGWDG(ILogger logger) : BaseProvider("https://chat-ai
|
|||||||
ChatRole.USER => "user",
|
ChatRole.USER => "user",
|
||||||
ChatRole.AI => "assistant",
|
ChatRole.AI => "assistant",
|
||||||
ChatRole.AGENT => "assistant",
|
ChatRole.AGENT => "assistant",
|
||||||
|
ChatRole.RAG => "assistant",
|
||||||
ChatRole.SYSTEM => "system",
|
ChatRole.SYSTEM => "system",
|
||||||
|
|
||||||
_ => "user",
|
_ => "user",
|
||||||
|
@ -50,6 +50,7 @@ public class ProviderGoogle(ILogger logger) : BaseProvider("https://generativela
|
|||||||
ChatRole.AI => "assistant",
|
ChatRole.AI => "assistant",
|
||||||
ChatRole.AGENT => "assistant",
|
ChatRole.AGENT => "assistant",
|
||||||
ChatRole.SYSTEM => "system",
|
ChatRole.SYSTEM => "system",
|
||||||
|
ChatRole.RAG => "assistant",
|
||||||
|
|
||||||
_ => "user",
|
_ => "user",
|
||||||
},
|
},
|
||||||
|
@ -50,6 +50,7 @@ public class ProviderGroq(ILogger logger) : BaseProvider("https://api.groq.com/o
|
|||||||
ChatRole.AI => "assistant",
|
ChatRole.AI => "assistant",
|
||||||
ChatRole.AGENT => "assistant",
|
ChatRole.AGENT => "assistant",
|
||||||
ChatRole.SYSTEM => "system",
|
ChatRole.SYSTEM => "system",
|
||||||
|
ChatRole.RAG => "assistant",
|
||||||
|
|
||||||
_ => "user",
|
_ => "user",
|
||||||
},
|
},
|
||||||
|
@ -49,6 +49,7 @@ public sealed class ProviderHelmholtz(ILogger logger) : BaseProvider("https://ap
|
|||||||
ChatRole.USER => "user",
|
ChatRole.USER => "user",
|
||||||
ChatRole.AI => "assistant",
|
ChatRole.AI => "assistant",
|
||||||
ChatRole.AGENT => "assistant",
|
ChatRole.AGENT => "assistant",
|
||||||
|
ChatRole.RAG => "assistant",
|
||||||
ChatRole.SYSTEM => "system",
|
ChatRole.SYSTEM => "system",
|
||||||
|
|
||||||
_ => "user",
|
_ => "user",
|
||||||
|
@ -48,6 +48,7 @@ public sealed class ProviderMistral(ILogger logger) : BaseProvider("https://api.
|
|||||||
ChatRole.AI => "assistant",
|
ChatRole.AI => "assistant",
|
||||||
ChatRole.AGENT => "assistant",
|
ChatRole.AGENT => "assistant",
|
||||||
ChatRole.SYSTEM => "system",
|
ChatRole.SYSTEM => "system",
|
||||||
|
ChatRole.RAG => "assistant",
|
||||||
|
|
||||||
_ => "user",
|
_ => "user",
|
||||||
},
|
},
|
||||||
|
@ -76,6 +76,7 @@ public sealed class ProviderOpenAI(ILogger logger) : BaseProvider("https://api.o
|
|||||||
ChatRole.USER => "user",
|
ChatRole.USER => "user",
|
||||||
ChatRole.AI => "assistant",
|
ChatRole.AI => "assistant",
|
||||||
ChatRole.AGENT => "assistant",
|
ChatRole.AGENT => "assistant",
|
||||||
|
ChatRole.RAG => "assistant",
|
||||||
ChatRole.SYSTEM => systemPromptRole,
|
ChatRole.SYSTEM => systemPromptRole,
|
||||||
|
|
||||||
_ => "user",
|
_ => "user",
|
||||||
|
@ -46,6 +46,7 @@ public sealed class ProviderSelfHosted(ILogger logger, Host host, string hostnam
|
|||||||
ChatRole.AI => "assistant",
|
ChatRole.AI => "assistant",
|
||||||
ChatRole.AGENT => "assistant",
|
ChatRole.AGENT => "assistant",
|
||||||
ChatRole.SYSTEM => "system",
|
ChatRole.SYSTEM => "system",
|
||||||
|
ChatRole.RAG => "assistant",
|
||||||
|
|
||||||
_ => "user",
|
_ => "user",
|
||||||
},
|
},
|
||||||
|
@ -50,6 +50,7 @@ public sealed class ProviderX(ILogger logger) : BaseProvider("https://api.x.ai/v
|
|||||||
ChatRole.AI => "assistant",
|
ChatRole.AI => "assistant",
|
||||||
ChatRole.AGENT => "assistant",
|
ChatRole.AGENT => "assistant",
|
||||||
ChatRole.SYSTEM => "system",
|
ChatRole.SYSTEM => "system",
|
||||||
|
ChatRole.RAG => "assistant",
|
||||||
|
|
||||||
_ => "user",
|
_ => "user",
|
||||||
},
|
},
|
||||||
|
@ -51,9 +51,6 @@ public readonly record struct DataSourceERI_V1 : IERIDataSource
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public ERIVersion Version { get; init; } = ERIVersion.V1;
|
public ERIVersion Version { get; init; } = ERIVersion.V1;
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public string SelectedRetrievalId { get; init; } = string.Empty;
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public async Task<IReadOnlyList<IRetrievalContext>> RetrieveDataAsync(IContent lastPrompt, ChatThread thread, CancellationToken token = default)
|
public async Task<IReadOnlyList<IRetrievalContext>> RetrieveDataAsync(IContent lastPrompt, ChatThread thread, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
@ -77,7 +74,7 @@ public readonly record struct DataSourceERI_V1 : IERIDataSource
|
|||||||
|
|
||||||
Thread = await thread.ToERIChatThread(token),
|
Thread = await thread.ToERIChatThread(token),
|
||||||
MaxMatches = 10,
|
MaxMatches = 10,
|
||||||
RetrievalProcessId = string.IsNullOrWhiteSpace(this.SelectedRetrievalId) ? null : this.SelectedRetrievalId,
|
RetrievalProcessId = null, // The ERI server selects the retrieval process when multiple processes are available
|
||||||
Parameters = null, // The ERI server selects useful default parameters
|
Parameters = null, // The ERI server selects useful default parameters
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -100,7 +97,7 @@ public readonly record struct DataSourceERI_V1 : IERIDataSource
|
|||||||
Links = eriContext.Links,
|
Links = eriContext.Links,
|
||||||
Category = eriContext.Type.ToRetrievalContentCategory(),
|
Category = eriContext.Type.ToRetrievalContentCategory(),
|
||||||
MatchedText = eriContext.MatchedContent,
|
MatchedText = eriContext.MatchedContent,
|
||||||
DataSourceName = this.Name,
|
DataSourceName = eriContext.Name,
|
||||||
SurroundingContent = eriContext.SurroundingContent,
|
SurroundingContent = eriContext.SurroundingContent,
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
@ -114,7 +111,7 @@ public readonly record struct DataSourceERI_V1 : IERIDataSource
|
|||||||
Source = eriContext.MatchedContent,
|
Source = eriContext.MatchedContent,
|
||||||
Category = eriContext.Type.ToRetrievalContentCategory(),
|
Category = eriContext.Type.ToRetrievalContentCategory(),
|
||||||
SourceType = ContentImageSource.BASE64,
|
SourceType = ContentImageSource.BASE64,
|
||||||
DataSourceName = this.Name,
|
DataSourceName = eriContext.Name,
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -29,9 +29,4 @@ public interface IERIDataSource : IExternalDataSource
|
|||||||
/// The ERI specification to use.
|
/// The ERI specification to use.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ERIVersion Version { get; init; }
|
public ERIVersion Version { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The ID of the selected retrieval process.
|
|
||||||
/// </summary>
|
|
||||||
public string SelectedRetrievalId { get; init; }
|
|
||||||
}
|
}
|
@ -9,10 +9,9 @@ public abstract class ERIClientBase(string baseAddress) : IDisposable
|
|||||||
{
|
{
|
||||||
WriteIndented = true,
|
WriteIndented = true,
|
||||||
AllowTrailingCommas = true,
|
AllowTrailingCommas = true,
|
||||||
PropertyNameCaseInsensitive = true,
|
PropertyNamingPolicy = null,
|
||||||
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
|
|
||||||
DictionaryKeyPolicy = JsonNamingPolicy.CamelCase,
|
DictionaryKeyPolicy = JsonNamingPolicy.CamelCase,
|
||||||
UnmappedMemberHandling = JsonUnmappedMemberHandling.Disallow,
|
PropertyNameCaseInsensitive = true,
|
||||||
Converters =
|
Converters =
|
||||||
{
|
{
|
||||||
new JsonStringEnumConverter(JsonNamingPolicy.SnakeCaseUpper),
|
new JsonStringEnumConverter(JsonNamingPolicy.SnakeCaseUpper),
|
||||||
|
@ -66,8 +66,22 @@ public sealed class AugmentationOne : IAugmentationProcess
|
|||||||
// Let's convert all retrieval contexts to Markdown:
|
// Let's convert all retrieval contexts to Markdown:
|
||||||
await retrievalContexts.AsMarkdown(sb, token);
|
await retrievalContexts.AsMarkdown(sb, token);
|
||||||
|
|
||||||
// Add the augmented data to the chat thread:
|
//
|
||||||
chatThread.AugmentedData = sb.ToString();
|
// Append the entire augmentation to the chat thread,
|
||||||
|
// just before the user prompt:
|
||||||
|
//
|
||||||
|
chatThread.Blocks.Insert(chatThread.Blocks.Count - 1, new()
|
||||||
|
{
|
||||||
|
Role = ChatRole.RAG,
|
||||||
|
Time = DateTimeOffset.UtcNow,
|
||||||
|
ContentType = ContentType.TEXT,
|
||||||
|
HideFromUser = true,
|
||||||
|
Content = new ContentText
|
||||||
|
{
|
||||||
|
Text = sb.ToString(),
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return chatThread;
|
return chatThread;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
using AIStudio.Chat;
|
using AIStudio.Chat;
|
||||||
using AIStudio.Provider;
|
using AIStudio.Provider;
|
||||||
using AIStudio.Settings;
|
using AIStudio.Settings;
|
||||||
using AIStudio.Settings.DataModel;
|
|
||||||
using AIStudio.Tools.RAG.AugmentationProcesses;
|
using AIStudio.Tools.RAG.AugmentationProcesses;
|
||||||
using AIStudio.Tools.RAG.DataSourceSelectionProcesses;
|
using AIStudio.Tools.RAG.DataSourceSelectionProcesses;
|
||||||
using AIStudio.Tools.Services;
|
using AIStudio.Tools.Services;
|
||||||
@ -39,30 +38,6 @@ public sealed class AISrcSelWithRetCtxVal : IRagProcess
|
|||||||
// makes sense to proceed with the RAG process:
|
// makes sense to proceed with the RAG process:
|
||||||
var proceedWithRAG = true;
|
var proceedWithRAG = true;
|
||||||
|
|
||||||
//
|
|
||||||
// We read the last block in the chat thread. We need to re-arrange
|
|
||||||
// the order of blocks later, after the augmentation process takes
|
|
||||||
// place:
|
|
||||||
//
|
|
||||||
if(chatThread.Blocks.Count == 0)
|
|
||||||
{
|
|
||||||
logger.LogError("The chat thread is empty. Skipping the RAG process.");
|
|
||||||
return chatThread;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (chatThread.Blocks.Last().Role != ChatRole.AI)
|
|
||||||
{
|
|
||||||
logger.LogError("The last block in the chat thread is not the AI block. There is something wrong with the chat thread. Skipping the RAG process.");
|
|
||||||
return chatThread;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// At this point in time, the chat thread contains already the
|
|
||||||
// last block, which is the waiting AI block. We need to remove
|
|
||||||
// this block before we call some parts of the RAG process:
|
|
||||||
//
|
|
||||||
var chatThreadWithoutWaitingAIBlock = chatThread with { Blocks = chatThread.Blocks[..^1] };
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// When the user wants to bind data sources to the chat, we
|
// When the user wants to bind data sources to the chat, we
|
||||||
// have to check if the data sources are available for the
|
// have to check if the data sources are available for the
|
||||||
@ -97,56 +72,6 @@ public sealed class AISrcSelWithRetCtxVal : IRagProcess
|
|||||||
logger.LogWarning("No data sources are selected. The RAG process is skipped.");
|
logger.LogWarning("No data sources are selected. The RAG process is skipped.");
|
||||||
proceedWithRAG = false;
|
proceedWithRAG = false;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
var previousDataSecurity = chatThread.DataSecurity;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Update the data security of the chat thread. We consider the current data security
|
|
||||||
// of the chat thread and the data security of the selected data sources:
|
|
||||||
//
|
|
||||||
var dataSecurityRestrictedToSelfHosted = selectedDataSources.Any(x => x.SecurityPolicy is DataSourceSecurity.SELF_HOSTED);
|
|
||||||
chatThread.DataSecurity = dataSecurityRestrictedToSelfHosted switch
|
|
||||||
{
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// Case: the data sources which are selected have a security policy
|
|
||||||
// of SELF_HOSTED (at least one data source).
|
|
||||||
//
|
|
||||||
// When the policy was already set to ALLOW_ANY, we restrict it
|
|
||||||
// to SELF_HOSTED.
|
|
||||||
//
|
|
||||||
true => DataSourceSecurity.SELF_HOSTED,
|
|
||||||
|
|
||||||
//
|
|
||||||
// Case: the data sources which are selected have a security policy
|
|
||||||
// of ALLOW_ANY (none of the data sources has a SELF_HOSTED policy).
|
|
||||||
//
|
|
||||||
// When the policy was already set to SELF_HOSTED, we must keep that.
|
|
||||||
//
|
|
||||||
false => chatThread.DataSecurity switch
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// When the policy was not specified yet, we set it to ALLOW_ANY.
|
|
||||||
//
|
|
||||||
DataSourceSecurity.NOT_SPECIFIED => DataSourceSecurity.ALLOW_ANY,
|
|
||||||
DataSourceSecurity.ALLOW_ANY => DataSourceSecurity.ALLOW_ANY,
|
|
||||||
|
|
||||||
//
|
|
||||||
// When the policy was already set to SELF_HOSTED, we must keep that.
|
|
||||||
// This is important since the thread might already contain data
|
|
||||||
// from a data source with a SELF_HOSTED policy.
|
|
||||||
//
|
|
||||||
DataSourceSecurity.SELF_HOSTED => DataSourceSecurity.SELF_HOSTED,
|
|
||||||
|
|
||||||
// Default case: we use the current data security of the chat thread.
|
|
||||||
_ => chatThread.DataSecurity,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (previousDataSecurity != chatThread.DataSecurity)
|
|
||||||
logger.LogInformation($"The data security of the chat thread was updated from '{previousDataSecurity}' to '{chatThread.DataSecurity}'.");
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Trigger the retrieval part of the (R)AG process:
|
// Trigger the retrieval part of the (R)AG process:
|
||||||
@ -159,7 +84,7 @@ public sealed class AISrcSelWithRetCtxVal : IRagProcess
|
|||||||
//
|
//
|
||||||
var retrievalTasks = new List<Task<IReadOnlyList<IRetrievalContext>>>(selectedDataSources.Count);
|
var retrievalTasks = new List<Task<IReadOnlyList<IRetrievalContext>>>(selectedDataSources.Count);
|
||||||
foreach (var dataSource in selectedDataSources)
|
foreach (var dataSource in selectedDataSources)
|
||||||
retrievalTasks.Add(dataSource.RetrieveDataAsync(lastPrompt, chatThreadWithoutWaitingAIBlock, token));
|
retrievalTasks.Add(dataSource.RetrieveDataAsync(lastPrompt, chatThread, token));
|
||||||
|
|
||||||
//
|
//
|
||||||
// Wait for all retrieval tasks to finish:
|
// Wait for all retrieval tasks to finish:
|
||||||
|
@ -93,14 +93,6 @@ public sealed class DataSourceValidation
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string? ValidateRetrievalProcess(RetrievalInfo retrievalInfo)
|
|
||||||
{
|
|
||||||
if(retrievalInfo == default)
|
|
||||||
return "Please select one retrieval process.";
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string? ValidatingName(string dataSourceName)
|
public string? ValidatingName(string dataSourceName)
|
||||||
{
|
{
|
||||||
if(string.IsNullOrWhiteSpace(dataSourceName))
|
if(string.IsNullOrWhiteSpace(dataSourceName))
|
||||||
|
@ -18,9 +18,9 @@
|
|||||||
},
|
},
|
||||||
"HtmlAgilityPack": {
|
"HtmlAgilityPack": {
|
||||||
"type": "Direct",
|
"type": "Direct",
|
||||||
"requested": "[1.11.74, )",
|
"requested": "[1.11.72, )",
|
||||||
"resolved": "1.11.74",
|
"resolved": "1.11.72",
|
||||||
"contentHash": "q0wRGbegtr4sZXjCNoV3OeRLTOcTNJQKiO9etNVSKPoTo33unmSK8Ahg36C4jIg/Hd3aw8YnTQjtKpBy+wlOpg=="
|
"contentHash": "RNLgXxTFdIGFI+o5l8c2aJ2L5StIRn9Uv8HKR76p7QP4ZUL26wzpWUCWh08xWUdkL2kocl+Xhv6VUu0rA1npVg=="
|
||||||
},
|
},
|
||||||
"Microsoft.Extensions.FileProviders.Embedded": {
|
"Microsoft.Extensions.FileProviders.Embedded": {
|
||||||
"type": "Direct",
|
"type": "Direct",
|
||||||
@ -207,6 +207,6 @@
|
|||||||
"contentHash": "7WaVMHklpT3Ye2ragqRIwlFRsb6kOk63BOGADV0fan3ulVfGLUYkDi5yNUsZS/7FVNkWbtHAlDLmu4WnHGfqvQ=="
|
"contentHash": "7WaVMHklpT3Ye2ragqRIwlFRsb6kOk63BOGADV0fan3ulVfGLUYkDi5yNUsZS/7FVNkWbtHAlDLmu4WnHGfqvQ=="
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"net8.0/win-x64": {}
|
"net8.0/osx-x64": {}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,16 +1,2 @@
|
|||||||
# v0.9.32, build 207 (2025-03-08 20:15 UTC)
|
# v0.9.32, build 207 (2025-03-xx xx:xx UTC)
|
||||||
- Added the "Community & Code" section to the about page. It includes links to the GitHub repositories and the project website.
|
- Added the Community & Code section to the About page. It includes links to the GitHub repositories and the project homepage.
|
||||||
- Added the retrieval process section for ERI data sources in the configuration dialog. Like all RAG functions, this is hidden behind the RAG feature flag in the app settings due to its preview status.
|
|
||||||
- Improved data security by preventing the use of cloud LLMs after confidential data has been retrieved previously.
|
|
||||||
- Improved the ERI client to expect JSON responses and send JSON requests using camel case.
|
|
||||||
- Improved the ERI client to raise an error when the server responds with additional JSON data that is not expected.
|
|
||||||
- Improved the error handling in the ERI data source info dialog in cases where servers respond with an invalid message.
|
|
||||||
- Improved the error handling for the entire RAG process.
|
|
||||||
- Improved chat thread persistence after modifications through the RAG process.
|
|
||||||
- Improved the augmentation and generation part of RAG by passing the augmented data into the system prompt.
|
|
||||||
- Fixed the chat thread we use for the data retrieval by removing the last block, which is meant to be for the final AI answer.
|
|
||||||
- Fixed the data source name for ERI data sources when performing data retrieval.
|
|
||||||
- Fixed the default data source selection when replacing the current chat with a new one.
|
|
||||||
- Fixed the state of the re-generate button in the chat thread, when no provider is selected or the data security is preventing the use of cloud LLMs.
|
|
||||||
- Updated the code contributions section in the supporter page. Thanks `peerschuett` for being our next contributor.
|
|
||||||
- Upgraded code dependencies.
|
|
@ -1 +0,0 @@
|
|||||||
# v0.9.33, build 208 (2025-03-xx xx:xx UTC)
|
|
@ -1,9 +1,9 @@
|
|||||||
0.9.32
|
0.9.31
|
||||||
2025-03-08 20:15:02 UTC
|
2025-03-03 15:33:03 UTC
|
||||||
207
|
206
|
||||||
8.0.113 (commit 8f216348dc)
|
8.0.113 (commit 8f216348dc)
|
||||||
8.0.13 (commit eba546b0f0)
|
8.0.13 (commit eba546b0f0)
|
||||||
1.85.0 (commit 4d91de4e4)
|
1.85.0 (commit 4d91de4e4)
|
||||||
7.16.0
|
7.16.0
|
||||||
1.8.1
|
1.8.1
|
||||||
5a726577ca2, release
|
2e84f10a977, release
|
||||||
|
53
runtime/Cargo.lock
generated
53
runtime/Cargo.lock
generated
@ -377,12 +377,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.2.16"
|
version = "1.1.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "be714c154be609ec7f5dad223a33bf1482fff90472de28f7362806e6d4832b8c"
|
checksum = "2aba8f4e9906c7ce3c73463f62a7f0c65183ada1a2d47e397cc8810827f9694f"
|
||||||
dependencies = [
|
|
||||||
"shlex",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cesu8"
|
name = "cesu8"
|
||||||
@ -2184,9 +2181,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "keyring"
|
name = "keyring"
|
||||||
version = "3.6.2"
|
version = "3.6.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1961983669d57bdfe6c0f3ef8e4c229b5ef751afcc7d87e4271d2f71f6ccfa8b"
|
checksum = "2f8fe839464d4e4b37d756d7e910063696af79a7e877282cb1825e4ec5f10833"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"dbus-secret-service",
|
"dbus-secret-service",
|
||||||
@ -2217,9 +2214,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.170"
|
version = "0.2.155"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "875b3680cb2f8f71bdcf9a30f38d48282f5d3c95cbf9b3fa57269bb5d5c06828"
|
checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libdbus-sys"
|
name = "libdbus-sys"
|
||||||
@ -2264,9 +2261,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "log"
|
name = "log"
|
||||||
version = "0.4.26"
|
version = "0.4.22"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e"
|
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "loom"
|
name = "loom"
|
||||||
@ -2350,7 +2347,7 @@ checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mindwork-ai-studio"
|
name = "mindwork-ai-studio"
|
||||||
version = "0.9.32"
|
version = "0.9.31"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aes",
|
"aes",
|
||||||
"arboard",
|
"arboard",
|
||||||
@ -2368,7 +2365,6 @@ dependencies = [
|
|||||||
"rand_chacha 0.9.0",
|
"rand_chacha 0.9.0",
|
||||||
"rcgen",
|
"rcgen",
|
||||||
"reqwest 0.12.12",
|
"reqwest 0.12.12",
|
||||||
"ring",
|
|
||||||
"rocket",
|
"rocket",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
@ -2762,9 +2758,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "once_cell"
|
name = "once_cell"
|
||||||
version = "1.20.3"
|
version = "1.20.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e"
|
checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "open"
|
name = "open"
|
||||||
@ -3561,14 +3557,15 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ring"
|
name = "ring"
|
||||||
version = "0.17.13"
|
version = "0.17.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "70ac5d832aa16abd7d1def883a8545280c20a60f523a370aa3a9617c2b8550ee"
|
checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"getrandom 0.2.15",
|
"getrandom 0.2.15",
|
||||||
"libc",
|
"libc",
|
||||||
|
"spin",
|
||||||
"untrusted",
|
"untrusted",
|
||||||
"windows-sys 0.52.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
@ -3876,18 +3873,18 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.218"
|
version = "1.0.217"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e8dfc9d19bdbf6d17e22319da49161d5d0108e4188e8b680aef6299eed22df60"
|
checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "1.0.218"
|
version = "1.0.217"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f09503e191f4e797cb8aac08e9a4a4695c5edf6a2e70e376d961ddd5c969f82b"
|
checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@ -4031,12 +4028,6 @@ dependencies = [
|
|||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "shlex"
|
|
||||||
version = "1.3.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "signal-hook-registry"
|
name = "signal-hook-registry"
|
||||||
version = "1.4.2"
|
version = "1.4.2"
|
||||||
@ -4728,9 +4719,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio"
|
name = "tokio"
|
||||||
version = "1.44.0"
|
version = "1.42.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9975ea0f48b5aa3972bf2d888c238182458437cc2a19374b81b25cdf1023fb3a"
|
checksum = "5cec9b21b0450273377fc97bd4c33a8acffc8c996c987a7c5b319a0083707551"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"backtrace",
|
"backtrace",
|
||||||
"bytes",
|
"bytes",
|
||||||
@ -4745,9 +4736,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-macros"
|
name = "tokio-macros"
|
||||||
version = "2.5.0"
|
version = "2.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8"
|
checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
Loading…
Reference in New Issue
Block a user