Fixed media transcripts reaching the AI without the prompt injection filter (#1083)

This commit is contained in:
Thorsten Sommer authored and GitHub committed 2026-10-18 13:48:18 +02:00
1 parent 8e3660a74a
commit 34d88f723c
14 files changed
+423 -63

No files matched your search

@@ -3,6 +3,8 @@ using System.Text;
using AIStudio.Settings;
using AIStudio.Tools.PluginSystem;
using AIStudio.Tools.Rust;
using AIStudio.Tools.Security;
using AIStudio.Tools.Services;
namespace AIStudio.Tools.Media;
@@ -155,6 +157,29 @@ internal static class PersistentMediaTranscript
}
}
/// <summary>
/// Reads a transcript for an AI, through the runtime like every document.
/// </summary>
/// <remarks>
/// The runtime filters prompt injections while it reads, so a transcript must never reach an AI
/// by any other way, such as reading the file directly. What the filter removed is reported under
/// the recording: the transcript is a file AI Studio made, while the recording is the file the
/// user chose.
/// </remarks>
/// <param name="rustService">The runtime service.</param>
/// <param name="transcript">A transcript with the status READY.</param>
/// <param name="mediaPath">The audio or video file the transcript belongs to.</param>
/// <param name="reportingScope">The action the transcript is read for, or null when it is read for none.</param>
/// <param name="token">The cancellation token.</param>
/// <returns>The filtered text of the transcript, or why it could not be read.</returns>
public static Task<FileExtractionResult> ReadTranscriptAsync(RustService rustService, PersistentMediaTranscriptResult transcript, string mediaPath, PromptInjectionReportingScope? reportingScope, CancellationToken token)
{
if (transcript.Status is not PersistentMediaTranscriptStatus.READY)
throw new ArgumentException($"Only a ready transcript can be read, but its status is {transcript.Status}.", nameof(transcript));
return rustService.ReadArbitraryFileData(transcript.TranscriptPath, int.MaxValue, reportAs: PromptInjectionSource.FileContent(mediaPath), reportingScope: reportingScope, token: token);
}
private static PersistentMediaTranscriptResult SourceChanged(MediaTranscriptSlot slot) => PersistentMediaTranscriptResult.Unavailable(PersistentMediaTranscriptStatus.SOURCE_CHANGED, slot, TB("The media file changed while it was being transcribed, so its transcript was not kept."));
/// <summary>
@@ -8,7 +8,9 @@ namespace AIStudio.Tools.Media;
/// <remarks>
/// The transcript itself is not part of it: whoever needs the text reads the file at
/// TranscriptPath, so a transcript reaches the AI by the same path no matter whether it was just
/// made or stored long ago.
/// made or stored long ago. That read always goes through the runtime, which filters prompt
/// injections: PersistentMediaTranscript.ReadTranscriptAsync reads a transcript as a whole, and a
/// data source reads it in pieces for its index.
/// </remarks>
/// <param name="Status">How the request ended.</param>
/// <param name="TranscriptPath">The path of the transcript; empty when the place could not be determined.</param>