Chat/Lilith.Chat.cscsharp

Documentation

Chat

User-facing chat loop, conversation management, and slash commands.

Lilith.Chat.cs

  • ChatAsync — streams a user message (optional images) and logs token usage.
  • NewConversation / SaveConversation / LoadConversation — session persistence via Agent-Core chat history.
  • HandleInputAsync — parses commands (exit, /new, /history, etc.) or forwards text to ChatAsync.
using Agent.Core.Logging;using Agent.Core.Ollama;namespace Lilith.Agent;public partial class Lilith{    public async Task ChatAsync(string input, List<string>? images = null)    {        Logger.Write("Lilith", "Lilith: ", LogColors.Yellow);        await _client.StreamReply(input, images);        Logger.WriteLine("Lilith", color: LogColors.Yellow);        LogTokenCounts();    }    public void NewConversation()    {        _client.SaveCurrentConversation();        _client.StartNewSession();        _client.ClearHistory();        Logger.WriteLine("System", "New conversation started.", LogColors.Cyan);    }    public void SaveConversation() => _client.SaveCurrentConversation();    public IReadOnlyList<ChatSessionSummary> ListConversations() => _client.ListSavedConversations();    public bool LoadConversation(int displayIndex) => _client.LoadSavedConversation(displayIndex);    public bool LoadConversation(string id) => _client.LoadSavedConversation(id);    public void HandleHistoryCommand(string input)    {        var parts = input.Split(' ', 2, StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);        if (parts.Length == 1)        {            var sessions = ListConversations();            if (sessions.Count == 0)            {                Logger.WriteLine("History", "No saved chats found.", LogColors.Gray);                return;            }            Logger.WriteLine("History", "Saved chats:", LogColors.Cyan);            for (int i = 0; i < sessions.Count; i++)            {                var session = sessions[i];                Logger.WriteLine(                    "History",                    $"{i + 1}. {session.Title} ({session.UpdatedAt.LocalDateTime:g}, {session.MessageCount} messages)",                    LogColors.Gray);            }            Logger.WriteLine("History", "Use /history <number> to load a chat.", LogColors.Gray);            return;        }        if (!int.TryParse(parts[1], out int index))        {            Logger.WriteLine("History", "Usage: /history or /history <number>", LogColors.Orange);            return;        }        if (LoadConversation(index))        {            Logger.WriteLine("History", $"Loaded saved chat #{index}.", LogColors.Cyan);        }        else        {            Logger.WriteLine("History", $"Saved chat #{index} was not found.", LogColors.Orange);        }    }    public void LogTokenCounts()    {        if (History.Count < 2)        {            return;        }        int? promptTokens = History[^2].Tokens;        int? completionTokens = History[^1].Tokens;        if (promptTokens.HasValue || completionTokens.HasValue)        {            Logger.WriteLine(                "Tokens",                $"prompt: {promptTokens ?? 0}  completion: {completionTokens ?? 0}  total: {(promptTokens ?? 0) + (completionTokens ?? 0)}",                LogColors.Gray);        }    }    public async Task<bool> HandleInputAsync(string input)    {        if (input.Equals("/history", StringComparison.OrdinalIgnoreCase) ||            input.StartsWith("/history ", StringComparison.OrdinalIgnoreCase))        {            return TryCatchExtensions.ReturnTrueTryCatch(                () => HandleHistoryCommand(input),                new CatchLog("History", "History command failed.", Logger));        }        return input.ToLowerInvariant() switch        {            "exit" => false,            "/new" => TryCatchExtensions.ReturnTrueTryCatch(                NewConversation,                new CatchLog("System", "Failed to start new conversation.", Logger)),            _ => await TryCatchExtensions.ReturnTrueTryCatchAsync(                () => ChatAsync(input),                new CatchLog("Lilith", "Chat failed.", Logger))        };    }}