Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/CompilerBrain/CompilerBrainAIFunctions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public IEnumerable<AIFunction> GetAIFunctions()
yield return AIFunctionFactory.Create(GetProjects, factoryOptions);
yield return AIFunctionFactory.Create(GetDiagnostics, factoryOptions);
yield return AIFunctionFactory.Create(ReadImportantInformationFiles, factoryOptions);
yield return AIFunctionFactory.Create(ReadContextFiles, factoryOptions);
yield return AIFunctionFactory.Create(ReadCode, factoryOptions);
yield return AIFunctionFactory.Create(ReadManyCodes, factoryOptions);
yield return AIFunctionFactory.Create(AddOrReplaceCode, factoryOptions);
Expand Down Expand Up @@ -82,6 +83,12 @@ public RootFile ReadImportantInformationFiles()
return rootFile;
}

[Description("Read context files (AGENTS.md, CLAUDE.md) from working directory or solution root.")]
public ContextFiles ReadContextFiles()
{
return ContextFileLoader.Load(memory.Solution?.FilePath);
}

[Description("Read existing code in current session context, if not found returns null.")]
public string? ReadCode(string projectName, string fileNameOrFullPath)
{
Expand Down
6 changes: 6 additions & 0 deletions src/CompilerBrain/CompilerBrainChatService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ public async Task<AgentRunResponse> ContinueAsync(ResponseContinuationToken cont
string CreateInstructions(SessionMemory memory)
{
var runtimeInfo = MachineRuntimeInformation.FromCurrent();
var contextFiles = ContextFileLoader.Load(memory.Solution?.FilePath);

var inst =
$$"""
Expand Down Expand Up @@ -70,6 +71,11 @@ string CreateInstructions(SessionMemory memory)
- **Avoid unnecessary output** No pleasantries or greetings
""";

foreach (var (fileName, content) in contextFiles.Files)
{
inst += $"\n\n# {fileName}\n\n{content}";
}

return inst;
}
}
59 changes: 59 additions & 0 deletions src/CompilerBrain/ContextFileLoader.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
namespace CompilerBrain;

public static class ContextFileLoader
{
static readonly string[] FileNames = ["AGENTS.md", "CLAUDE.md"];

public static ContextFiles Load(string? solutionPath)
{
var files = new Dictionary<string, string>();

// Build search directories: working directory first, then solution root
var searchDirs = new List<string> { Environment.CurrentDirectory };

if (!string.IsNullOrEmpty(solutionPath))
{
var solutionDir = Path.GetDirectoryName(solutionPath);
if (!string.IsNullOrEmpty(solutionDir) && solutionDir != Environment.CurrentDirectory)
{
searchDirs.Add(solutionDir);
}
}

var seenContents = new HashSet<string>();
foreach (var fileName in FileNames)
{
var content = FindAndReadFile(searchDirs, fileName);
if (content != null && seenContents.Add(content))
{
files[fileName] = content;
}
}

return new ContextFiles(files);
}

static string? FindAndReadFile(List<string> searchDirs, string fileName)
{
foreach (var dir in searchDirs)
{
try
{
foreach (var file in Directory.EnumerateFiles(dir))
{
var name = Path.GetFileName(file);
if (name.Equals(fileName, StringComparison.OrdinalIgnoreCase))
{
return File.ReadAllText(file);
}
}
}
catch
{
// Directory access error - continue to next directory
}
}

return null;
}
}
2 changes: 2 additions & 0 deletions src/CompilerBrain/RequestResponseTypes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ public record struct RootFile
public string? EditorConfig { get; set; }
}

public record struct ContextFiles(Dictionary<string, string> Files);

public readonly record struct CodeLocation(int Start, int Length);

public readonly record struct ReadManyCodesResult(string FilePath, string Code);
Expand Down