Finished the function for importing arbitrary documents (#516)

This commit is contained in:
Thorsten Sommer authored and GitHub committed 2025-06-30 21:51:02 +02:00
1 parent aaedf667fe
commit 68f5bb1512
5 files changed
+123 -47

No files matched your search

@@ -38,8 +38,7 @@ public partial class ReadFileContent : MSGComponentBase
return;
}
var streamId = Guid.NewGuid().ToString();
var fileContent = await this.RustService.ReadArbitraryFileData(selectedFile.SelectedFilePath, streamId, int.MaxValue);
var fileContent = await this.RustService.ReadArbitraryFileData(selectedFile.SelectedFilePath, int.MaxValue);
await this.FileContentChanged.InvokeAsync(fileContent);
}
}
@@ -8,7 +8,7 @@ public static class ContentStreamSseHandler
private static readonly ConcurrentDictionary<string, List<ContentStreamPptxImageData>> CHUNKED_IMAGES = new();
private static readonly ConcurrentDictionary<string, int> CURRENT_SLIDE_NUMBERS = new();
public static string ProcessEvent(ContentStreamSseEvent? sseEvent, bool extractImages = true)
public static string? ProcessEvent(ContentStreamSseEvent? sseEvent, bool extractImages = true)
{
switch (sseEvent)
{
@@ -16,40 +16,50 @@ public static class ContentStreamSseHandler
switch (sseEvent.Metadata)
{
case ContentStreamTextMetadata:
return $"{sseEvent.Content}\n";
return sseEvent.Content;
case ContentStreamPdfMetadata pdfMetadata:
var pageNumber = pdfMetadata.Pdf?.PageNumber ?? 0;
return $"# Page {pageNumber}\n{sseEvent.Content}";
return $"""
# Page {pageNumber}
{sseEvent.Content}
""";
case ContentStreamSpreadsheetMetadata spreadsheetMetadata:
var sheetName = spreadsheetMetadata.Spreadsheet?.SheetName;
var rowNumber = spreadsheetMetadata.Spreadsheet?.RowNumber;
var spreadSheetResult = new StringBuilder();
if (rowNumber == 1)
spreadSheetResult.AppendLine($"\n# {sheetName}");
spreadSheetResult.AppendLine($"{sseEvent.Content}");
if (rowNumber == 0)
{
spreadSheetResult.AppendLine();
spreadSheetResult.AppendLine($"# {sheetName}");
}
spreadSheetResult.Append(sseEvent.Content);
return spreadSheetResult.ToString();
case ContentStreamDocumentMetadata:
case ContentStreamImageMetadata:
return $"{sseEvent.Content}";
return sseEvent.Content;
case ContentStreamPresentationMetadata presentationMetadata:
var slideNumber = presentationMetadata.Presentation?.SlideNumber ?? 0;
var image = presentationMetadata.Presentation?.Image ?? null;
var presentationResult = new StringBuilder();
var streamId = sseEvent.StreamId;
CURRENT_SLIDE_NUMBERS.TryGetValue(streamId!, out var currentSlideNumber);
if (slideNumber != currentSlideNumber)
{
presentationResult.AppendLine();
presentationResult.AppendLine($"# Slide {slideNumber}");
}
presentationResult.Append($"{sseEvent.Content}");
if (image is not null)
if(!string.IsNullOrWhiteSpace(sseEvent.Content))
presentationResult.AppendLine(sseEvent.Content);
if (extractImages && image is not null)
{
var imageId = $"{streamId}-{image.Id!}";
var isEnd = ProcessImageSegment(imageId, image);
@@ -58,8 +68,8 @@ public static class ContentStreamSseHandler
}
CURRENT_SLIDE_NUMBERS[streamId!] = slideNumber;
return presentationResult.ToString();
return presentationResult.Length is 0 ? null : presentationResult.ToString();
default:
return sseEvent.Content;
}
@@ -68,7 +78,7 @@ public static class ContentStreamSseHandler
return sseEvent.Content;
default:
return string.Empty;
return null;
}
}
@@ -5,9 +5,10 @@ namespace AIStudio.Tools.Services;
public sealed partial class RustService
{
public async Task<string> ReadArbitraryFileData(string path, string streamId, int maxChunks)
public async Task<string> ReadArbitraryFileData(string path, int maxChunks, bool extractImages = false)
{
var requestUri = $"/retrieval/fs/extract?path={Uri.EscapeDataString(path)}&stream_id={streamId}";
var streamId = Guid.NewGuid().ToString();
var requestUri = $"/retrieval/fs/extract?path={Uri.EscapeDataString(path)}&stream_id={streamId}&extract_images={extractImages}";
var request = new HttpRequestMessage(HttpMethod.Get, requestUri);
var response = await this.http.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
@@ -36,8 +37,10 @@ public sealed partial class RustService
var sseEvent = JsonSerializer.Deserialize<ContentStreamSseEvent>(jsonContent);
if (sseEvent is not null)
{
var content = ContentStreamSseHandler.ProcessEvent(sseEvent, false);
resultBuilder.Append(content);
var content = ContentStreamSseHandler.ProcessEvent(sseEvent, extractImages);
if(content is not null)
resultBuilder.AppendLine(content);
chunkCount++;
}
}
@@ -1,5 +1,6 @@
# v0.9.49, build 224 (2025-06-xx xx:xx UTC)
- Added a library by Nils Kruthoff (`nilskruthoff`) that allows AI Studio to read PowerPoint files. This feature is not yet available in the UI, but it will soon be available. Thanks, Nils, for that great contribution.
- Added a library by Nils Kruthoff (`nilskruthoff`) that allows AI Studio to read PowerPoint files. Thanks, Nils, for that great contribution.
- Added support for loading arbitrary document data into some assistants. This functionality replaces the previous PDF reading function and was contributed by Nils as well.
- Improved the loading of some components that require data fetching, resulting in a more responsive UI.
- Improved some awkward phrasings in English and German.
- Improved the implementation of configuration plugins to enhance long-term maintainability.