mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2026-10-14 13:13:48 +00:00
Fixed prompt injection warnings waiting for other actions to finish (#1053)
This commit is contained in:
1 parent
a3c6b29313
commit
57dda9ff8b
25 files changed
+589
-146
No files matched your search
@@ -400,7 +400,12 @@ public sealed class ContentText : IContent
|
||||
[JsonIgnore]
|
||||
public IReadOnlySet<string> RuntimeAttachmentWebAddresses { get; internal set; } = new HashSet<string>(StringComparer.Ordinal);
|
||||
|
||||
public async Task<string> PrepareTextContentForAI()
|
||||
/// <summary>
|
||||
/// Builds the text the AI gets for this message, with the content of its attached documents.
|
||||
/// </summary>
|
||||
/// <param name="reportingScope">The request this message is part of, which tells the user once about everything filtered out of its attachments, or null when the request reads no documents.</param>
|
||||
/// <returns>The text for the AI.</returns>
|
||||
public async Task<string> PrepareTextContentForAI(PromptInjectionReportingScope? reportingScope)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
var attachmentWebAddresses = new HashSet<string>(StringComparer.Ordinal);
|
||||
@@ -447,13 +452,6 @@ public sealed class ContentText : IContent
|
||||
LOGGER.LogWarning("File attachments which need Pandoc could not be processed because the Pandoc version check failed.");
|
||||
}
|
||||
|
||||
//
|
||||
// One report for the whole batch: attaching twenty documents must produce one
|
||||
// dialog listing all of them, not twenty dialogs in a row.
|
||||
//
|
||||
var guardService = Program.SERVICE_PROVIDER.GetRequiredService<PromptInjectionGuardService>();
|
||||
await using var promptInjectionScope = guardService.BeginAction();
|
||||
|
||||
//
|
||||
// The document blocks are collected separately, so we only announce attached
|
||||
// files when at least one of them could actually be read. Announcing files we
|
||||
@@ -475,7 +473,7 @@ public sealed class ContentText : IContent
|
||||
continue;
|
||||
}
|
||||
|
||||
var extraction = await Program.RUST_SERVICE.ReadArbitraryFileData(document.FilePath, int.MaxValue);
|
||||
var extraction = await Program.RUST_SERVICE.ReadArbitraryFileData(document.FilePath, int.MaxValue, reportingScope: reportingScope);
|
||||
if (!extraction.HasUsableContent)
|
||||
{
|
||||
LOGGER.LogError("Reading the file attachment '{FilePath}' failed and it will not be sent: code={ErrorCode}, message='{ErrorMessage}'.", document.FilePath, extraction.ErrorCode, extraction.ErrorMessage);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using AIStudio.Provider;
|
||||
using AIStudio.Provider.OpenAI;
|
||||
using AIStudio.Settings;
|
||||
using AIStudio.Tools.Security;
|
||||
|
||||
namespace AIStudio.Chat;
|
||||
|
||||
@@ -30,6 +31,16 @@ public static class ListContentBlockExtensions
|
||||
//
|
||||
var canProcessImages = provider.SupportsImageInput();
|
||||
|
||||
//
|
||||
// One report for the whole request: every message of the conversation reads its attached
|
||||
// documents anew, all at the same time. Twenty documents must produce one dialog listing
|
||||
// all of them, not twenty dialogs in a row. A request without documents has nothing to
|
||||
// report, and needs no scope.
|
||||
//
|
||||
await using var reportingScope = blocks.Any(block => block.Content is ContentText text && text.FileAttachments.MayContainDocuments())
|
||||
? Program.SERVICE_PROVIDER.GetRequiredService<PromptInjectionGuardService>().BeginAction()
|
||||
: null;
|
||||
|
||||
var messageTaskList = new List<Task<IMessageBase>>(blocks.Count);
|
||||
foreach (var block in blocks)
|
||||
{
|
||||
@@ -65,7 +76,7 @@ public static class ListContentBlockExtensions
|
||||
return Task.Run(async () => new TextMessage
|
||||
{
|
||||
Role = roleTransformer(block.Role),
|
||||
Content = await text.PrepareTextContentForAI(),
|
||||
Content = await text.PrepareTextContentForAI(reportingScope),
|
||||
} as IMessageBase);
|
||||
}
|
||||
|
||||
@@ -92,7 +103,7 @@ public static class ListContentBlockExtensions
|
||||
Role = roleTransformer(block.Role),
|
||||
Content =
|
||||
[
|
||||
innerTextSubContentFactory(await text.PrepareTextContentForAI()),
|
||||
innerTextSubContentFactory(await text.PrepareTextContentForAI(reportingScope)),
|
||||
..images,
|
||||
]
|
||||
} as IMessageBase;
|
||||
|
||||
@@ -3,4 +3,16 @@ namespace AIStudio.Chat;
|
||||
public static class ListFileAttachmentExtensions
|
||||
{
|
||||
public static bool ContainsImages(this List<FileAttachment> attachments) => attachments.Any(attachment => attachment.IsImage);
|
||||
|
||||
/// <summary>
|
||||
/// Whether preparing the message for the AI may read a document through the runtime.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Every attachment but a picture counts: its type is checked again with the latest rules
|
||||
/// before it is read, cf. FileAttachment.Normalize, and may turn out to be a document then.
|
||||
/// Checking that here would touch every file twice, which takes long on a network drive.
|
||||
/// </remarks>
|
||||
/// <param name="attachments">The attachments of the message.</param>
|
||||
/// <returns>True when a document may be read.</returns>
|
||||
public static bool MayContainDocuments(this List<FileAttachment> attachments) => attachments.Any(attachment => !attachment.IsImage);
|
||||
}
|
||||
Reference in new issue
Block a user