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.
This commit is contained in:
2026-04-04 04:09:57 +02:00
parent dcdd77b5ae
commit a4ed65e452
18 changed files with 456 additions and 0 deletions
@@ -0,0 +1,40 @@
using Luna.Configuration.Services.Agents;
using Luna.Configuration.Services.Providers;
using Microsoft.Extensions.Configuration;
namespace Luna.Configuration.Extensions;
public static class ConfigurationBuilderExtensions
{
private static string[] AgentConfigSearchPaths =
[
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".luna", "agents")
];
private static string[] ProviderConfigSearchPaths =
[
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".luna", "providers")
];
extension(IConfigurationBuilder builder)
{
public IConfigurationBuilder AddLunaConfiguration()
{
builder.Add(new AgentOptionsConfigurationSource());
foreach (var searchPath in AgentConfigSearchPaths)
{
builder.Add(new AgentOptionsConfigurationSource(searchPath));
}
builder.Add(new ProviderOptionsConfigurationSource());
foreach (var searchPath in ProviderConfigSearchPaths)
{
builder.Add(new ProviderOptionsConfigurationSource(searchPath));
}
return builder;
}
}
}
@@ -0,0 +1,72 @@
using Microsoft.Extensions.DependencyInjection;
namespace Luna.Configuration.Extensions;
public static class ServiceCollectionExtensions
{
extension(IServiceCollection services)
{
public IServiceCollection AddProviderOptions(string? name)
{
services.AddOptions<ProviderOptions>(name)
.BindConfiguration($"Providers:{name}")
.Validate(
options => !string.IsNullOrWhiteSpace(options.ApiKey),
$"{name} options missing ApiKey")
.Validate(
options => !string.IsNullOrWhiteSpace(options.ApiUrl),
$"{name} options missing ApiUrl")
.Validate(
options => options.Models is { Length: > 0 },
$"{name} options missing Model definitions")
.ValidateOnStart();
return services;
}
public IServiceCollection AddAgentOptions(string? name)
{
services.AddOptions<AgentOptions>(name)
.BindConfiguration($"Agents:{name}")
.Validate(
options => !string.IsNullOrWhiteSpace(options.Provider),
$"{name} options missing Provider")
.Validate(
options => !string.IsNullOrWhiteSpace(options.ModelId),
$"{name} options missing ModelId")
.Validate(
options => !string.IsNullOrWhiteSpace(options.Instructions),
$"{name} options missing Instructions")
.Validate(
options => options.MaxContextTokens > 0,
$"{name} options must have MaxContextTokens greater than 0")
.ValidateOnStart();
return services;
}
public IServiceCollection AddSessionOptions()
{
services.AddOptions<SessionOptions>()
.BindConfiguration("Session")
.Validate(
options => options.ContextTokenThreshold > 0,
"Session options must have ContextTokenThreshold greater than 0")
.ValidateOnStart();
return services;
}
public IServiceCollection AddTelegramOptions()
{
services.AddOptions<TelegramOptions>()
.BindConfiguration("Channels:Telegram")
.Validate(
options => !string.IsNullOrWhiteSpace(options.BotToken),
"Telegram options missing BotToken")
.ValidateOnStart();
return services;
}
}
}