using Agent.Core.Logging;namespace Lilith.Agent.ScenarioSystem;/// <summary>/// Scenario log wrapper for the AdminDashboard test overlay./// The overlay already renders a dedicated "Task" bubble for lines starting with "Delegating to "./// We exploit that convention to create distinct boxes for scenarios + steps without changing Logger./// </summary>internal static class ScenarioLog{ // Unique marker codes so the overlay can style scenario headers differently. // These are embedded inside the "Delegating to ..." line so existing overlay logic still works. private const string ScenarioMarker = "[SCN]"; private const string StepMarker = "[STP]"; public static IDisposable BeginScenario(Lilith lilith, string scenarioId, string? title = null) { WriteDelegation(lilith, ScenarioMarker, $"Scenario {scenarioId}{(string.IsNullOrWhiteSpace(title) ? "" : $" — {title}")}"); return new Scope(() => WriteDelegation(lilith, ScenarioMarker, $"Scenario {scenarioId} — done")); } public static IDisposable BeginStep(Lilith lilith, int stepIndex1, int totalSteps, string prompt) { var shortPrompt = Trunc(prompt, 100); WriteDelegation(lilith, StepMarker, $"Step {stepIndex1}/{totalSteps}: {shortPrompt}"); return new Scope(() => { }); } private static void WriteDelegation(Lilith lilith, string marker, string text) { // IMPORTANT: in the DLL-based runner, the dashboard only receives Logger output. // So emit via Lilith.Logger (and keep the exact "Delegating to ..." prefix). lilith.Logger.WriteLine("Scenario", $"Delegating to {marker} {text}", LogColors.Gray); } private static string Trunc(string s, int max) { s = (s ?? "").Replace("\r", " ").Replace("\n", " ").Trim(); return s.Length > max ? s[..max] + "…" : s; } private sealed class Scope(Action onDispose) : IDisposable { public void Dispose() => onDispose(); }}
Documentation
Lilith (Version 3)
Version 3 Lilith agent library. Entry point: Lilith.cs with partials under Boot/, Chat/, Ollama/, and SystemPrompt/.
Build the solution or run python ../Build-v3.py from this tree.