Draft of document analysis assistant

This commit is contained in:
Thorsten Sommer 2025-10-19 14:39:40 +02:00
parent 953d75efd9
commit 72e36366b6
Signed by: tsommer
GPG Key ID: 371BBA77A02C0108
14 changed files with 562 additions and 0 deletions

View File

@ -0,0 +1,65 @@
@attribute [Route(Routes.ASSISTANT_DOCUMENT_ANALYSIS)]
@inherits AssistantBaseCore<AIStudio.Dialogs.Settings.SettingsDialogDocumentAnalysis>
@using AIStudio.Settings.DataModel
<PreviewPrototype/>
<div class="mb-6"></div>
<MudText Typo="Typo.h4" Class="mb-3">
@T("Document analysis policies")
</MudText>
<MudJustifiedText Typo="Typo.body1" Class="mb-3">
@T("Here you have the option to save different policies for various document analysis assistants and switch between them.")
</MudJustifiedText>
@if(this.SettingsManager.ConfigurationData.DocumentAnalysis.Policies.Count is 0)
{
<MudText Typo="Typo.body1" Class="mb-3">
@T("You have not yet added any document analysis policies.")
</MudText>
}
else
{
<MudList T="DataDocumentAnalysisPolicy" Class="mb-1" SelectedValue="@this.selectedPolicy" SelectedValueChanged="@this.SelectedPolicyChanged">
@foreach (var policy in this.SettingsManager.ConfigurationData.DocumentAnalysis.Policies)
{
<MudListItem T="DataDocumentAnalysisPolicy" Icon="@Icons.Material.Filled.Settings" Value="@policy">
@policy.PolicyName
</MudListItem>
}
</MudList>
}
<MudStack Row="@true" Class="mt-1">
<MudButton OnClick="@this.AddPolicy" Variant="Variant.Filled" Color="Color.Primary">
@T("Add policy")
</MudButton>
<MudButton OnClick="@this.RemovePolicy" Disabled="@(this.selectedPolicy?.IsProtected ?? true)" Variant="Variant.Filled" Color="Color.Error">
@T("Delete this policy")
</MudButton>
</MudStack>
<hr style="width: 100%; border-width: 0.25ch;" class="mt-6"/>
<MudExpansionPanels Class="mb-3 mt-6" MultiExpansion="@false">
<ExpansionPanel HeaderIcon="@Icons.Material.Filled.Settings" HeaderText="@T("Settings")" IsExpanded="@(!this.selectedPolicy?.IsProtected ?? true)">
<MudText Typo="Typo.h4" Class="mb-1">
@T("Common settings")
</MudText>
<MudTextField T="string" Disabled="@this.IsNoPolicySelectedOrProtected" @bind-Text="@this.policyName" Validation="@this.ValidatePolicyName" Immediate="@true" Label="@T("Policy name")" HelperText="@T("Please give your policy a name that provides information about the intended purpose. The name will be displayed to users in AI Studio.")" Counter="60" MaxLength="60" Variant="Variant.Outlined" Margin="Margin.Normal" UserAttributes="@USER_INPUT_ATTRIBUTES" Class="mb-3" OnKeyUp="() => this.PolicyNameWasChanged()"/>
<MudTextField T="string" Disabled="@this.IsNoPolicySelectedOrProtected" @bind-Text="@this.policyDescription" Validation="@this.ValidatePolicyDescription" Immediate="@true" Label="@T("Policy description")" HelperText="@T("Please provide a brief description of your policy. Describe or explain what your policy does. This description will be shown to users in AI Studio.")" Counter="512" MaxLength="512" Variant="Variant.Outlined" Margin="Margin.Normal" Lines="3" AutoGrow="@true" MaxLines="6" UserAttributes="@USER_INPUT_ATTRIBUTES" Class="mb-3"/>
<MudTextSwitch Label="@T("Would you like to protect this policy so that you cannot accidentally edit or delete it?")" Value="@this.policyIsProtected" ValueChanged="async state => await this.PolicyProtectionWasChanged(state)" LabelOn="@T("Yes, protect this policy")" LabelOff="@T("No, the policy can be edited")" />
<MudText Typo="Typo.h4" Class="mt-6 mb-1">
@T("Input and output rules")
</MudText>
<MudTextField T="string" Disabled="@this.IsNoPolicySelectedOrProtected" @bind-Text="@this.policyAnalysisRules" Validation="@this.ValidateAnalysisRules" Immediate="@true" Label="@T("Analysis rules")" HelperText="@T("Please provide a description of your analysis rules. This rules will be used to instruct the AI on how to analyze the documents.")" Variant="Variant.Outlined" Margin="Margin.Normal" Lines="5" AutoGrow="@true" MaxLines="26" UserAttributes="@USER_INPUT_ATTRIBUTES" Class="mb-3"/>
<MudTextField T="string" Disabled="@this.IsNoPolicySelectedOrProtected" @bind-Text="@this.policyOutputRules" Validation="@this.ValidateOutputRules" Immediate="@true" Label="@T("Output rules")" HelperText="@T("Please provide a description of your output rules. This rules will be used to instruct the AI on how to format the output of the analysis.")" Variant="Variant.Outlined" Margin="Margin.Normal" Lines="5" AutoGrow="@true" MaxLines="26" UserAttributes="@USER_INPUT_ATTRIBUTES" Class="mb-3"/>
</ExpansionPanel>
<ExpansionPanel HeaderIcon="@Icons.Material.Filled.DocumentScanner" HeaderText="@T("Document analysis")">
TODO
</ExpansionPanel>
</MudExpansionPanels>

