using System.Runtime.CompilerServices; using Luna.Agents.Abstractions; using Luna.Configuration; using Luna.Providers.Abstractions; using Microsoft.Extensions.AI; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; namespace Luna.Agents.Librarian; public class LibrarianAgent( [FromKeyedServices("Mistral")] IProvider provider, IOptionsMonitor options) : IAgent { private readonly IChatClient chatClient = provider.GetChatClient(options.Get(Name).ModelId); public static string Name => "Librarian"; public string DisplayName => Options.DisplayName ?? Name; public string Description => Options.Description ?? string.Empty; public AgentOptions Options { get; init; } = options.Get(Name); public async Task> ProcessAsync( IReadOnlyList messages, CancellationToken ct) { var chatOptions = new ChatOptions { Instructions = Options.Instructions }; var messagesWithoutSystemPrompt = messages .Where(m => m.Role != ChatRole.System) .ToList(); var response = await chatClient.GetResponseAsync(messagesWithoutSystemPrompt, chatOptions, ct); return response.Messages .Where(m => m.Role != ChatRole.System); } public async IAsyncEnumerable ProcessStreamingAsync( IReadOnlyList messages, [EnumeratorCancellation] CancellationToken ct = default) { var chatOptions = new ChatOptions { Instructions = Options.Instructions }; var messagesWithoutSystemPrompt = messages .Where(m => m.Role != ChatRole.System) .ToList(); await foreach (var update in chatClient.GetStreamingResponseAsync(messagesWithoutSystemPrompt, chatOptions, ct)) { if (update.Role != ChatRole.System) { yield return update; } } } }