// Copyright (c) Microsoft. All rights reserved.
using System.Text;
using Harness.ConsoleReactiveComponents;
using Microsoft.Agents.AI;
namespace Harness.Shared.Console;
///
/// Provides a reusable interactive console loop for running an
/// with streaming output, extensible observers, and mode-aware interaction strategies.
///
public static class HarnessConsole
{
///
/// Runs an interactive console session with the specified agent.
/// Constructs the reactive UI component and the ,
/// wires them together, and awaits the component's
/// (which completes when the user types /exit).
///
/// The agent to interact with.
/// A short prompt to the user, displayed as a placeholder in the input area.
/// Optional configuration options for the console session.
public static async Task RunAgentAsync(AIAgent agent, string userPrompt, HarnessConsoleOptions? options = null)
{
options ??= new();
System.Console.OutputEncoding = Encoding.UTF8;
// Null means use defaults; an explicit (possibly empty) list means use exactly what was provided.
var observers = options.Observers
?? HarnessConsoleOptions.BuildDefaultObservers();
var commandHandlers = options.CommandHandlers
?? HarnessConsoleOptions.BuildDefaultCommandHandlers(agent, options.ModeColors);
var modeProvider = agent.GetService();
var messageInjector = agent.GetService();
AgentSession session = options.SessionFactory is not null
? await options.SessionFactory(agent)
: await agent.CreateSessionAsync();
using var component = new HarnessAppComponent(
placeholder: userPrompt,
initialMode: modeProvider?.GetMode(session),
inputEnabled: messageInjector is not null,
runnerFactory: ux => new HarnessAgentRunner(
agent: agent,
session: session,
modeProvider: modeProvider,
messageInjector: messageInjector,
commandHandlers: commandHandlers,
observers: observers,
ux: ux),
modeColors: options.ModeColors);
// Trigger the initial render of the component now that state is seeded.
component.Render();
try
{
await component.ShutdownTask.ConfigureAwait(false);
}
finally
{
component.Deactivate();
}
System.Console.ResetColor();
System.Console.Write(AnsiEscapes.ResetScrollRegion);
System.Console.Write(AnsiEscapes.EraseScrollbackBuffer);
System.Console.Write(AnsiEscapes.EraseEntireScreen);
System.Console.Write(AnsiEscapes.MoveCursor(1, 1));
System.Console.WriteLine("Goodbye!");
}
}