View File

@ -0,0 +1,262 @@
using System.Text;
using AIStudio.Chat;
using AIStudio.Dialogs;
using AIStudio.Dialogs.Settings;
using AIStudio.Settings.DataModel;
using Microsoft.AspNetCore.Components;
using DialogOptions = AIStudio.Dialogs.DialogOptions;
namespace AIStudio.Assistants.DocumentAnalysis;
public partial class DocumentAnalysisAssistant : AssistantBaseCore<SettingsDialogDocumentAnalysis>
{
[Inject]
private IDialogService DialogService { get; init; } = null!;
public override Tools.Components Component => Tools.Components.DOCUMENT_ANALYSIS_ASSISTANT;
protected override string Title => T("Document Analysis Assistant");
protected override string Description => T(
"""
The document analysis assistant helps you to analyze and extract information from documents
based on predefined policies. You can create, edit, and manage document analysis policies
that define how documents should be processed and what information should be extracted.
Some policies might be protected by your organization and cannot be modified or deleted.
""");
protected override string SystemPrompt
{
get
{
var sb = new StringBuilder();
return sb.ToString();
}
}
protected override IReadOnlyList<IButtonData> FooterButtons => [];
protected override bool ShowEntireChatThread => true;
protected override bool ShowSendTo => true;
protected override string SubmitText => T("Analyze document");
protected override Func<Task> SubmitAction => this.Analyze;
protected override bool SubmitDisabled => this.IsNoPolicySelected;
protected override ChatThread ConvertToChatThread => (this.chatThread ?? new()) with
{
SystemPrompt = SystemPrompts.DEFAULT,
};
protected override void ResetForm()
{
if (!this.MightPreselectValues())
{
this.policyName = string.Empty;
this.policyDescription = string.Empty;
this.policyIsProtected = false;
this.policyAnalysisRules = string.Empty;
this.policyOutputRules = string.Empty;
}
}
protected override bool MightPreselectValues()
{
if (this.selectedPolicy is not null)
{
this.policyName = this.selectedPolicy.PolicyName;
this.policyDescription = this.selectedPolicy.PolicyDescription;
this.policyIsProtected = this.selectedPolicy.IsProtected;
this.policyAnalysisRules = this.selectedPolicy.AnalysisRules;
this.policyOutputRules = this.selectedPolicy.OutputRules;
return true;
}
return false;
}
protected override async Task OnFormChange()
{
await this.AutoSave();
}
#region Overrides of AssistantBase
protected override async Task OnInitializedAsync()
{
this.selectedPolicy = this.SettingsManager.ConfigurationData.DocumentAnalysis.Policies.FirstOrDefault();
if(this.selectedPolicy is null)
{
await this.AddPolicy();
this.selectedPolicy = this.SettingsManager.ConfigurationData.DocumentAnalysis.Policies.First();
}
await base.OnInitializedAsync();
}
#endregion
private async Task AutoSave(bool force = false)
{
if(this.selectedPolicy is null)
return;
if(!force && this.selectedPolicy.IsProtected)
return;
if(!force && this.policyIsProtected)
return;
this.selectedPolicy.PreselectedProvider = this.providerSettings.Id;
this.selectedPolicy.PolicyName = this.policyName;
this.selectedPolicy.PolicyDescription = this.policyDescription;
this.selectedPolicy.IsProtected = this.policyIsProtected;
this.selectedPolicy.AnalysisRules = this.policyAnalysisRules;
this.selectedPolicy.OutputRules = this.policyOutputRules;
await this.SettingsManager.StoreSettings();
}
private DataDocumentAnalysisPolicy? selectedPolicy;
private bool policyIsProtected;
private string policyName = string.Empty;
private string policyDescription = string.Empty;
private string policyAnalysisRules = string.Empty;
private string policyOutputRules = string.Empty;
private bool IsNoPolicySelectedOrProtected => this.selectedPolicy is null || this.selectedPolicy.IsProtected;
private bool IsNoPolicySelected => this.selectedPolicy is null;
private void SelectedPolicyChanged(DataDocumentAnalysisPolicy? policy)
{
this.selectedPolicy = policy;
this.ResetForm();
}
private async Task AddPolicy()
{
this.SettingsManager.ConfigurationData.DocumentAnalysis.Policies.Add(new ()
{
PolicyName = string.Format(T("Policy {0}"), DateTimeOffset.UtcNow),
});
await this.SettingsManager.StoreSettings();
}
private async Task RemovePolicy()
{
if(this.selectedPolicy is null)
return;
if(this.selectedPolicy.IsProtected)
return;
var dialogParameters = new DialogParameters<ConfirmDialog>
{
{ x => x.Message, string.Format(T("Are you sure you want to delete the document analysis policy '{0}'?"), this.selectedPolicy.PolicyName) },
};
var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>(T("Delete document analysis policy"), dialogParameters, DialogOptions.FULLSCREEN);
var dialogResult = await dialogReference.Result;
if (dialogResult is null || dialogResult.Canceled)
return;
this.SettingsManager.ConfigurationData.DocumentAnalysis.Policies.Remove(this.selectedPolicy);
this.selectedPolicy = null;
this.ResetForm();
await this.SettingsManager.StoreSettings();
this.form?.ResetValidation();
}
/// <summary>
/// Gets called when the policy name was changed by typing.
/// </summary>
/// <remarks>
/// This method is used to update the policy name in the selected policy.
/// Otherwise, the users would be confused when they change the name and the changes are not reflected in the UI.
/// </remarks>
private void PolicyNameWasChanged()
{
if(this.selectedPolicy is null)
return;
if(this.selectedPolicy.IsProtected)
return;
this.selectedPolicy.PolicyName = this.policyName;
}
private async Task PolicyProtectionWasChanged(bool state)
{
if(this.selectedPolicy is null)
return;
this.policyIsProtected = state;
this.selectedPolicy.IsProtected = state;
await this.AutoSave(true);
}
private string? ValidatePolicyName(string name)
{
if(string.IsNullOrWhiteSpace(name))
return T("Please provide a name for your policy. This name will be used to identify the policy in AI Studio.");
if(name.Length is > 60 or < 6)
return T("The name of your policy must be between 6 and 60 characters long.");
if(this.SettingsManager.ConfigurationData.DocumentAnalysis.Policies.Where(n => n != this.selectedPolicy).Any(n => n.PolicyName == name))
return T("A policy with this name already exists. Please choose a different name.");
return null;
}
private string? ValidatePolicyDescription(string description)
{
if(string.IsNullOrWhiteSpace(description))
return T("Please provide a description for your policy. This description will be used to inform users about the purpose of your document analysis policy.");
if(description.Length is < 32 or > 512)
return T("The description of your policy must be between 32 and 512 characters long.");
return null;
}
private string? ValidateAnalysisRules(string analysisRules)
{
if(string.IsNullOrWhiteSpace(analysisRules))
return T("Please provide a description of your analysis rules. This rules will be used to instruct the AI on how to analyze the documents.");
return null;
}
private string? ValidateOutputRules(string outputRules)
{
if(string.IsNullOrWhiteSpace(outputRules))
return T("Please provide a description of your output rules. This rules will be used to instruct the AI on how to format the output of the analysis.");
return null;
}
private async Task Analyze()
{
if (this.IsNoPolicySelectedOrProtected)
return;
await this.AutoSave();
await this.form!.Validate();
if (!this.inputIsValid)
return;
#warning TODO
}
}

