mirror of
https://github.com/marcominerva/SqlDatabaseVectorSearch.git
synced 2026-06-20 12:23:10 +00:00
Add citation handling and styling in Ask.razor
Updated Ask.razor to include regex for citation extraction and display. Introduced a new method to extract citations and updated the Message class to store them. Added a Citation class for individual citation representation. Enhanced app.css with styles for citation display.
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
@page "/ask"
|
||||
@using System.Text.RegularExpressions
|
||||
|
||||
@inject IServiceProvider ServiceProvider
|
||||
@inject IJSRuntime JSRuntime
|
||||
@@ -72,6 +73,23 @@
|
||||
</Tooltip>
|
||||
</div>
|
||||
</div>
|
||||
@if (message.Citations is not null && message.Citations.Count() > 0)
|
||||
{
|
||||
<div class="mt-3 d-flex flex-wrap">
|
||||
@foreach (var citation in message.Citations)
|
||||
{
|
||||
<div class="border rounded p-2 me-2 mb-2 citation-box small">
|
||||
<div>
|
||||
<strong>@citation.FileName</strong> @if (!string.IsNullOrEmpty(citation.PageNumber))
|
||||
{
|
||||
<span class="ms-2">pag. @citation.PageNumber</span>
|
||||
}
|
||||
</div>
|
||||
<div class="text-secondary small mt-1">@citation.Quote</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
}
|
||||
@@ -178,10 +196,17 @@
|
||||
}
|
||||
else if (delta.StreamState == StreamState.Append)
|
||||
{
|
||||
// Adds tokens to the assistant message as they are received
|
||||
assistantMessage.Text += delta.Answer;
|
||||
}
|
||||
else if (delta.StreamState == StreamState.End)
|
||||
{
|
||||
// Extracts citations, if any.
|
||||
var (cleanText, citations) = ExtractCitations(assistantMessage.Text);
|
||||
|
||||
assistantMessage.Text = cleanText;
|
||||
assistantMessage.Citations = citations;
|
||||
|
||||
assistantMessage.IsCompleted = true;
|
||||
assistantMessage.TokenUsage += FormatTokenUsage(delta.TokenUsage);
|
||||
}
|
||||
@@ -269,6 +294,36 @@
|
||||
await JSRuntime.InvokeVoidAsync("scrollTo", chat);
|
||||
}
|
||||
|
||||
private static (string, IEnumerable<Citation>) ExtractCitations(string? text)
|
||||
{
|
||||
var citations = new List<Citation>();
|
||||
|
||||
if (string.IsNullOrEmpty(text))
|
||||
{
|
||||
return (text ?? string.Empty, citations);
|
||||
}
|
||||
|
||||
var pattern = "<citation\\s+filename='([^']*)'\\s+page_number='([^']*)'>(.*?)<\\/citation>";
|
||||
|
||||
var matches = Regex.Matches(text, pattern, RegexOptions.Singleline);
|
||||
foreach (Match match in matches)
|
||||
{
|
||||
if (match.Success && match.Groups.Count == 4)
|
||||
{
|
||||
citations.Add(new Citation
|
||||
{
|
||||
FileName = match.Groups[1].Value,
|
||||
PageNumber = match.Groups[2].Value,
|
||||
Quote = match.Groups[3].Value
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Remove all <citation> tags from the text
|
||||
var cleanText = Regex.Replace(text, pattern, string.Empty, RegexOptions.Singleline).TrimEnd();
|
||||
return (cleanText, citations);
|
||||
}
|
||||
|
||||
public class Message
|
||||
{
|
||||
public string? Text { get; set; }
|
||||
@@ -278,5 +333,17 @@
|
||||
public bool IsCompleted { get; set; }
|
||||
|
||||
public string? TokenUsage { get; set; }
|
||||
|
||||
// List of citations extracted from the answer
|
||||
public IEnumerable<Citation>? Citations { get; set; }
|
||||
}
|
||||
|
||||
public class Citation
|
||||
{
|
||||
public string FileName { get; set; } = null!;
|
||||
|
||||
public string Quote { get; set; } = null!;
|
||||
|
||||
public string PageNumber { get; set; } = null!;
|
||||
}
|
||||
}
|
||||
@@ -62,3 +62,9 @@ h1:focus {
|
||||
.blazor-error-boundary::after {
|
||||
content: "An error has occurred."
|
||||
}
|
||||
|
||||
.citation-box {
|
||||
width: fit-content;
|
||||
max-width: 100%;
|
||||
background-color: #f8f9fa;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user