using System.Text.RegularExpressions; using Tomlyn; namespace Luna.Configuration.Services.Agents; internal sealed class AgentOptionsProvider(string? searchPath = null) { private readonly EmbeddedResourceLoader embeddedResourceLoader = new(); public IEnumerable GetAgentOptions() { return string.IsNullOrWhiteSpace(searchPath) ? GetAgentOptionsFromEmbeddedResources() : GetAgentOptionsFromFiles(); } private IEnumerable GetAgentOptionsFromFiles() { ArgumentException.ThrowIfNullOrEmpty(searchPath); var files = Directory.Exists(searchPath) ? Directory.EnumerateFiles(searchPath, "Agent.*.toml") : []; foreach (var file in files) { using var reader = File.OpenText(file); var agentOptions = TomlSerializer.Deserialize(reader); yield return agentOptions ?? throw new FormatException($"Invalid agent config file: {file}"); } } private IEnumerable GetAgentOptionsFromEmbeddedResources() { var resources = embeddedResourceLoader.ListResources("Agent.*.toml"); foreach (var resource in resources) { var content = embeddedResourceLoader.LoadAsync(resource).GetAwaiter().GetResult(); var agentOptions = TomlSerializer.Deserialize(content); yield return agentOptions ?? throw new FormatException($"Invalid agent config embedded resource: {resource}"); } } } internal static partial class StringExtensions { [GeneratedRegex(@"Agent\.(.+)\.toml", RegexOptions.IgnoreCase | RegexOptions.Compiled)] private static partial Regex AgentNameRegex { get; } extension(string str) { public string ToAgentName() => AgentNameRegex.Match(str) is { Success: true } match ? match.Groups[1].Value : throw new FormatException($"Invalid agent config file name: {str}"); } }