mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2025-04-28 15:39:46 +00:00
Added an option to all data sources to select a local security policy
This commit is contained in:
parent
ea671a1fcd
commit
e85a75aa96
@ -1,4 +1,6 @@
|
|||||||
|
@using AIStudio.Settings.DataModel
|
||||||
@using AIStudio.Tools.ERIClient.DataModel
|
@using AIStudio.Tools.ERIClient.DataModel
|
||||||
|
|
||||||
<MudDialog>
|
<MudDialog>
|
||||||
<DialogContent>
|
<DialogContent>
|
||||||
|
|
||||||
@ -25,7 +27,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
<TextInfoLines Label="Server description" MaxLines="14" Value="@this.serverDescription" ClipboardTooltipSubject="the server description"/>
|
<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"/>
|
<TextInfoLines Label="Security requirements of the data provider" MaxLines="3" Value="@this.securityRequirements.Explain()" ClipboardTooltipSubject="the security requirements of the data provider"/>
|
||||||
|
<TextInfoLines Label="Your security policy" MaxLines="3" Value="@this.DataSource.SecurityPolicy.ToInfoText()" Color="@this.DataSource.SecurityPolicy.GetColor()" ClipboardTooltipSubject="your security policy"/>
|
||||||
|
|
||||||
<MudText Typo="Typo.h5" Class="mt-6">
|
<MudText Typo="Typo.h5" Class="mt-6">
|
||||||
Retrieval information
|
Retrieval information
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
@using AIStudio.Settings.DataModel
|
||||||
@using AIStudio.Tools.ERIClient.DataModel
|
@using AIStudio.Tools.ERIClient.DataModel
|
||||||
<MudDialog>
|
<MudDialog>
|
||||||
<DialogContent>
|
<DialogContent>
|
||||||
@ -109,6 +110,13 @@
|
|||||||
UserAttributes="@SPELLCHECK_ATTRIBUTES"/>
|
UserAttributes="@SPELLCHECK_ATTRIBUTES"/>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
<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>())
|
||||||
|
{
|
||||||
|
<MudSelectItem Value="@policy">@policy.ToSelectionText()</MudSelectItem>
|
||||||
|
}
|
||||||
|
</MudSelect>
|
||||||
|
|
||||||
</MudForm>
|
</MudForm>
|
||||||
<Issues IssuesData="@this.dataIssues"/>
|
<Issues IssuesData="@this.dataIssues"/>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
|
@ -45,6 +45,8 @@ public partial class DataSourceERI_V1Dialog : ComponentBase, ISecretId
|
|||||||
private string dataSecretStorageIssue = string.Empty;
|
private string dataSecretStorageIssue = string.Empty;
|
||||||
private string dataEditingPreviousInstanceName = string.Empty;
|
private string dataEditingPreviousInstanceName = string.Empty;
|
||||||
private List<AuthMethod> availableAuthMethods = [];
|
private List<AuthMethod> availableAuthMethods = [];
|
||||||
|
private DataSourceSecurity dataSecurityPolicy;
|
||||||
|
private SecurityRequirements dataSourceSecurityRequirements;
|
||||||
private bool connectionTested;
|
private bool connectionTested;
|
||||||
private bool connectionSuccessfulTested;
|
private bool connectionSuccessfulTested;
|
||||||
|
|
||||||
@ -71,6 +73,7 @@ public partial class DataSourceERI_V1Dialog : ComponentBase, ISecretId
|
|||||||
GetTestedConnection = () => this.connectionTested,
|
GetTestedConnection = () => this.connectionTested,
|
||||||
GetTestedConnectionResult = () => this.connectionSuccessfulTested,
|
GetTestedConnectionResult = () => this.connectionSuccessfulTested,
|
||||||
GetAvailableAuthMethods = () => this.availableAuthMethods,
|
GetAvailableAuthMethods = () => this.availableAuthMethods,
|
||||||
|
GetSecurityRequirements = () => this.dataSourceSecurityRequirements,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,6 +150,7 @@ public partial class DataSourceERI_V1Dialog : ComponentBase, ISecretId
|
|||||||
AuthMethod = this.dataAuthMethod,
|
AuthMethod = this.dataAuthMethod,
|
||||||
Username = this.dataUsername,
|
Username = this.dataUsername,
|
||||||
Type = DataSourceType.ERI_V1,
|
Type = DataSourceType.ERI_V1,
|
||||||
|
SecurityPolicy = this.dataSecurityPolicy,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -196,6 +200,28 @@ public partial class DataSourceERI_V1Dialog : ComponentBase, ISecretId
|
|||||||
|
|
||||||
this.availableAuthMethods = authSchemes.Data!.Select(n => n.AuthMethod).ToList();
|
this.availableAuthMethods = authSchemes.Data!.Select(n => n.AuthMethod).ToList();
|
||||||
|
|
||||||
|
var loginResult = await client.AuthenticateAsync(this.DataSource, this.RustService, cts.Token);
|
||||||
|
if (!loginResult.Successful)
|
||||||
|
{
|
||||||
|
await this.form.Validate();
|
||||||
|
|
||||||
|
Array.Resize(ref this.dataIssues, this.dataIssues.Length + 1);
|
||||||
|
this.dataIssues[^1] = loginResult.Message;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var securityRequirementsRequest = await client.GetSecurityRequirementsAsync(cts.Token);
|
||||||
|
if (!securityRequirementsRequest.Successful)
|
||||||
|
{
|
||||||
|
await this.form.Validate();
|
||||||
|
|
||||||
|
Array.Resize(ref this.dataIssues, this.dataIssues.Length + 1);
|
||||||
|
this.dataIssues[^1] = securityRequirementsRequest.Message;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.dataSourceSecurityRequirements = securityRequirementsRequest.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.");
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
@using AIStudio.Settings.DataModel
|
||||||
|
|
||||||
<MudDialog>
|
<MudDialog>
|
||||||
<DialogContent>
|
<DialogContent>
|
||||||
<MudForm @ref="@this.form" @bind-IsValid="@this.dataIsValid" @bind-Errors="@this.dataIssues">
|
<MudForm @ref="@this.form" @bind-IsValid="@this.dataIsValid" @bind-Errors="@this.dataIssues">
|
||||||
@ -60,6 +62,13 @@
|
|||||||
</MudJustifiedText>
|
</MudJustifiedText>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
<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>())
|
||||||
|
{
|
||||||
|
<MudSelectItem Value="@policy">@policy.ToSelectionText()</MudSelectItem>
|
||||||
|
}
|
||||||
|
</MudSelect>
|
||||||
</MudForm>
|
</MudForm>
|
||||||
<Issues IssuesData="@this.dataIssues"/>
|
<Issues IssuesData="@this.dataIssues"/>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
|
@ -42,6 +42,7 @@ public partial class DataSourceLocalDirectoryDialog : ComponentBase
|
|||||||
private bool dataUserAcknowledgedCloudEmbedding;
|
private bool dataUserAcknowledgedCloudEmbedding;
|
||||||
private string dataEmbeddingId = string.Empty;
|
private string dataEmbeddingId = string.Empty;
|
||||||
private string dataPath = string.Empty;
|
private string dataPath = string.Empty;
|
||||||
|
private DataSourceSecurity dataSecurityPolicy;
|
||||||
|
|
||||||
// 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!;
|
||||||
@ -102,6 +103,7 @@ public partial class DataSourceLocalDirectoryDialog : ComponentBase
|
|||||||
Type = DataSourceType.LOCAL_DIRECTORY,
|
Type = DataSourceType.LOCAL_DIRECTORY,
|
||||||
EmbeddingId = this.dataEmbeddingId,
|
EmbeddingId = this.dataEmbeddingId,
|
||||||
Path = this.dataPath,
|
Path = this.dataPath,
|
||||||
|
SecurityPolicy = this.dataSecurityPolicy,
|
||||||
};
|
};
|
||||||
|
|
||||||
private async Task Store()
|
private async Task Store()
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
@using AIStudio.Settings.DataModel
|
||||||
|
|
||||||
<MudDialog>
|
<MudDialog>
|
||||||
<DialogContent>
|
<DialogContent>
|
||||||
<TextInfoLine Icon="@Icons.Material.Filled.Tag" Label="Data source name" Value="@this.DataSource.Name" ClipboardTooltipSubject="the data source name"/>
|
<TextInfoLine Icon="@Icons.Material.Filled.Tag" Label="Data source name" Value="@this.DataSource.Name" ClipboardTooltipSubject="the data source name"/>
|
||||||
@ -31,6 +33,8 @@
|
|||||||
</MudJustifiedText>
|
</MudJustifiedText>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
<TextInfoLines Label="Your security policy" MaxLines="3" Value="@this.DataSource.SecurityPolicy.ToInfoText()" Color="@this.DataSource.SecurityPolicy.GetColor()" ClipboardTooltipSubject="your security policy"/>
|
||||||
|
|
||||||
<TextInfoLine Icon="@Icons.Material.Filled.SquareFoot" Label="Number of files" Value="@this.NumberFilesInDirectory" ClipboardTooltipSubject="the number of files in the directory"/>
|
<TextInfoLine Icon="@Icons.Material.Filled.SquareFoot" Label="Number of files" Value="@this.NumberFilesInDirectory" ClipboardTooltipSubject="the number of files in the directory"/>
|
||||||
<TextInfoLines Label="Files list" MaxLines="14" Value="@this.directoryFiles.ToString()" ClipboardTooltipSubject="the files list"/>
|
<TextInfoLines Label="Files list" MaxLines="14" Value="@this.directoryFiles.ToString()" ClipboardTooltipSubject="the files list"/>
|
||||||
@if (this.directorySizeNumFiles > 100)
|
@if (this.directorySizeNumFiles > 100)
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
@using AIStudio.Settings.DataModel
|
||||||
<MudDialog>
|
<MudDialog>
|
||||||
<DialogContent>
|
<DialogContent>
|
||||||
<MudForm @ref="@this.form" @bind-IsValid="@this.dataIsValid" @bind-Errors="@this.dataIssues">
|
<MudForm @ref="@this.form" @bind-IsValid="@this.dataIsValid" @bind-Errors="@this.dataIssues">
|
||||||
@ -59,6 +60,13 @@
|
|||||||
</MudJustifiedText>
|
</MudJustifiedText>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
<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>())
|
||||||
|
{
|
||||||
|
<MudSelectItem Value="@policy">@policy.ToSelectionText()</MudSelectItem>
|
||||||
|
}
|
||||||
|
</MudSelect>
|
||||||
</MudForm>
|
</MudForm>
|
||||||
<Issues IssuesData="@this.dataIssues"/>
|
<Issues IssuesData="@this.dataIssues"/>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
|
@ -42,6 +42,7 @@ public partial class DataSourceLocalFileDialog : ComponentBase
|
|||||||
private bool dataUserAcknowledgedCloudEmbedding;
|
private bool dataUserAcknowledgedCloudEmbedding;
|
||||||
private string dataEmbeddingId = string.Empty;
|
private string dataEmbeddingId = string.Empty;
|
||||||
private string dataFilePath = string.Empty;
|
private string dataFilePath = string.Empty;
|
||||||
|
private DataSourceSecurity dataSecurityPolicy;
|
||||||
|
|
||||||
// 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!;
|
||||||
@ -102,6 +103,7 @@ public partial class DataSourceLocalFileDialog : ComponentBase
|
|||||||
Type = DataSourceType.LOCAL_FILE,
|
Type = DataSourceType.LOCAL_FILE,
|
||||||
EmbeddingId = this.dataEmbeddingId,
|
EmbeddingId = this.dataEmbeddingId,
|
||||||
FilePath = this.dataFilePath,
|
FilePath = this.dataFilePath,
|
||||||
|
SecurityPolicy = this.dataSecurityPolicy,
|
||||||
};
|
};
|
||||||
|
|
||||||
private async Task Store()
|
private async Task Store()
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
@using AIStudio.Settings.DataModel
|
||||||
|
|
||||||
<MudDialog>
|
<MudDialog>
|
||||||
<DialogContent>
|
<DialogContent>
|
||||||
<TextInfoLine Icon="@Icons.Material.Filled.Tag" Label="Data source name" Value="@this.DataSource.Name" ClipboardTooltipSubject="the data source name"/>
|
<TextInfoLine Icon="@Icons.Material.Filled.Tag" Label="Data source name" Value="@this.DataSource.Name" ClipboardTooltipSubject="the data source name"/>
|
||||||
@ -31,6 +33,7 @@
|
|||||||
</MudJustifiedText>
|
</MudJustifiedText>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
<TextInfoLines Label="Your security policy" MaxLines="3" Value="@this.DataSource.SecurityPolicy.ToInfoText()" Color="@this.DataSource.SecurityPolicy.GetColor()" ClipboardTooltipSubject="your security policy"/>
|
||||||
<TextInfoLine Icon="@Icons.Material.Filled.SquareFoot" Label="File size" Value="@this.FileSize" ClipboardTooltipSubject="the file size"/>
|
<TextInfoLine Icon="@Icons.Material.Filled.SquareFoot" Label="File size" Value="@this.FileSize" ClipboardTooltipSubject="the file size"/>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
<DialogActions>
|
<DialogActions>
|
||||||
|
@ -36,4 +36,7 @@ public readonly record struct DataSourceERI_V1 : IERIDataSource
|
|||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public string Username { get; init; } = string.Empty;
|
public string Username { get; init; } = string.Empty;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public DataSourceSecurity SecurityPolicy { get; init; } = DataSourceSecurity.NOT_SPECIFIED;
|
||||||
}
|
}
|
@ -24,6 +24,9 @@ public readonly record struct DataSourceLocalDirectory : IInternalDataSource
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public string EmbeddingId { get; init; } = Guid.Empty.ToString();
|
public string EmbeddingId { get; init; } = Guid.Empty.ToString();
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public DataSourceSecurity SecurityPolicy { get; init; } = DataSourceSecurity.NOT_SPECIFIED;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The path to the directory.
|
/// The path to the directory.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -24,6 +24,9 @@ public readonly record struct DataSourceLocalFile : IInternalDataSource
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public string EmbeddingId { get; init; } = Guid.Empty.ToString();
|
public string EmbeddingId { get; init; } = Guid.Empty.ToString();
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public DataSourceSecurity SecurityPolicy { get; init; } = DataSourceSecurity.NOT_SPECIFIED;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The path to the file.
|
/// The path to the file.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -0,0 +1,19 @@
|
|||||||
|
namespace AIStudio.Settings.DataModel;
|
||||||
|
|
||||||
|
public enum DataSourceSecurity
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The security of the data source is not specified yet.
|
||||||
|
/// </summary>
|
||||||
|
NOT_SPECIFIED,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This data can be used with any LLM provider.
|
||||||
|
/// </summary>
|
||||||
|
ALLOW_ANY,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This data can only be used for self-hosted LLM providers.
|
||||||
|
/// </summary>
|
||||||
|
SELF_HOSTED,
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
namespace AIStudio.Settings.DataModel;
|
||||||
|
|
||||||
|
public static class DataSourceSecurityExtensions
|
||||||
|
{
|
||||||
|
public static string ToSelectionText(this DataSourceSecurity security) => security switch
|
||||||
|
{
|
||||||
|
DataSourceSecurity.NOT_SPECIFIED => "Please select a security policy",
|
||||||
|
|
||||||
|
DataSourceSecurity.ALLOW_ANY => "This data source can be used with any LLM provider. Your data may be sent to a cloud-based provider.",
|
||||||
|
DataSourceSecurity.SELF_HOSTED => "This data source can only be used with a self-hosted LLM provider. Your data will not be sent to any cloud-based provider.",
|
||||||
|
|
||||||
|
_ => "Unknown security policy"
|
||||||
|
};
|
||||||
|
|
||||||
|
public static string ToInfoText(this DataSourceSecurity security) => security switch
|
||||||
|
{
|
||||||
|
DataSourceSecurity.NOT_SPECIFIED => "The security of the data source is not specified yet. You cannot use this data source until you specify a security policy.",
|
||||||
|
|
||||||
|
DataSourceSecurity.ALLOW_ANY => "This data source can be used with any LLM provider. Your data may be sent to a cloud-based provider.",
|
||||||
|
DataSourceSecurity.SELF_HOSTED => "This data source can only be used with a self-hosted LLM provider. Your data will not be sent to any cloud-based provider.",
|
||||||
|
|
||||||
|
_ => "Unknown security policy"
|
||||||
|
};
|
||||||
|
|
||||||
|
public static TextColor GetColor(this DataSourceSecurity security) => security switch
|
||||||
|
{
|
||||||
|
DataSourceSecurity.ALLOW_ANY => TextColor.WARN,
|
||||||
|
DataSourceSecurity.SELF_HOSTED => TextColor.SUCCESS,
|
||||||
|
|
||||||
|
_ => TextColor.ERROR
|
||||||
|
};
|
||||||
|
}
|
@ -32,4 +32,9 @@ public interface IDataSource
|
|||||||
/// Which type of data source is this?
|
/// Which type of data source is this?
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DataSourceType Type { get; init; }
|
public DataSourceType Type { get; init; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Which data security policy is applied to this data source?
|
||||||
|
/// </summary>
|
||||||
|
public DataSourceSecurity SecurityPolicy { get; init; }
|
||||||
}
|
}
|
@ -1,3 +1,4 @@
|
|||||||
|
using AIStudio.Settings.DataModel;
|
||||||
using AIStudio.Tools.ERIClient.DataModel;
|
using AIStudio.Tools.ERIClient.DataModel;
|
||||||
|
|
||||||
namespace AIStudio.Tools.Validation;
|
namespace AIStudio.Tools.Validation;
|
||||||
@ -12,6 +13,8 @@ public sealed class DataSourceValidation
|
|||||||
|
|
||||||
public Func<AuthMethod> GetAuthMethod { get; init; } = () => AuthMethod.NONE;
|
public Func<AuthMethod> GetAuthMethod { get; init; } = () => AuthMethod.NONE;
|
||||||
|
|
||||||
|
public Func<SecurityRequirements?> GetSecurityRequirements { get; init; } = () => null;
|
||||||
|
|
||||||
public Func<bool> GetSelectedCloudEmbedding { get; init; } = () => false;
|
public Func<bool> GetSelectedCloudEmbedding { get; init; } = () => false;
|
||||||
|
|
||||||
public Func<bool> GetTestedConnection { get; init; } = () => false;
|
public Func<bool> GetTestedConnection { get; init; } = () => false;
|
||||||
@ -42,6 +45,21 @@ public sealed class DataSourceValidation
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string? ValidateSecurityPolicy(DataSourceSecurity securityPolicy)
|
||||||
|
{
|
||||||
|
if(securityPolicy is DataSourceSecurity.NOT_SPECIFIED)
|
||||||
|
return "Please select your security policy.";
|
||||||
|
|
||||||
|
var dataSourceSecurity = this.GetSecurityRequirements();
|
||||||
|
if (dataSourceSecurity is null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
if(dataSourceSecurity.Value.AllowedProviderType is ProviderType.SELF_HOSTED && securityPolicy is not DataSourceSecurity.SELF_HOSTED)
|
||||||
|
return "This data source can only be used with a self-hosted LLM provider. Please change the security policy.";
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public string? ValidateUsername(string username)
|
public string? ValidateUsername(string username)
|
||||||
{
|
{
|
||||||
if(this.GetAuthMethod() is not AuthMethod.USERNAME_PASSWORD)
|
if(this.GetAuthMethod() is not AuthMethod.USERNAME_PASSWORD)
|
||||||
|
@ -1,2 +1,3 @@
|
|||||||
# v0.9.29, build 204 (2025-02-xx xx:xx UTC)
|
# v0.9.29, build 204 (2025-02-xx xx:xx UTC)
|
||||||
- Added the possibility to select data sources for chats. This preview feature is hidden behind the RAG feature flag, check your app options in case you want to enable it.
|
- Added the possibility to select data sources for chats. This preview feature is hidden behind the RAG feature flag, check your app options in case you want to enable it.
|
||||||
|
- Added an option to all data sources to select a local security policy. This preview feature is hidden behind the RAG feature flag.
|
Loading…
Reference in New Issue
Block a user