-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(agent): Create repository context services (#26)
- Update FxKit to 0.8.4 (support TryAggregate) - Create DirectoryStructureMessageFactory to build a message with repository structure - Create ProjectFilesMessageFactory to build a message with the content of project key files - Fix ReadAllText(To) extension methods for using abstractions
- Loading branch information
Showing
21 changed files
with
827 additions
and
125 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
26 changes: 26 additions & 0 deletions
26
src/FlowPair/Agent/Services/DirectoryStructureMessageFactory.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
using System.IO.Abstractions; | ||
using AutomaticInterface; | ||
using Ciandt.FlowTools.FlowPair.Chats.Models; | ||
using Ciandt.FlowTools.FlowPair.LocalFileSystem.GetDirectoryStructure; | ||
|
||
namespace Ciandt.FlowTools.FlowPair.Agent.Services; | ||
|
||
public partial interface IDirectoryStructureMessageFactory; | ||
|
||
[GenerateAutomaticInterface] | ||
public sealed class DirectoryStructureMessageFactory( | ||
IGetDirectoryStructureHandler getDirectoryStructureHandler) | ||
: IDirectoryStructureMessageFactory | ||
{ | ||
public Message CreateWithRepositoryStructure(IDirectoryInfo directory) | ||
{ | ||
return new Message( | ||
SenderRole.User, | ||
$""" | ||
The repository has the following directory structure: | ||
``` | ||
{getDirectoryStructureHandler.Execute(directory)} | ||
``` | ||
"""); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
using System.Collections.Immutable; | ||
|
||
namespace Ciandt.FlowTools.FlowPair.Agent.Services; | ||
|
||
public static class FileNaming | ||
{ | ||
public static ImmutableList<string> ProjectExtensions { get; } = | ||
[ | ||
".csproj", ".slnx", // C# | ||
".Rproj", // R | ||
".xcodeproj", ".xcworkspace", // Swift | ||
".project", // Java (Eclipse) | ||
".workspace", // C++ (CodeBlocks) | ||
".idea", // Kotlin, Scala (IntelliJ IDEA) | ||
".prj", // MATLAB | ||
]; | ||
|
||
public static ImmutableList<string> ProjectFiles { get; } = | ||
[ | ||
"Directory.Packages.props", "Directory.Build.props", "Directory.Build.targets", // C# | ||
"pom.xml", "build.gradle", // Java (Maven, Gradle) | ||
"pyproject.toml", "setup.py", // Python | ||
"package.json", // JavaScript | ||
"CMakeLists.txt", "Makefile", // C++ | ||
"composer.json", // PHP | ||
"Gemfile", // Ruby | ||
"Package.swift", // Swift | ||
"DESCRIPTION", // R | ||
"build.gradle.kts", // Kotlin | ||
"tsconfig.json", // TypeScript | ||
"go.mod", // Go (Golang) | ||
"Cargo.toml", // Rust | ||
"build.sbt", // Scala | ||
"pubspec.yaml", // Dart | ||
"Makefile.PL", "dist.ini", // Perl | ||
]; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
using System.IO.Abstractions; | ||
using System.Text; | ||
using AutomaticInterface; | ||
using Ciandt.FlowTools.FlowPair.Chats.Models; | ||
using Ciandt.FlowTools.FlowPair.Common; | ||
using Ciandt.FlowTools.FlowPair.LocalFileSystem.Services; | ||
|
||
namespace Ciandt.FlowTools.FlowPair.Agent.Services; | ||
|
||
public partial interface IProjectFilesMessageFactory; | ||
|
||
[GenerateAutomaticInterface] | ||
public sealed class ProjectFilesMessageFactory( | ||
IWorkingDirectoryWalker workingDirectoryWalker) | ||
: IProjectFilesMessageFactory | ||
{ | ||
public Message CreateWithProjectFilesContent( | ||
IDirectoryInfo rootDirectory, | ||
IEnumerable<string>? extensions = null, | ||
IEnumerable<string>? filenames = null) | ||
{ | ||
return new Message( | ||
SenderRole.User, | ||
workingDirectoryWalker | ||
.FindFilesByExtension(rootDirectory, extensions ?? FileNaming.ProjectExtensions) | ||
.Concat(workingDirectoryWalker.FindFilesByName(rootDirectory, filenames ?? FileNaming.ProjectFiles)) | ||
.Aggregate(new StringBuilder(), (curr, next) => AggregateFileContent(curr, next, rootDirectory)) | ||
.ToString()); | ||
} | ||
|
||
private static StringBuilder AggregateFileContent( | ||
StringBuilder sb, | ||
IFileInfo fileInfo, | ||
IDirectoryInfo rootDirectory) | ||
{ | ||
if (sb.Length > 0) | ||
{ | ||
sb.AppendLine(); | ||
} | ||
|
||
sb.Append("File: "); | ||
sb.Append(rootDirectory.GetRelativePath(fileInfo.FullName)); | ||
sb.AppendLine(); | ||
sb.AppendLine("```"); | ||
fileInfo.ReadAllTextTo(sb); | ||
sb.AppendLine(); | ||
sb.AppendLine("```"); | ||
return sb; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
using System.Text.RegularExpressions; | ||
|
||
namespace Ciandt.FlowTools.FlowPair.LocalFileSystem.Services; | ||
|
||
public static partial class PathAnalyzer | ||
{ | ||
public static string Normalize(string path) | ||
{ | ||
if (OperatingSystem.IsWindows()) | ||
{ | ||
return path.Replace('/', '\\'); | ||
} | ||
else | ||
{ | ||
var tmp = path.AsSpan(); | ||
if (DriveLetterRegex().IsMatch(tmp)) | ||
{ | ||
tmp = tmp[2..]; | ||
|
||
if (tmp.IsEmpty) | ||
return "/"; | ||
} | ||
|
||
return string.Create( | ||
length: tmp.Length, | ||
state: tmp, | ||
action: static (dest, src) => src.Replace(dest, '\\', '/')); | ||
} | ||
} | ||
|
||
[GeneratedRegex("^[a-zA-Z]:")] | ||
private static partial Regex DriveLetterRegex(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
63 changes: 63 additions & 0 deletions
63
tests/FlowPair.Tests/Agent/Services/DirectoryStructureMessageFactoryTest.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
using System.IO.Abstractions; | ||
using Ciandt.FlowTools.FlowPair.Agent.Services; | ||
using Ciandt.FlowTools.FlowPair.Chats.Models; | ||
using Ciandt.FlowTools.FlowPair.LocalFileSystem.GetDirectoryStructure; | ||
using FluentAssertions; | ||
using JetBrains.Annotations; | ||
using NSubstitute; | ||
|
||
namespace Ciandt.FlowTools.FlowPair.Tests.Agent.Services; | ||
|
||
[TestSubject(typeof(DirectoryStructureMessageFactory))] | ||
public class DirectoryStructureMessageFactoryTest | ||
{ | ||
private readonly IGetDirectoryStructureHandler _getDirectoryStructureHandler; | ||
private readonly DirectoryStructureMessageFactory _factory; | ||
|
||
public DirectoryStructureMessageFactoryTest() | ||
{ | ||
_getDirectoryStructureHandler = Substitute.For<IGetDirectoryStructureHandler>(); | ||
_factory = new DirectoryStructureMessageFactory(_getDirectoryStructureHandler); | ||
} | ||
|
||
[Fact] | ||
public void CreateWithRepositoryStructureShouldReturnCorrectMessage() | ||
{ | ||
// Arrange | ||
var mockDirectory = Substitute.For<IDirectoryInfo>(); | ||
const string expectedStructure = "mock/directory/structure"; | ||
_getDirectoryStructureHandler | ||
.Execute(mockDirectory) | ||
.Returns(expectedStructure); | ||
|
||
// Act | ||
var result = _factory.CreateWithRepositoryStructure(mockDirectory); | ||
|
||
// Assert | ||
result.Should().NotBeNull(); | ||
result.Role.Should().Be(SenderRole.User); | ||
result.Content.Should().Contain("The repository has the following directory structure:"); | ||
result.Content.Should().Contain("```"); | ||
result.Content.Should().Contain(expectedStructure); | ||
_getDirectoryStructureHandler.Received(1).Execute(mockDirectory); | ||
} | ||
|
||
[Fact] | ||
public void CreateWithRepositoryStructureShouldHandleEmptyStructure() | ||
{ | ||
// Arrange | ||
var mockDirectory = Substitute.For<IDirectoryInfo>(); | ||
_getDirectoryStructureHandler | ||
.Execute(mockDirectory) | ||
.Returns(string.Empty); | ||
|
||
// Act | ||
var result = _factory.CreateWithRepositoryStructure(mockDirectory); | ||
|
||
// Assert | ||
result.Should().NotBeNull(); | ||
result.Role.Should().Be(SenderRole.User); | ||
result.Content.Should().Contain("The repository has the following directory structure:"); | ||
result.Content.Should().Contain("```"); | ||
} | ||
} |
Oops, something went wrong.