Surface NER routing provenance (ModelOrigin, NerModelsInvoked) through the pipeline and WPF harness so English/Tamil routing is observable during POC validation. Consolidate docs into solution-guide and add NER logs, topic filtering, and batch UI fixes in the test harness.

This commit is contained in:
Bilal Nazer Ali
2026-07-08 12:18:27 +05:30
parent cf8f5a7232
commit 81220c6ade
51 changed files with 1530 additions and 1463 deletions

View File

@@ -46,6 +46,36 @@ public sealed class OnnxNerPiiDetectorTests
action.Should().Throw<ArgumentException>();
}
[Test]
public void Detect_ModelAvailable_RecordsInvokedModels()
{
var runner = new FakeOnnxNerModelRunner
{
IsModelAvailable = true,
InvokedModelsToReturn = [NerModelOrigin.English, NerModelOrigin.Tamil]
};
var detector = new OnnxNerPiiDetector(runner);
detector.Detect("Mixed prompt");
detector.LastInvokedModels.Should().Equal(NerModelOrigin.English, NerModelOrigin.Tamil);
}
[Test]
public void Detect_ModelUnavailable_ClearsInvokedModels()
{
var runner = new FakeOnnxNerModelRunner
{
IsModelAvailable = false,
InvokedModelsToReturn = [NerModelOrigin.English]
};
var detector = new OnnxNerPiiDetector(runner);
detector.Detect("Any text");
detector.LastInvokedModels.Should().BeEmpty();
}
private static OnnxNerPiiDetector CreateDetector(bool modelAvailable)
{
var runner = new FakeOnnxNerModelRunner { IsModelAvailable = modelAvailable };

View File

@@ -32,7 +32,32 @@ public sealed class RealTamilPipelineTests : RealRoutingNerModelFixture
result.SanitizedPrompt.Should().Contain("<PERSON_1>");
result.SanitizedPrompt.Should().NotContain("ராஜேஷ்");
result.DetectedEntities.Should().Contain(entity =>
entity.Type == PiiEntityType.Person && entity.Source == PiiDetectionSource.Ner);
entity.Type == PiiEntityType.Person
&& entity.Source == PiiDetectionSource.Ner
&& entity.ModelOrigin == NerModelOrigin.Tamil);
result.NerModelsInvoked.Should().Equal(NerModelOrigin.Tamil);
}
[Test]
public void Sanitize_TanglishCustomer_InvokesEnglishNerOnly()
{
const string prompt = "Customer Senthil phone 9876543210 reported a failed UPI transfer.";
var result = _sanitizer.Sanitize(new SanitizationRequest(prompt));
result.NerModelsInvoked.Should().Equal(NerModelOrigin.English);
result.DetectedEntities.Should().Contain(entity =>
entity.Type == PiiEntityType.Person && entity.ModelOrigin == NerModelOrigin.English);
}
[Test]
public void Sanitize_MixedTamilEnglish_InvokesBothNerModels()
{
const string prompt = "வாடிக்கையாளர் Ravi Kumar phone 9876543210 disputed the charge.";
var result = _sanitizer.Sanitize(new SanitizationRequest(prompt));
result.NerModelsInvoked.Should().Equal(NerModelOrigin.English, NerModelOrigin.Tamil);
}
[Test]

View File

@@ -9,11 +9,13 @@ public sealed class FakeOnnxNerModelRunner : IOnnxNerModelRunner
public IReadOnlyList<PiiEntity> EntitiesToReturn { get; set; } = [];
public IReadOnlyList<NerModelOrigin> InvokedModelsToReturn { get; set; } = [NerModelOrigin.English];
public string? LastPredictedText { get; private set; }
public IReadOnlyList<PiiEntity> PredictEntities(string text)
public NerPredictionResult PredictEntities(string text)
{
LastPredictedText = text;
return EntitiesToReturn;
return new NerPredictionResult(EntitiesToReturn, InvokedModelsToReturn);
}
}

View File

@@ -1,3 +1,4 @@
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
using PiiRedaction.Core.Abstractions;
using PiiRedaction.Core.Configuration;
@@ -20,7 +21,8 @@ public static class ProductionPipelineFactory
CreateWithRealModel(new RoutingOnnxNerModelRunner(
englishRunner,
tamilRunner,
options ?? Options.Create(new PiiRedactionOptions { EnableTamilNer = true })));
options ?? Options.Create(new PiiRedactionOptions { EnableTamilNer = true }),
NullLogger<RoutingOnnxNerModelRunner>.Instance));
public static IPiiDetector CreateCompositeDetector(IOnnxNerModelRunner runner) =>
new CompositePiiDetector(