// Copyright (c) Microsoft. All rights reserved. using Microsoft.Agents.AI; using Microsoft.Extensions.AI; namespace Harness.Shared.Console; /// /// Abstraction over the harness UI state. All callers (observers, command handlers, /// the agent runner) interact with the UI exclusively through this interface, which /// internally translates each operation into a SetState call on the underlying /// reactive component. /// /// /// This interface is intentionally narrow: it does not expose blocking input methods. /// The agent runner orchestrates input flow via /// objects returned from observers. /// public interface IUXStateDriver { /// /// Gets or sets the current agent mode (e.g. "plan", "execute"). Setting also /// refreshes the rule colour and bottom-panel prompt to match the new mode. /// string? CurrentMode { get; set; } /// /// Echoes a submitted user input as a regular user-input entry in the output area. /// void WriteUserInputEcho(string text); /// /// Writes informational output as an output entry, without a trailing newline. /// Task WriteInfoAsync(string text, ConsoleColor? color = null); /// /// Writes informational output as an output entry, followed by a newline. /// Task WriteInfoLineAsync(string text, ConsoleColor? color = null); /// /// Writes streaming text output from the agent. Successive calls accumulate into a /// single streaming entry that is re-rendered by the text panel. /// Task WriteTextAsync(string text, ConsoleColor? color = null); /// /// Writes a blank-line separator to visually close the streaming output section. /// Task EndStreamingOutputAsync(); /// /// Shows a "(no text response from agent)" warning if no text was received /// and no observer produced follow-up actions. /// Task WriteNoTextWarningAsync(bool hasFollowUpActions); /// /// Switches the bottom panel to streaming mode and starts the spinner. /// void BeginStreaming(); /// /// Stops the spinner without leaving streaming mode. /// void StopSpinner(); /// /// Switches the bottom panel back to text-input mode and stops the spinner. /// void EndStreaming(); /// /// Resets per-turn streaming bookkeeping in preparation for a new agent turn. /// void BeginStreamingOutput(); /// /// Sets the formatted usage text shown on the agent status bar. /// void SetUsageText(string usageText); /// /// Replaces the queued-message display with one entry per pending message. /// void SetQueuedMessages(IReadOnlyList pending); /// /// Appends the supplied questions to the pending follow-up question queue in /// component state. If the queue was empty, the bottom-panel display is /// reconfigured to present the new head question. /// void QueueFollowUpQuestions(IReadOnlyList questions); /// /// Appends a message to the accumulated follow-up response list in component state. /// Called by the runner for direct outputs and by /// the component when a question's continuation produces a response. /// void AddFollowUpResponse(ChatMessage response); /// /// Pops the head of the pending follow-up question queue. Reconfigures the /// bottom-panel display for the new head, or restores the default text-input /// mode if the queue is now empty. /// void AdvanceFollowUpQuestion(); /// /// Returns the current accumulated follow-up responses and clears them in state. /// Called by the runner immediately before invoking the next agent turn. /// IReadOnlyList TakeFollowUpResponses(); /// /// Signals that the application should shut down. Completes the shutdown task /// on the owning component. /// void RequestShutdown(); /// /// Replaces the current agent session with the specified session (e.g., after importing /// a serialized session from a file). /// /// The new session to use. Task ReplaceSessionAsync(AgentSession newSession); }