Added local RAG (#756)

Co-authored-by: Thorsten Sommer <SommerEngineering@users.noreply.github.com>
This commit is contained in:
Paul KoudelkaandThorsten Sommer authored and GitHub committed 2026-09-09 18:43:37 +02:00
1 parent d043fbc8f0
commit c7b42bee96
179 files changed
+276977 -1421

No files matched your search

@@ -3,6 +3,9 @@ using AIStudio.Tools.Services;
using Microsoft.AspNetCore.Components;
// This component has a parameter called File, which would shadow the file system's File class:
using IOFile = System.IO.File;
namespace AIStudio.Components;
public partial class SelectFile : MSGComponentBase
@@ -28,6 +31,24 @@ public partial class SelectFile : MSGComponentBase
[Parameter]
public Func<string, string?> Validation { get; set; } = _ => null;
/// <summary>
/// When true, the file can also be chosen by dropping it onto this component.
/// </summary>
[Parameter]
public bool EnableDragDrop { get; set; }
/// <summary>
/// On which layer to register the drop area. Higher layers have priority over lower layers.
/// </summary>
[Parameter]
public int Layer { get; set; } = DropLayers.ROOT;
/// <summary>
/// Catch all documents that are hovered over the AI Studio window and not only over the drop zone.
/// </summary>
[Parameter]
public bool CatchAllDocuments { get; set; }
[Inject]
public RustService RustService { get; set; } = null!;
@@ -73,4 +94,46 @@ public partial class SelectFile : MSGComponentBase
this.isFileDialogOpen = false;
}
}
/// <summary>
/// Takes the first dropped path which leads to a usable file.
/// </summary>
/// <remarks>
/// This component carries exactly one file, so a multi-selection cannot be honored as a whole.
/// A dropped folder is rejected instead of being read as "the first file inside it": the user
/// was asked for a file, and picking one for them would be a surprise.
/// </remarks>
/// <param name="paths">The dropped paths.</param>
private async Task PathsDropped(List<string> paths)
{
foreach (var path in paths)
{
if (!IOFile.Exists(path))
continue;
if (this.Filter is { Length: > 0 } && !FileTypes.IsAllowedPath(path, this.Filter))
continue;
this.Logger.LogInformation("The user dropped the file '{DroppedFilePath}'.", path);
this.InternalFileChanged(path);
return;
}
this.Logger.LogWarning("None of the {Count} dropped path(s) could be used as a file.", paths.Count);
await this.MessageBus.SendWarning(new(Icons.Material.Filled.Warning, this.GetDropWarning(paths)));
}
private string GetDropWarning(List<string> paths)
{
// Naming the actual mistake beats a generic "that did not work". Dropping a folder onto a
// file picker is the likeliest of them:
if (paths.Any(Directory.Exists))
return T("Please drop a file, not a folder.");
// The file exists, so the file type filter is what turned it down:
if (paths.Any(IOFile.Exists))
return T("Please drop a file with a supported file type.");
return T("The dropped file could not be accessed. Please choose it with the file chooser instead.");
}
}