Files
Luna/Luna.Configuration/Services/Providers/ProviderOptionsProvider.cs
T
darman a4ed65e452 Add Luna.Configuration with TOML-based agent and provider config
Implement configuration system with embedded TOML resources for agent
and provider definitions, custom IConfigurationSource/Provider for
agent and provider options, and DI extension methods. Includes config
models for agents, providers, sessions, and Telegram integration.
2026-04-04 04:09:57 +02:00

64 lines
2.3 KiB
C#

using System.Text.RegularExpressions;
using Tomlyn;
namespace Luna.Configuration.Services.Providers;
internal sealed class ProviderOptionsProvider(string? searchPath = null)
{
private readonly EmbeddedResourceLoader embeddedResourceLoader = new();
public IEnumerable<(string Name, ProviderOptions Options)> GetProviderOptions()
{
return string.IsNullOrWhiteSpace(searchPath)
? GetProviderOptionsFromEmbeddedResources()
: GetProviderOptionsFromFiles();
}
private IEnumerable<(string Name, ProviderOptions Options)> GetProviderOptionsFromFiles()
{
ArgumentException.ThrowIfNullOrEmpty(searchPath);
var files = Directory.Exists(searchPath)
? Directory.EnumerateFiles(searchPath, "Provider.*.toml")
: [];
foreach (var file in files)
{
var name = Path.GetFileName(file).ToProviderName();
using var reader = File.OpenText(file);
var providerOptions = TomlSerializer.Deserialize<ProviderOptions>(reader);
yield return (name, providerOptions
?? throw new FormatException($"Invalid provider config file: {file}"));
}
}
private IEnumerable<(string Name, ProviderOptions Options)> GetProviderOptionsFromEmbeddedResources()
{
var resources = embeddedResourceLoader.ListResources("Provider.*.toml");
foreach (var resource in resources)
{
var name = resource.ToProviderName();
var content = embeddedResourceLoader.LoadAsync(resource).GetAwaiter().GetResult();
var providerOptions = TomlSerializer.Deserialize<ProviderOptions>(content);
yield return (name, providerOptions
?? throw new FormatException($"Invalid provider config embedded resource: {resource}"));
}
}
}
internal static partial class ProviderStringExtensions
{
[GeneratedRegex(@"Provider\.(.+)\.toml", RegexOptions.IgnoreCase | RegexOptions.Compiled)]
private static partial Regex ProviderNameRegex { get; }
extension(string str)
{
public string ToProviderName() => ProviderNameRegex.Match(str) is { Success: true } match
? match.Groups[1].Value
: throw new FormatException($"Invalid provider config file name: {str}");
}
}