← All source files

V6 / 920e1e35d097

Lilith.Extensions.cs

Lilith/Agent/Lilith.Extensions.cs

Unchanged from the preceding version
CS
using Lilith.Core.Logging;
using Lilith.Core.Ollama;
using Lilith.Core.Providers;
using Lilith.Core.LMStudio;

namespace Lilith.Agent;

/// <summary>Agent client creation and logging helpers.</summary>
public static class LilithExtensions
{
    public static void EnsureSystemPromptSeeded(this Lilith agent)
    {
        if (agent.History.Count == 0 || !string.Equals(agent.History[0].Role, "system", StringComparison.OrdinalIgnoreCase))
            throw new InvalidOperationException("Chat history was not seeded with a system prompt.");
    }

    public static void EnsureSystemPromptContent(this Lilith agent)
    {
        agent.EnsureSystemPromptSeeded();
        if (string.IsNullOrWhiteSpace(agent.History[0].Content))
            throw new InvalidOperationException("System prompt content is missing.");
    }

    public static void EnsureContextInitialized(this Lilith agent)
    {
        if (agent.ContextMax <= 0)
            throw new InvalidOperationException("Model context window was not initialized.");
    }

    public static async Task<ProviderClient> CreateClient(this Lilith agent, bool startServerIfNotRunning = true) =>
        agent.Credentials.Provider switch
        {
            ProviderKind.Ollama => await OllamaClient.CreateClient(agent.Credentials.Model, agent.Credentials.SystemPrompt,
                agent.Logger, startServerIfNotRunning, agent.Credentials.AgentName),
            ProviderKind.LMStudio => await LMStudioClient.CreateClient(agent.Credentials.Model, agent.Credentials.SystemPrompt,
                agent.Logger, startServerIfNotRunning, agent.Credentials.AgentName),
            _ => throw new ArgumentOutOfRangeException(nameof(agent.Credentials.Provider))
        };

    public static void HistoryWriteLine(this Logger logger, string description = "", string color = LogColors.Gray) =>
        logger.WriteLine("History", description, color);

    public static void TokensWriteLine(this Logger logger, string description = "", string color = LogColors.Gray) =>
        logger.WriteLine("Tokens", description, color);

    public static void SystemWriteLine(this Logger logger, string description = "", string color = LogColors.Cyan) =>
        logger.WriteLine("System", description, color);

    public static void SystemPromptWriteLine(this Logger logger, string description = "", string color = LogColors.Cyan) =>
        logger.WriteLine("SYSTEM", description, color);

    public static void LogTokenCounts(this Lilith agent, TimeSpan? elapsed = null, string color = LogColors.Gray)
    {
        if (agent.History.Count < 2)
        {
            return;
        }

        int? promptTokens = agent.History[^2].Tokens;
        int? completionTokens = agent.History[^1].Tokens;
        if (promptTokens.HasValue || completionTokens.HasValue)
        {
            string elapsedText = elapsed is { } duration ? $"  elapsed: {duration.TotalSeconds:F2}s" : string.Empty;
            agent.Logger.TokensWriteLine($"prompt: {promptTokens ?? 0}  completion: {completionTokens ?? 0}  total: {(promptTokens ?? 0) + (completionTokens ?? 0)}{elapsedText}", color);
        }
    }
}