using AIStudio.Settings; using AIStudio.Tools.Security; namespace AIStudio.Tools.Services.Indexing; /// /// Reads the text of a file through the runtime, in the pieces the chunking cuts along. /// /// /// The runtime filters prompt injections while it reads, so the text arrives filtered. /// internal static class ExtractedFileText { /// /// Reads the text of a file. /// /// The runtime. /// The path of the file. /// The embedding provider whose tokenizer counts the pieces. /// The source the user is told about when passages were filtered out, or null for the file itself. /// The cancellation token. /// The text, empty when the file has none. public static async Task ReadAsync(RustService rustService, string filePath, EmbeddingProvider embeddingProvider, PromptInjectionSource? reportAs, CancellationToken token) { var segments = new List(); await foreach (var segment in rustService.StreamArbitraryFileDataWithTokenCounts(filePath, embeddingProvider, reportAs, token)) { var normalized = TextChunker.NormalizeSegment(segment.Content); if (!string.IsNullOrWhiteSpace(normalized)) segments.Add(new(normalized, segment.TokenCount, segment.PageNumber)); } return new(string.Join("\n", segments.Select(segment => segment.Text)).Trim(), segments); } }