Improve context handling in SlideAssistant

This commit is contained in:
hart_s3 2026-02-27 14:46:45 +01:00
parent ec23b0c342
commit b3b0fbe588
3 changed files with 108 additions and 13 deletions

View File

@ -1354,6 +1354,9 @@ UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::SLIDEBUILDER::SLIDEASSISTANT::T24391765"]
-- Target group
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::SLIDEBUILDER::SLIDEASSISTANT::T2709966651"] = "Target group"
-- The result of your previous slide builder session.
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::SLIDEBUILDER::SLIDEASSISTANT::T3000286990"] = "The result of your previous slide builder session."
-- Please provide a title
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::SLIDEBUILDER::SLIDEASSISTANT::T3049299559"] = "Please provide a title"
@ -1366,9 +1369,15 @@ UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::SLIDEBUILDER::SLIDEASSISTANT::T3079776593
-- (Optional) Specify aspects that the LLM should consider when creating the slides. For example, the use of emojis or specific topics that should be highlighted.
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::SLIDEBUILDER::SLIDEASSISTANT::T3476149293"] = "(Optional) Specify aspects that the LLM should consider when creating the slides. For example, the use of emojis or specific topics that should be highlighted."
-- Empty
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::SLIDEBUILDER::SLIDEASSISTANT::T3512147854"] = "Empty"
-- Custom target language
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::SLIDEBUILDER::SLIDEASSISTANT::T3848935911"] = "Custom target language"
-- {0} - Slide Builder Session
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::SLIDEBUILDER::SLIDEASSISTANT::T3922788056"] = "{0} - Slide Builder Session"
-- This assistant helps you create clear, structured slide components from long texts or documents. Enter a presentation title and provide the content either as self-written text or as an uploaded document. Important aspects allow you to add instructions to the LLM regarding output or formatting. Set the number of slides either directly or based on your desired presentation duration. You can also specify the number of bullet points. If the default value of 0 is not changed, the LLM will independently determine how many slides or bullet points to generate. The output can be flexibly generated in various languages and with adjustable complexity.
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::SLIDEBUILDER::SLIDEASSISTANT::T3996977501"] = "This assistant helps you create clear, structured slide components from long texts or documents. Enter a presentation title and provide the content either as self-written text or as an uploaded document. Important aspects allow you to add instructions to the LLM regarding output or formatting. Set the number of slides either directly or based on your desired presentation duration. You can also specify the number of bullet points. If the default value of 0 is not changed, the LLM will independently determine how many slides or bullet points to generate. The output can be flexibly generated in various languages and with adjustable complexity."

View File

@ -3,10 +3,10 @@
<MudTextField T="string" @bind-Text="@this.inputTitle" Validation="@this.ValidatingTitle" Adornment="Adornment.Start" Label="@T("Your title")" Variant="Variant.Outlined" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
<MudTextField T="string" @bind-Text="@this.inputContext" Adornment="Adornment.Start" Lines="6" MaxLines="12" AutoGrow="@false" Label="@T("Your content")" Variant="Variant.Outlined" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
<MudText Typo="Typo.h5" Class="mb-1 mt-6"> @T("Upload documents for input")</MudText>
<MudTextField T="string" @bind-Text="@this.inputContent" Adornment="Adornment.Start" Lines="6" MaxLines="12" AutoGrow="@false" Label="@T("Your content")" Variant="Variant.Outlined" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
<MudText Typo="Typo.h5" Class="mb-1 mt-1"> @T("Upload documents for input")</MudText>
<AttachDocuments Name="Upload documents for input" Layer="@DropLayers.ASSISTANTS" @bind-DocumentPaths="@this.loadedDocumentPaths" CatchAllDocuments="true" UseSmallForm="false" Provider="@this.providerSettings"/>
<MudTextField T="string" AutoGrow="true" Lines="2" @bind-Text="@this.importantAspects" class="mb-3" Label="@T("(Optional) Important Aspects")" HelperText="@T("(Optional) Specify aspects that the LLM should consider when creating the slides. For example, the use of emojis or specific topics that should be highlighted.")" ShrinkLabel="true" Variant="Variant.Outlined" AdornmentIcon="@Icons.Material.Filled.List" Adornment="Adornment.Start"/>
<MudTextField T="string" AutoGrow="true" Lines="2" @bind-Text="@this.importantAspects" class="mb-3 mt-5" Label="@T("(Optional) Important Aspects")" HelperText="@T("(Optional) Specify aspects that the LLM should consider when creating the slides. For example, the use of emojis or specific topics that should be highlighted.")" ShrinkLabel="true" Variant="Variant.Outlined" AdornmentIcon="@Icons.Material.Filled.List" Adornment="Adornment.Start"/>
<MudGrid>
<MudItem xs="4">

View File

