diff --git a/SqlDatabaseVectorSearch/Components/Pages/Ask.razor b/SqlDatabaseVectorSearch/Components/Pages/Ask.razor index 60a2af1..dbc459e 100644 --- a/SqlDatabaseVectorSearch/Components/Pages/Ask.razor +++ b/SqlDatabaseVectorSearch/Components/Pages/Ask.razor @@ -196,15 +196,16 @@ } else if (delta.StreamState == StreamState.Append) { - // Adds tokens to the assistant message as they are received - assistantMessage.Text += delta.Answer; + // Adds tokens to the assistant message as they are received. + assistantMessage.RawText += delta.Answer; + + // Updates the Text property to remove citations, if any. + assistantMessage.Text = RemoveCitations(assistantMessage.RawText); } else if (delta.StreamState == StreamState.End) { // Extracts citations, if any. - var (cleanText, citations) = ExtractCitations(assistantMessage.Text); - - assistantMessage.Text = cleanText; + var (_, citations) = ExtractCitations(assistantMessage.RawText); assistantMessage.Citations = citations; assistantMessage.IsCompleted = true; @@ -294,6 +295,16 @@ await JSRuntime.InvokeVoidAsync("scrollTo", chat); } + private static string RemoveCitations(string? text) + { + if (string.IsNullOrEmpty(text)) + { + return string.Empty; + } + + return (text.AsSpan().IndexOf("= 0 ? text[..index] : text).TrimEnd(); + } + private static (string, IEnumerable) ExtractCitations(string? text) { var citations = new List(); @@ -326,6 +337,13 @@ public class Message { + private string? rawText; + public string? RawText + { + get => rawText ?? Text; + set => rawText = value; + } + public string? Text { get; set; } public required string Role { get; set; } diff --git a/SqlDatabaseVectorSearch/Services/ChatService.cs b/SqlDatabaseVectorSearch/Services/ChatService.cs index 4e8d0fa..77686cb 100644 --- a/SqlDatabaseVectorSearch/Services/ChatService.cs +++ b/SqlDatabaseVectorSearch/Services/ChatService.cs @@ -144,24 +144,6 @@ public class ChatService(IChatCompletionService chatCompletionService, Tokenizer - The citations must always be in a list at the end of the response, one after the other. Never add the citations between the actual response text or inside sentences. - Do NOT add any text after the citations. - ALWAYS leave a blank line between your answer and the first citation. - - Examples (CORRECT): - Here is my complete answer to your question. I'm providing all the information based on the context. - - Paris is the capital - largest city in France - - Examples (WRONG): - Here is my answer Paris is the capital of France and is known for the Eiffel Tower with more text. - Paris is the capital of France and is known for the Eiffel Tower Here is my answer. - Here is my answer. (without any citations when information is available) - Here is my answer. - Paris is the capital of France and is known for the Eiffel Tower More answer text. - - YOU MUST SEPARATE YOUR ANSWER FROM CITATIONS WITH A BLANK LINE. - NEVER INSERT CITATIONS WITHIN YOUR ANSWER TEXT. - CITATIONS MUST ONLY APPEAR AT THE END, AFTER A BLANK LINE. - IF YOU DO NOT FOLLOW THESE RULES, YOUR RESPONSE IS INVALID. """); var prompt = new StringBuilder($"""