diff --git a/Legba.Engine/Legba.Engine.csproj b/Legba.Engine/Legba.Engine.csproj
index ff15f3c..cf38ffc 100644
--- a/Legba.Engine/Legba.Engine.csproj
+++ b/Legba.Engine/Legba.Engine.csproj
@@ -5,7 +5,7 @@
true
enable
enable
- 2.0.0.0
+ 2.1.0.0
@@ -14,12 +14,13 @@
-
-
-
-
+
+
+
+
-
+
+
diff --git a/Legba.Engine/Models/OpenAi/Message.cs b/Legba.Engine/Models/OpenAi/Message.cs
index 04a008a..4d64281 100644
--- a/Legba.Engine/Models/OpenAi/Message.cs
+++ b/Legba.Engine/Models/OpenAi/Message.cs
@@ -37,34 +37,34 @@ public string DisplayText
}
[JsonIgnore]
- public System.Windows.HorizontalAlignment MessageAlignment
+ public System.Windows.Media.Brush BackgroundColor
{
get
{
if (Role == Enums.Role.System || IsInitialSourceCode)
{
- return System.Windows.HorizontalAlignment.Center;
+ return System.Windows.Media.Brushes.Gold;
}
return IsSentByUser
- ? System.Windows.HorizontalAlignment.Right
- : System.Windows.HorizontalAlignment.Left;
+ ? System.Windows.Media.Brushes.LightBlue
+ : System.Windows.Media.Brushes.LightGray;
}
}
[JsonIgnore]
- public System.Windows.Media.Brush MessageBackground
+ public System.Windows.TextAlignment Alignment
{
get
{
if (Role == Enums.Role.System || IsInitialSourceCode)
{
- return System.Windows.Media.Brushes.Gold;
+ return System.Windows.TextAlignment.Center;
}
return IsSentByUser
- ? System.Windows.Media.Brushes.LightBlue
- : System.Windows.Media.Brushes.LightGray;
+ ? System.Windows.TextAlignment.Right
+ : System.Windows.TextAlignment.Left;
}
}
}
\ No newline at end of file
diff --git a/Legba.Engine/Models/OpenAi/OpenAiResponse.cs b/Legba.Engine/Models/OpenAi/OpenAiResponse.cs
index 7e08d2a..809b7e2 100644
--- a/Legba.Engine/Models/OpenAi/OpenAiResponse.cs
+++ b/Legba.Engine/Models/OpenAi/OpenAiResponse.cs
@@ -5,15 +5,15 @@ namespace Legba.Engine.Models.OpenAi;
public class OpenAiResponse
{
[JsonPropertyName("id")]
- public string Id { get; set; }
+ public string Id { get; set; } = string.Empty;
[JsonPropertyName("object")]
- public string _object { get; set; }
+ public string _object { get; set; } = string.Empty;
[JsonPropertyName("created")]
public int Created { get; set; }
[JsonPropertyName("model")]
- public string Model { get; set; }
+ public string Model { get; set; } = string.Empty;
[JsonPropertyName("usage")]
- public Usage Usage { get; set; }
+ public Usage Usage { get; set; } = new Usage();
[JsonPropertyName("choices")]
public List Choices { get; set; } = new List();
}
\ No newline at end of file
diff --git a/Legba.Engine/Services/FileCollector.cs b/Legba.Engine/Services/FileCollector.cs
index 85feab6..75349a5 100644
--- a/Legba.Engine/Services/FileCollector.cs
+++ b/Legba.Engine/Services/FileCollector.cs
@@ -9,12 +9,20 @@ public class FileCollector
{
#region Constants and Fields
- private static readonly IReadOnlyList s_fileExtensionsToInclude = [".cs", ".vb", ".xaml"];
+ private static readonly IReadOnlyList s_fileExtensionsToInclude =
+ [
+ ".cs", ".vb", ".xaml", ".xaml.cs", ".xaml.vb", ".vsixmanifest", ".vsct", ".resx",
+ ".targets", ".props", ".ruleset", ".settings", ".cshtml", ".vbhtml", ".aspx", ".ascx"
+ ];
private static readonly IReadOnlyList s_excludedFilePatterns =
- [
- new Regex(@"(AssemblyAttributes|AssemblyInfo|\.g|\.g\.i|\.Designer|\.generated)\.(cs|vb)$",
- RegexOptions.IgnoreCase | RegexOptions.Compiled)
- ];
+ [
+ new Regex(
+ @"(AssemblyInfo|AssemblyAttributes|\.g|\.g\.i|\.Designer|\.generated|\.razor\.cs|\.g\.cshtml|\.tt|\.t4|\.Reference)\.(cs|vb|xaml|cshtml)$",
+ RegexOptions.IgnoreCase | RegexOptions.Compiled)
+ ];
+
+ private static readonly IReadOnlyList s_excludedDirectories =
+ [ "bin", "obj", "node_modules", ".vs", "packages" ];
#endregion
@@ -91,20 +99,22 @@ public static async Task> GetFilesFromFoldersAsync(string[
{
ValidateFolderPaths(folderPaths);
- var filePaths = new List();
+ var filePaths = new ConcurrentBag();
- foreach (var folderPath in folderPaths)
+ await Parallel.ForEachAsync(folderPaths, async (folderPath, ct) =>
{
- foreach (var extension in s_fileExtensionsToInclude)
+ await foreach (var file in Directory.EnumerateFiles(folderPath, "*.*", SearchOption.AllDirectories)
+ .ToAsyncEnumerable()
+ .Where(file =>
+ s_fileExtensionsToInclude.Any(ext => file.EndsWith(ext, StringComparison.OrdinalIgnoreCase)) &&
+ !s_excludedDirectories.Any(dir => file.Contains(Path.DirectorySeparatorChar + dir + Path.DirectorySeparatorChar, StringComparison.OrdinalIgnoreCase)) &&
+ !IsExcludedFile(file)))
{
- filePaths.AddRange(
- Directory.GetFiles(folderPath, $"*{extension}",
- SearchOption.AllDirectories));
+ filePaths.Add(file);
}
- }
+ });
- return await Task.FromResult>(
- filePaths.Where(f => !IsExcludedFile(f)).ToList().AsReadOnly());
+ return filePaths.ToList().AsReadOnly();
}
public static async Task> GetFilesFromFilesAsync(string[] filePaths)
@@ -140,7 +150,7 @@ private static void ValidateFolderPaths(string[] folderPaths)
var invalidPaths = folderPaths.Where(fp => !Directory.Exists(fp)).ToArray();
- if (invalidPaths.Any())
+ if (invalidPaths.Length != 0)
{
throw new DirectoryNotFoundException("One or more folder paths do not exist: " + string.Join(", ", invalidPaths));
}
@@ -155,7 +165,7 @@ private static void ValidateFilePaths(string[] filePaths)
var invalidPaths = filePaths.Where(fp => !File.Exists(fp)).ToArray();
- if (invalidPaths.Any())
+ if (invalidPaths.Length != 0)
{
throw new FileNotFoundException("One or more files do not exist: " + string.Join(", ", invalidPaths));
}
diff --git a/Legba.Engine/ViewModels/AboutViewModel.cs b/Legba.Engine/ViewModels/AboutViewModel.cs
index 387418d..dbdacc0 100644
--- a/Legba.Engine/ViewModels/AboutViewModel.cs
+++ b/Legba.Engine/ViewModels/AboutViewModel.cs
@@ -6,7 +6,7 @@ namespace Legba.Engine.ViewModels;
public class AboutViewModel
{
- private int initialCopyrightYear = 2023;
+ private const int INITIAL_COPYRIGHT_YEAR = 2023;
private static readonly Version s_version =
Assembly.GetExecutingAssembly().GetName().Version;
@@ -14,7 +14,7 @@ public class AboutViewModel
public string VersionText =>
$"{s_version.Major}.{s_version.Minor}.{s_version.Revision}";
public string Copyright =>
- $"© {(DateTime.Now.Year == initialCopyrightYear ? $"{initialCopyrightYear}" : $"{initialCopyrightYear} - {DateTime.Now.Year}")}, Lilly Software Consulting";
+ $"© {(DateTime.Now.Year == INITIAL_COPYRIGHT_YEAR ? $"{INITIAL_COPYRIGHT_YEAR}" : $"{INITIAL_COPYRIGHT_YEAR} - {DateTime.Now.Year}")}, Lilly Software Consulting";
public string License =>
"Licensed under the MIT License";
public string ContactInformation =>
diff --git a/Legba.Engine/ViewModels/ChatSessionViewModel.cs b/Legba.Engine/ViewModels/ChatSessionViewModel.cs
index 5faf572..9e65a45 100644
--- a/Legba.Engine/ViewModels/ChatSessionViewModel.cs
+++ b/Legba.Engine/ViewModels/ChatSessionViewModel.cs
@@ -2,7 +2,10 @@
using Microsoft.Extensions.DependencyInjection;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
+using System.Windows;
+using System.Windows.Documents;
using System.Windows.Input;
+using System.Windows.Media;
namespace Legba.Engine.ViewModels;
@@ -44,6 +47,7 @@ public ChatSession? ChatSession
OnPropertyChanged(nameof(ChatSession));
OnPropertyChanged(nameof(HasChatSession));
OnPropertyChanged(nameof(HasChatMessages));
+ OnPropertyChanged(nameof(MessagesDocument));
if (_chatSession != null)
{
@@ -52,6 +56,35 @@ public ChatSession? ChatSession
}
}
+ public FlowDocument MessagesDocument
+ {
+ get
+ {
+ var document = new FlowDocument();
+
+ if (ChatSession == null)
+ {
+ return document;
+ }
+
+ foreach (var message in ChatSession.Messages)
+ {
+ var paragraph = new Paragraph(new Run(message.DisplayText))
+ {
+ Margin = new Thickness(5),
+ TextAlignment = message.Alignment,
+ Background = message.BackgroundColor,
+ Padding = new Thickness(8),
+ FontSize = 14,
+ FontFamily = new FontFamily("Consolas")
+ };
+
+ document.Blocks.Add(paragraph);
+ }
+
+ return document;
+ }
+ }
public bool HasChatSession => ChatSession != null;
public bool HasChatMessages => ChatSession?.Messages.Count > 0;
@@ -80,6 +113,7 @@ public ChatSessionViewModel(IServiceProvider serviceProvider)
private void Messages_CollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
{
OnPropertyChanged(nameof(HasChatMessages));
+ OnPropertyChanged(nameof(MessagesDocument));
}
private void SelectModel(Settings.Model model)
diff --git a/Legba/Legba.csproj b/Legba/Legba.csproj
index e376f98..e10ae85 100644
--- a/Legba/Legba.csproj
+++ b/Legba/Legba.csproj
@@ -8,7 +8,7 @@
true
True
Images\LegbaIcon.ico
- 2.0.0.0
+ 2.1.0.0
f63a3566-54ef-4629-9a95-4254f119e9a0
@@ -24,12 +24,12 @@
-
-
-
-
-
-
+
+
+
+
+
+
diff --git a/Legba/MainWindow.xaml b/Legba/MainWindow.xaml
index d04be1e..ddb2cdd 100644
--- a/Legba/MainWindow.xaml
+++ b/Legba/MainWindow.xaml
@@ -127,38 +127,15 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+