diff --git a/SqlDatabaseVectorSearch/Components/Pages/Documents.razor b/SqlDatabaseVectorSearch/Components/Pages/Documents.razor
index 2eca5f6..64bd2b4 100644
--- a/SqlDatabaseVectorSearch/Components/Pages/Documents.razor
+++ b/SqlDatabaseVectorSearch/Components/Pages/Documents.razor
@@ -1,7 +1,7 @@
@page "/documents"
@using MimeMapping
-@inject IServiceProvider ServiceProvider
+@inject IServiceScopeFactory ServiceScopeFactory
@inject IJSRuntime JSRuntime
@@ -127,7 +127,7 @@ else
return;
}
- await using var scope = ServiceProvider.CreateAsyncScope();
+ await using var scope = ServiceScopeFactory.CreateAsyncScope();
await LoadDocumentsAsync(scope.ServiceProvider);
StateHasChanged();
@@ -173,7 +173,7 @@ else
await using var inputStream = Model.File.OpenReadStream(20 * 1024 * 1024); // 20 MB
await using var stream = await inputStream.GetMemoryStreamAsync();
- await using var scope = ServiceProvider.CreateAsyncScope();
+ await using var scope = ServiceScopeFactory.CreateAsyncScope();
var vectorSearchService = scope.ServiceProvider.GetRequiredService();
var documentId = string.IsNullOrWhiteSpace(Model.DocumentId) ? null : (Guid?)Guid.Parse(Model.DocumentId);
@@ -223,7 +223,7 @@ else
{
deleteButton.ShowLoading();
- await using var scope = ServiceProvider.CreateAsyncScope();
+ await using var scope = ServiceScopeFactory.CreateAsyncScope();
var documentService = scope.ServiceProvider.GetRequiredService();
await documentService.DeleteAsync(selectedDocumentIds);
diff --git a/SqlDatabaseVectorSearch/Program.cs b/SqlDatabaseVectorSearch/Program.cs
index 7217fe8..4b09813 100644
--- a/SqlDatabaseVectorSearch/Program.cs
+++ b/SqlDatabaseVectorSearch/Program.cs
@@ -159,24 +159,23 @@ var textSearchOptions = new TextSearchProviderOptions()
sb.AppendLine("Use the excerpts below to answer the user.");
sb.AppendLine("Citation rules:");
sb.AppendLine("- Do NOT add inline citations.");
- sb.AppendLine("- At the END of your answer, add a single line exactly like:");
- sb.AppendLine(" Sources: [SourceName](SourceLink), [SourceName](SourceLink)");
+ sb.AppendLine("- At the END of your answer, add a sources label translated in the same language as the user's question.");
+ sb.AppendLine("- The sources label MUST be standard-size italic Markdown text, not a heading and not bold. For example: *Sources* or *Fonti*.");
+ sb.AppendLine("- The citation list MUST be a numbered Markdown list.");
+ sb.AppendLine("- Format each citation with the source name and the localized page label, followed by a Markdown block quote of about 20-30 words from the excerpt that supports the answer.");
+ sb.AppendLine("- The block quote MUST start on a new line with the '>' Markdown character.");
+ sb.AppendLine("- Format each source exactly like:");
+ sb.AppendLine(" *Sources*");
+ sb.AppendLine(" 1. SourceName, localized-page-label PageNumber");
+ sb.AppendLine(" > Supporting excerpt quote of about 20-30 words.");
+ sb.AppendLine("- Do NOT format source names as links.");
sb.AppendLine("- Include ONLY sources you actually used. No duplicates.");
sb.AppendLine();
sb.AppendLine("### Sources (copy/paste-ready)");
foreach (var (i, r) in results.Index())
{
- var name = string.IsNullOrWhiteSpace(r.SourceName) ? $"Source {i + 1}" : r.SourceName;
-
- if (!string.IsNullOrWhiteSpace(r.SourceLink))
- {
- sb.AppendLine($"- [{name}]({r.SourceLink})");
- }
- else
- {
- sb.AppendLine($"- {name}");
- }
+ sb.AppendLine($"- {GetSourceName(r, i)}");
}
sb.AppendLine();
@@ -184,14 +183,21 @@ var textSearchOptions = new TextSearchProviderOptions()
sb.AppendLine("### Excerpts");
foreach (var (i, r) in results.Index())
{
- var name = string.IsNullOrWhiteSpace(r.SourceName) ? $"Source {i + 1}" : r.SourceName;
-
- sb.AppendLine($"[{i + 1}] {name}");
+ sb.AppendLine($"[{i + 1}] {GetSourceName(r, i)}");
sb.AppendLine(r.Text);
- sb.AppendLine();
+ sb.AppendLine("---");
}
return sb.ToString();
+
+ static string GetSourceName(TextSearchProvider.TextSearchResult result, int index)
+ {
+ var name = string.IsNullOrWhiteSpace(result.SourceName) ? $"Source {index + 1}" : result.SourceName;
+ var pageNumber = result.RawRepresentation is int number ? number : (int?)null;
+ var pageText = pageNumber.HasValue ? $", page {pageNumber}" : string.Empty;
+
+ return $"{name}{pageText}";
+ }
}
};
diff --git a/SqlDatabaseVectorSearch/Services/VectorSearchService.cs b/SqlDatabaseVectorSearch/Services/VectorSearchService.cs
index 2c19f40..9333f45 100644
--- a/SqlDatabaseVectorSearch/Services/VectorSearchService.cs
+++ b/SqlDatabaseVectorSearch/Services/VectorSearchService.cs
@@ -105,7 +105,7 @@ public class ContextProvider(ApplicationDbContext dbContext, IEmbeddingGenerator
SourceLink = c.Id.ToString().ToLowerInvariant(),
SourceName = c.Document.Name,
Text = c.Content,
- RawRepresentation = new { c.Id, c.DocumentId, c.PageNumber, c.IndexOnPage, c.Content }
+ RawRepresentation = c.PageNumber
})
.ToListAsync(cancellationToken);