View File

@ -382,6 +382,96 @@ UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::CODING::COMMONCODINGLANGUAGEEXTENSIONS::T
-- None
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::CODING::COMMONCODINGLANGUAGEEXTENSIONS::T810547195"] = "None"
-- Please provide a brief description of your policy. Describe or explain what your policy does. This description will be shown to users in AI Studio.
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T1182372158"] = "Please provide a brief description of your policy. Describe or explain what your policy does. This description will be shown to users in AI Studio."
-- Settings
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T1258653480"] = "Settings"
-- No, the policy can be edited
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T1286595725"] = "No, the policy can be edited"
-- Please provide a description of your analysis rules. This rules will be used to instruct the AI on how to analyze the documents.
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T1291179736"] = "Please provide a description of your analysis rules. This rules will be used to instruct the AI on how to analyze the documents."
-- Input and output rules
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T1714738288"] = "Input and output rules"
-- Yes, protect this policy
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T1762380857"] = "Yes, protect this policy"
-- Please give your policy a name that provides information about the intended purpose. The name will be displayed to users in AI Studio.
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T1786783201"] = "Please give your policy a name that provides information about the intended purpose. The name will be displayed to users in AI Studio."
-- Please provide a description for your policy. This description will be used to inform users about the purpose of your document analysis policy.
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T1837166236"] = "Please provide a description for your policy. This description will be used to inform users about the purpose of your document analysis policy."
-- Common settings
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T1963959073"] = "Common settings"
-- Analyze document
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T2053296240"] = "Analyze document"
-- Document analysis policies
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T2064879144"] = "Document analysis policies"
-- The name of your policy must be between 6 and 60 characters long.
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T2435013256"] = "The name of your policy must be between 6 and 60 characters long."
-- Are you sure you want to delete the document analysis policy '{0}'?
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T2582525917"] = "Are you sure you want to delete the document analysis policy '{0}'?"
-- Document analysis
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T2708005534"] = "Document analysis"
-- Policy name
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T2879019438"] = "Policy name"
-- Analysis rules
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T3108719748"] = "Analysis rules"
-- Delete this policy
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T3119086260"] = "Delete this policy"
-- Policy {0}
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T3157740273"] = "Policy {0}"
-- The description of your policy must be between 32 and 512 characters long.
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T3285636934"] = "The description of your policy must be between 32 and 512 characters long."
-- Add policy
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T3357792182"] = "Add policy"
-- You have not yet added any document analysis policies.
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T3394850216"] = "You have not yet added any document analysis policies."
-- Document Analysis Assistant
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T348883878"] = "Document Analysis Assistant"
-- A policy with this name already exists. Please choose a different name.
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T3584374593"] = "A policy with this name already exists. Please choose a different name."
-- Output rules
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T3918193587"] = "Output rules"
-- Please provide a name for your policy. This name will be used to identify the policy in AI Studio.
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T4040507702"] = "Please provide a name for your policy. This name will be used to identify the policy in AI Studio."
-- Delete document analysis policy
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T4293094335"] = "Delete document analysis policy"
-- Please provide a description of your output rules. This rules will be used to instruct the AI on how to format the output of the analysis.
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T652187065"] = "Please provide a description of your output rules. This rules will be used to instruct the AI on how to format the output of the analysis."
-- Policy description
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T748735777"] = "Policy description"
-- Would you like to protect this policy so that you cannot accidentally edit or delete it?
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T80597472"] = "Would you like to protect this policy so that you cannot accidentally edit or delete it?"
-- Here you have the option to save different policies for various document analysis assistants and switch between them.
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::DOCUMENTANALYSIS::DOCUMENTANALYSISASSISTANT::T848153710"] = "Here you have the option to save different policies for various document analysis assistants and switch between them."
-- Provide a list of bullet points and some basic information for an e-mail. The assistant will generate an e-mail based on that input.
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::EMAIL::ASSISTANTEMAIL::T1143222914"] = "Provide a list of bullet points and some basic information for an e-mail. The assistant will generate an e-mail based on that input."
@ -3604,6 +3694,33 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGDATASOURCES::T774473
-- Local Directory
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGDATASOURCES::T926703547"] = "Local Directory"
-- When enabled, you can preselect some ERI server options.
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGDOCUMENTANALYSIS::T1280666275"] = "When enabled, you can preselect some ERI server options."
-- Assistant: Document Analysis
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGDOCUMENTANALYSIS::T1372406750"] = "Assistant: Document Analysis"
-- Most document analysis options can be customized and saved directly in the assistant. For this, the assistant has an auto-save function.
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGDOCUMENTANALYSIS::T1870328357"] = "Most document analysis options can be customized and saved directly in the assistant. For this, the assistant has an auto-save function."
-- Would you like to preselect one of your profiles?
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGDOCUMENTANALYSIS::T2221665527"] = "Would you like to preselect one of your profiles?"
-- Preselect document analysis options?
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGDOCUMENTANALYSIS::T2230062650"] = "Preselect document analysis options?"
-- No document analysis options are preselected
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGDOCUMENTANALYSIS::T3317802895"] = "No document analysis options are preselected"
-- Close
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGDOCUMENTANALYSIS::T3448155331"] = "Close"
-- Document analysis options are preselected
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGDOCUMENTANALYSIS::T3945756386"] = "Document analysis options are preselected"
-- Preselect one of your profiles?
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGDOCUMENTANALYSIS::T4004501229"] = "Preselect one of your profiles?"
-- When enabled, you can preselect some ERI server options.
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGERISERVER::T1280666275"] = "When enabled, you can preselect some ERI server options."
@ -4477,6 +4594,9 @@ UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T986578435"] = "Install Pandoc"
-- Get coding and debugging support from an LLM.
UI_TEXT_CONTENT["AISTUDIO::PAGES::ASSISTANTS::T1243850917"] = "Get coding and debugging support from an LLM."
-- Analyze a document regarding defined rules and extract key information.
UI_TEXT_CONTENT["AISTUDIO::PAGES::ASSISTANTS::T1271524187"] = "Analyze a document regarding defined rules and extract key information."
-- Business
UI_TEXT_CONTENT["AISTUDIO::PAGES::ASSISTANTS::T131837803"] = "Business"
@ -4522,6 +4642,9 @@ UI_TEXT_CONTENT["AISTUDIO::PAGES::ASSISTANTS::T2547582747"] = "Synonyms"
-- Find synonyms for a given word or phrase.
UI_TEXT_CONTENT["AISTUDIO::PAGES::ASSISTANTS::T2712131461"] = "Find synonyms for a given word or phrase."
-- Document Analysis
UI_TEXT_CONTENT["AISTUDIO::PAGES::ASSISTANTS::T2770149758"] = "Document Analysis"
-- AI Studio Development
UI_TEXT_CONTENT["AISTUDIO::PAGES::ASSISTANTS::T2830810750"] = "AI Studio Development"
@ -5044,6 +5167,9 @@ UI_TEXT_CONTENT["AISTUDIO::SETTINGS::DATAMODEL::PREVIEWFEATURESEXTENSIONS::T1587
-- Read PDF: Preview of our PDF reading system where you can read and extract text from PDF files
UI_TEXT_CONTENT["AISTUDIO::SETTINGS::DATAMODEL::PREVIEWFEATURESEXTENSIONS::T1847148141"] = "Read PDF: Preview of our PDF reading system where you can read and extract text from PDF files"
-- Document Analysis: Preview of our document analysis system where you can analyze and extract information from documents
UI_TEXT_CONTENT["AISTUDIO::SETTINGS::DATAMODEL::PREVIEWFEATURESEXTENSIONS::T1848209619"] = "Document Analysis: Preview of our document analysis system where you can analyze and extract information from documents"
-- Plugins: Preview of our plugin system where you can extend the functionality of the app
UI_TEXT_CONTENT["AISTUDIO::SETTINGS::DATAMODEL::PREVIEWFEATURESEXTENSIONS::T2056842933"] = "Plugins: Preview of our plugin system where you can extend the functionality of the app"

View File

@ -0,0 +1,28 @@
@using AIStudio.Settings
@inherits SettingsDialogBase
<MudDialog>
<TitleContent>
<PreviewPrototype/>
<MudText Typo="Typo.h6" Class="d-flex align-center">
<MudIcon Icon="@Icons.Material.Filled.DocumentScanner" Class="mr-2"/>
@T("Assistant: Document Analysis")
</MudText>
</TitleContent>
<DialogContent>
<MudPaper Class="pa-3 mb-8 border-dashed border rounded-lg">
<ConfigurationOption OptionDescription="@T("Preselect document analysis options?")" LabelOn="@T("Document analysis options are preselected")" LabelOff="@T("No document analysis options are preselected")" State="@(() => this.SettingsManager.ConfigurationData.ERI.PreselectOptions)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.ERI.PreselectOptions = updatedState)" OptionHelp="@T("When enabled, you can preselect some ERI server options.")"/>
<ConfigurationMinConfidenceSelection Disabled="@(() => !this.SettingsManager.ConfigurationData.ERI.PreselectOptions)" RestrictToGlobalMinimumConfidence="@true" SelectedValue="@(() => this.SettingsManager.ConfigurationData.ERI.MinimumProviderConfidence)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.ERI.MinimumProviderConfidence = selectedValue)"/>
<ConfigurationSelect OptionDescription="@T("Preselect one of your profiles?")" Disabled="@(() => !this.SettingsManager.ConfigurationData.ERI.PreselectOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.ERI.PreselectedProfile)" Data="@ConfigurationSelectDataFactory.GetProfilesData(this.SettingsManager.ConfigurationData.Profiles)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.ERI.PreselectedProfile = selectedValue)" OptionHelp="@T("Would you like to preselect one of your profiles?")"/>
<MudText Typo="Typo.body1" Class="mb-3">
@T("Most document analysis options can be customized and saved directly in the assistant. For this, the assistant has an auto-save function.")
</MudText>
</MudPaper>
</DialogContent>
<DialogActions>
<MudButton OnClick="@this.Close" Variant="Variant.Filled">
@T("Close")
</MudButton>
</DialogActions>
</MudDialog>

View File

@ -0,0 +1,3 @@
namespace AIStudio.Dialogs.Settings;
public partial class SettingsDialogDocumentAnalysis : SettingsDialogBase;

View File

@ -26,6 +26,12 @@
</MudText>
<MudStack Row="@true" Wrap="@Wrap.Wrap" Class="mb-3">
<AssistantBlock TSettings="SettingsDialogWritingEMails" Name="@T("E-Mail")" Description="@T("Generate an e-mail for a given context.")" Icon="@Icons.Material.Filled.Email" Link="@Routes.ASSISTANT_EMAIL"/>
@if (PreviewFeatures.PRE_DOCUMENT_ANALYSIS_2025.IsEnabled(this.SettingsManager))
{
<AssistantBlock TSettings="SettingsDialogDocumentAnalysis" Name="@T("Document Analysis")" Description="@T("Analyze a document regarding defined rules and extract key information.")" Icon="@Icons.Material.Filled.DocumentScanner" Link="@Routes.ASSISTANT_DOCUMENT_ANALYSIS"/>
}
<AssistantBlock TSettings="SettingsDialogMyTasks" Name="@T("My Tasks")" Description="@T("Analyze a text or an email for tasks you need to complete.")" Icon="@Icons.Material.Filled.Task" Link="@Routes.ASSISTANT_MY_TASKS"/>
<AssistantBlock TSettings="SettingsDialogAgenda" Name="@T("Agenda Planner")" Description="@T("Generate an agenda for a given meeting, seminar, etc.")" Icon="@Icons.Material.Filled.CalendarToday" Link="@Routes.ASSISTANT_AGENDA"/>
<AssistantBlock TSettings="SettingsDialogJobPostings" Name="@T("Job Posting")" Description="@T("Generate a job posting for a given job description.")" Icon="@Icons.Material.Filled.Work" Link="@Routes.ASSISTANT_JOB_POSTING"/>

View File

@ -27,5 +27,6 @@ public sealed partial class Routes
public const string ASSISTANT_BIAS = "/assistant/bias-of-the-day";
public const string ASSISTANT_ERI = "/assistant/eri";
public const string ASSISTANT_AI_STUDIO_I18N = "/assistant/ai-studio/i18n";
public const string ASSISTANT_DOCUMENT_ANALYSIS = "/assistant/document-analysis";
// ReSharper restore InconsistentNaming
}

