feat(ai-ux): deduplicate AI queries, handle ServiceUnavailable retries, and optimize reader canvas graph prerendering (#44)
This Pull Request encapsulates all outstanding AI, Blazor InteractiveAuto lifecycle, pgvector, and Firefox authorization/session compatibility fixes. ### Key Accomplishments: 1. **Concurrent Request Deduplication (Option B):** Implemented a thread-safe active task registry in `KnowledgeService` that groups concurrent graph extraction queries for the same content, preventing duplicate AI calls completely. 2. **Resilience Strategy for Downstream Demands:** Extended the `ai-retry` resilience pipeline to automatically intercept and retry on temporary Google API `503 ServiceUnavailable` / `high demand` spikes. 3. **Interactive Graph Generation Guard (Option A):** Prevented server-side prerender-phase graph requests in the reader canvas component. 4. **Firefox Compatibility & Cookie Handler:** Implemented an authentication endpoint and hybrid hidden-form submission flow to solve login, registration, and logout redirections and cookies securely. 5. **Autoscrolling & Graph Exclusions:** Added concept-to-block smooth scrolling, active block badging, and filtered out markdown code blocks from being extracted as nodes. All unit tests compiled and passed 100% cleanly. --------- Co-authored-by: Marek Jasiński <jasins.marek@gmail.com> Reviewed-on: #44 Co-authored-by: Antigravity <antigravity@google.com> Co-committed-by: Antigravity <antigravity@google.com>
This commit was merged in pull request #44.
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using FluentAssertions;
|
||||
using GeminiDotnet;
|
||||
using GeminiDotnet.Extensions.AI;
|
||||
using Microsoft.Extensions.AI;
|
||||
using Xunit;
|
||||
|
||||
namespace NexusReader.Application.Tests.Services;
|
||||
|
||||
public class GeminiEmbeddingTests
|
||||
{
|
||||
[Fact]
|
||||
public async Task TestGeminiEmbedding_ModelsAndDimensions()
|
||||
{
|
||||
var apiKey = Environment.GetEnvironmentVariable("GEMINI_API_KEY");
|
||||
if (string.IsNullOrEmpty(apiKey))
|
||||
{
|
||||
Console.WriteLine("Skipping test: GEMINI_API_KEY is not set.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Test Model 1: gemini-embedding-001
|
||||
try
|
||||
{
|
||||
var generator = new GeminiEmbeddingGenerator(new GeminiClientOptions
|
||||
{
|
||||
ApiKey = apiKey,
|
||||
ModelId = "gemini-embedding-001"
|
||||
});
|
||||
|
||||
// 1. Without dimensions (default)
|
||||
var responseDefault = await generator.GenerateAsync(new[] { "Hello world" });
|
||||
var vectorDefault = responseDefault.First().Vector.ToArray();
|
||||
Console.WriteLine($"[TEST] gemini-embedding-001 default dimensions: {vectorDefault.Length}");
|
||||
|
||||
// 2. With 768 dimensions
|
||||
var response768 = await generator.GenerateAsync(new[] { "Hello world" }, new EmbeddingGenerationOptions { Dimensions = 768 });
|
||||
var vector768 = response768.First().Vector.ToArray();
|
||||
Console.WriteLine($"[TEST] gemini-embedding-001 768 dimensions: {vector768.Length}");
|
||||
|
||||
// 3. With 1536 dimensions
|
||||
var response1536 = await generator.GenerateAsync(new[] { "Hello world" }, new EmbeddingGenerationOptions { Dimensions = 1536 });
|
||||
var vector1536 = response1536.First().Vector.ToArray();
|
||||
Console.WriteLine($"[TEST] gemini-embedding-001 1536 dimensions: {vector1536.Length}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"[TEST] gemini-embedding-001 failed: {ex}");
|
||||
}
|
||||
|
||||
// Test Model 2: models/embedding-001
|
||||
try
|
||||
{
|
||||
var generator = new GeminiEmbeddingGenerator(new GeminiClientOptions
|
||||
{
|
||||
ApiKey = apiKey,
|
||||
ModelId = "models/embedding-001"
|
||||
});
|
||||
|
||||
var response = await generator.GenerateAsync(new[] { "Hello world" });
|
||||
var vector = response.First().Vector.ToArray();
|
||||
Console.WriteLine($"[TEST] models/embedding-001 default dimensions: {vector.Length}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"[TEST] models/embedding-001 failed: {ex}");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user