| File: Model\Assistant\FollowUpPromptViewModel.cs | Web Access |
| Project: src\src\Aspire.Dashboard\Aspire.Dashboard.csproj (Aspire.Dashboard) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics.CodeAnalysis; using Aspire.Dashboard.Model.Markdown; using Markdig.Renderers.Normalize; using Markdig.Syntax; namespace Aspire.Dashboard.Model.Assistant; public sealed class FollowUpPromptViewModel { public required string Text { get; init; } public required string Html { get; init; } public static bool ParseResponseText(MarkdownProcessor markdownProcessor, List<FollowUpPromptViewModel> inProgressFollowUpPrompts, string responseText, bool inProgress) { var document = Markdig.Markdown.Parse(responseText); // Use items with complete content or use all if response is no longer in progress. var completedItems = document.Descendants<ListItemBlock>() .Where(i => !inProgress || (i.LastChild is { } item && !item.IsOpen)) .ToList(); var questions = new List<string>(); foreach (var item in completedItems) { if (TryGetQuestionText(item, out var text)) { questions.Add(text); } } // Only add new follow-up prompts. var followUpPromptAdded = false; for (var i = inProgressFollowUpPrompts.Count; i < completedItems.Count; i++) { var questionText = questions[i]; inProgressFollowUpPrompts.Add(new FollowUpPromptViewModel { Text = questionText, Html = markdownProcessor.ToHtml(questionText, suppressSurroundingParagraph: true) }); followUpPromptAdded = true; } return followUpPromptAdded; } /// <summary> /// Get the list item's markdown as a string. /// </summary> private static bool TryGetQuestionText(ListItemBlock listItem, [NotNullWhen(true)] out string? text) { var paragraph = listItem.Descendants<ParagraphBlock>().FirstOrDefault(); if (paragraph == null) { text = null; return false; } listItem.Remove(paragraph); var markdownDocument = new MarkdownDocument { paragraph }; var writer = new StringWriter(); var renderer = new NormalizeRenderer(writer); renderer.Render(markdownDocument); writer.Flush(); text = writer.ToString(); // Trim bold stars if the question was surrounded with them. if (text.Length >= 4 && text.StartsWith("**") && text.EndsWith("**")) { text = text[2..^2]; } // Trim double quotes if the question was surrounded with them. if (text.Length >= 2 && text.StartsWith('"') && text.EndsWith('"')) { text = text[1..^1]; } return true; } }