View File

@ -84,6 +84,8 @@ public sealed class Data
public DataCoding Coding { get; init; } = new();
public DataERI ERI { get; init; } = new();
public DataDocumentAnalysis DocumentAnalysis { get; init; } = new(x => x.DocumentAnalysis);
public DataTextSummarizer TextSummarizer { get; init; } = new();

View File

@ -0,0 +1,18 @@
using System.Linq.Expressions;
namespace AIStudio.Settings.DataModel;
public sealed class DataDocumentAnalysis(Expression<Func<Data, DataDocumentAnalysis>>? configSelection = null)
{
/// <summary>
/// The default constructor for the JSON deserializer.
/// </summary>
public DataDocumentAnalysis() : this(null)
{
}
/// <summary>
/// Configured document analysis policies.
/// </summary>
public List<DataDocumentAnalysisPolicy> Policies { get; set; } = [];
}

View File

@ -0,0 +1,47 @@
using AIStudio.Provider;
namespace AIStudio.Settings.DataModel;
public sealed class DataDocumentAnalysisPolicy
{
/// <summary>
/// Preselect the policy name?
/// </summary>
public string PolicyName { get; set; } = string.Empty;
/// <summary>
/// Preselect the policy description?
/// </summary>
public string PolicyDescription { get; set; } = string.Empty;
/// <summary>
/// Is this policy protected? If so, it cannot be deleted or modified by the user.
/// This is useful for policies that are distributed by the organization.
/// </summary>
public bool IsProtected { get; set; }
/// <summary>
/// The rules for the document analysis policy.
/// </summary>
public string AnalysisRules { get; set; } = string.Empty;
/// <summary>
/// The rules for the output of the document analysis, e.g., the desired format, structure, etc.
/// </summary>
public string OutputRules { get; set; } = string.Empty;
/// <summary>
/// The minimum confidence level required for a provider to be considered.
/// </summary>
public ConfidenceLevel MinimumProviderConfidence { get; set; } = ConfidenceLevel.NONE;
/// <summary>
/// Which LLM provider should be preselected?
/// </summary>
public string PreselectedProvider { get; set; } = string.Empty;
/// <summary>
/// Preselect a profile?
/// </summary>
public string PreselectedProfile { get; set; } = string.Empty;
}