@ -22,9 +22,10 @@ public partial class SlideAssistant : AssistantBaseCore<SettingsDialogSlideBuild
- Translate PRESENTATION_TITLE in: {{{this.selectedTargetLanguage.PromptGeneralPurpose(this.customTargetLanguage)}}}
# Content
- You get the following inputs: PRESENTATION_TITLE, PRESENTATION_CONTENT, and any attached documents that may provide additional context or source material.
- You get the following inputs: PRESENTATION_TITLE, PRESENTATION_CONTENT, and any attached documents that may provide additional context or source material (DOCUMENTS).
{{{this.PromptImportantAspects()}}}
{{{this.GetDocumentTaskDescription()}}}
{{{this.PromptImportantAspects()}}}
# Subheadings
- Rule for creating the individual subheadings:
@ -75,15 +76,76 @@ public partial class SlideAssistant : AssistantBaseCore<SettingsDialogSlideBuild
protected override Func<Task> SubmitAction => this.CreateSlideBuilder;
protected override ChatThread ConvertToChatThread => (this.chatThread ?? new()) with
protected override ChatThread ConvertToChatThread
{
SystemPrompt = SystemPrompts.DEFAULT,
};
get
{
if (this.chatThread is null || this.chatThread.Blocks.Count < 2)
{
return new ChatThread
{
SystemPrompt = SystemPrompts.DEFAULT
};
}
var presentationTitle = string.IsNullOrWhiteSpace(this.inputTitle) ? this.T("Empty") : this.inputTitle;
return new ChatThread
{
ChatId = Guid.NewGuid(),
Name = string.Format(T("{0} - Slide Builder Session"), presentationTitle),
SystemPrompt = SystemPrompts.DEFAULT,
Blocks =
[
// Visible user block:
new ContentBlock
{
Time = this.chatThread.Blocks.First().Time,
Role = ChatRole.USER,
HideFromUser = false,
ContentType = ContentType.TEXT,
Content = new ContentText
{
Text = this.T("The result of your previous slide builder session."),
FileAttachments = this.loadedDocumentPaths.ToList(),
}
},
// Hidden user block with inputContent data:
new ContentBlock
{
Time = this.chatThread.Blocks.First().Time,
Role = ChatRole.USER,
HideFromUser = true,
ContentType = ContentType.TEXT,
Content = new ContentText
{
Text = $"""
# PRESENTATION_TITLE
```
{presentationTitle}
```
# PRESENTATION_CONTENT
```
{this.inputContent}
```
""",
}
},
// Then, append the last block of the current chat thread
// (which is expected to be the AI response):
this.chatThread.Blocks.Last(),
]
};
}
}
protected override void ResetForm()
{
this.inputTitle = string.Empty;
this.inputContext = string.Empty;
this.inputContent = string.Empty;
this.selectedTargetGroup = TargetGroup.NO_CHANGE;
if (!this.MightPreselectValues())
{
@ -107,7 +169,7 @@ public partial class SlideAssistant : AssistantBaseCore<SettingsDialogSlideBuild
}
private string inputTitle = string.Empty;
private string inputContext = string.Empty;
private string inputContent = string.Empty;
private string customTargetLanguage = string.Empty;
private TargetGroup selectedTargetGroup;
private CommonLanguages selectedTargetLanguage;
@ -124,7 +186,7 @@ public partial class SlideAssistant : AssistantBaseCore<SettingsDialogSlideBuild
{
var deferredContent = MessageBus.INSTANCE.CheckDeferredMessages<string>(Event.SEND_TO_SLIDE_BUILDER_ASSISTANT).FirstOrDefault();
if (deferredContent is not null)
this.inputContext = deferredContent;
this.inputContent = deferredContent;
await base.OnInitializedAsync();
}
@ -165,11 +227,34 @@ public partial class SlideAssistant : AssistantBaseCore<SettingsDialogSlideBuild
return string.Empty;
return $"""
# Important aspects
Emphasize the following aspects in your presentation:
{this.importantAspects}
""";
}
private string GetDocumentTaskDescription()
{
var numDocuments = this.loadedDocumentPaths.Count(x => x is { Exists: true, IsImage: false });
var numImages = this.loadedDocumentPaths.Count(x => x is { Exists: true, IsImage: true });
return (numDocuments, numImages) switch
{
(0, 1) => "Your task is to analyze a single image file attached as a document.",
(0, > 1) => $"Your task is to analyze {numImages} image file(s) attached as documents.",
(1, 0) => "Your task is to analyze a single DOCUMENT.",
(1, 1) => "Your task is to analyze a single DOCUMENT and 1 image file attached as a document.",
(1, > 1) => $"Your task is to analyze a single DOCUMENT and {numImages} image file(s) attached as documents.",
(> 0, 0) => $"Your task is to analyze {numDocuments} DOCUMENTS. Different DOCUMENTS are divided by a horizontal rule in markdown formatting followed by the name of the document.",
(> 0, 1) => $"Your task is to analyze {numDocuments} DOCUMENTS and 1 image file attached as a document. Different DOCUMENTS are divided by a horizontal rule in Markdown formatting followed by the name of the document.",
(> 0, > 0) => $"Your task is to analyze {numDocuments} DOCUMENTS and {numImages} image file(s) attached as documents. Different DOCUMENTS are divided by a horizontal rule in Markdown formatting followed by the name of the document.",
_ => "Your task is to analyze a single DOCUMENT."
};
}
private async Task<string> PromptLoadDocumentsContent()
{
@ -262,9 +347,10 @@ public partial class SlideAssistant : AssistantBaseCore<SettingsDialogSlideBuild
# PRESENTATION_CONTENT
```
{this.inputContext}
{documentContent}
{this.inputContent}
```
{documentContent}
""",
hideContentFromUser: true,
imageAttachments);