View File

@ -11,4 +11,5 @@ public enum PreviewFeatures
PRE_PLUGINS_2025,
PRE_READ_PDF_2025,
PRE_DOCUMENT_ANALYSIS_2025,
}

View File

@ -13,6 +13,7 @@ public static class PreviewFeaturesExtensions
PreviewFeatures.PRE_PLUGINS_2025 => TB("Plugins: Preview of our plugin system where you can extend the functionality of the app"),
PreviewFeatures.PRE_READ_PDF_2025 => TB("Read PDF: Preview of our PDF reading system where you can read and extract text from PDF files"),
PreviewFeatures.PRE_DOCUMENT_ANALYSIS_2025 => TB("Document Analysis: Preview of our document analysis system where you can analyze and extract information from documents"),
_ => TB("Unknown preview feature")
};

View File

@ -20,6 +20,7 @@ public static class PreviewVisibilityExtensions
if (visibility >= PreviewVisibility.PROTOTYPE)
{
features.Add(PreviewFeatures.PRE_RAG_2024);
features.Add(PreviewFeatures.PRE_DOCUMENT_ANALYSIS_2025);
}
if (visibility >= PreviewVisibility.EXPERIMENTAL)

View File

@ -18,6 +18,7 @@ public enum Components
JOB_POSTING_ASSISTANT,
BIAS_DAY_ASSISTANT,
ERI_ASSISTANT,
DOCUMENT_ANALYSIS_ASSISTANT,
// ReSharper disable InconsistentNaming
I18N_ASSISTANT,