Hide discarded scan character candidates
This commit is contained in:
parent
09f003b0cd
commit
1ead298fa8
@ -67,6 +67,7 @@ var tests = new (string Name, Action Test)[]
|
||||
("Character sex hints are conservative and reviewable", CharacterSexHintsAreConservativeAndReviewable),
|
||||
("Character discovery does not truncate scan review candidates", CharacterDiscoveryDoesNotTruncateScanReviewCandidates),
|
||||
("Character discovery rejects sentence-start words", CharacterDiscoveryRejectsSentenceStartWords),
|
||||
("Manuscript scan preview keeps only auto-selected character candidates", ManuscriptScanPreviewKeepsOnlyAutoSelectedCharacterCandidates),
|
||||
("Scan review aliases feed Story Intelligence known character context", ScanReviewAliasesFeedStoryIntelligenceKnownCharacterContext),
|
||||
("Scan review post supports full-book form submissions", ScanReviewPostSupportsFullBookFormSubmissions),
|
||||
("Story Intelligence experience boot does not serialise live model", StoryIntelligenceExperienceBootDoesNotSerialiseLiveModel),
|
||||
@ -1315,6 +1316,23 @@ static void CharacterDiscoveryRejectsSentenceStartWords()
|
||||
Assert(!actionCandidates.Any(candidate => candidate.Text is "Door" or "Glass" or "Window"), "Repeated sentence-start action nouns must not become character candidates.");
|
||||
}
|
||||
|
||||
static void ManuscriptScanPreviewKeepsOnlyAutoSelectedCharacterCandidates()
|
||||
{
|
||||
var preview = new ManuscriptScanPreview
|
||||
{
|
||||
CharacterCandidates =
|
||||
[
|
||||
new() { TemporaryCharacterKey = "c-colin", Name = "Colin", MentionCount = 4, QualityScore = 7, Category = "ProbableCharacter" },
|
||||
new() { TemporaryCharacterKey = "c-door", Name = "Door", MentionCount = 4, QualityScore = 2, Category = "PossibleCharacter" },
|
||||
new() { TemporaryCharacterKey = "c-road", Name = "Road", MentionCount = 8, QualityScore = 1, Category = "Excluded" }
|
||||
]
|
||||
};
|
||||
|
||||
var candidates = WordCompanionService.DiscoverManuscriptScanCharacterCandidates(preview);
|
||||
Assert(candidates.Count == 1, $"Scan preview should keep only auto-selected character candidates; got {candidates.Count}.");
|
||||
Assert(candidates[0].Name == "Colin", "Scan preview should keep probable character candidates.");
|
||||
}
|
||||
|
||||
static void StoryIntelligenceExperienceBootDoesNotSerialiseLiveModel()
|
||||
{
|
||||
var view = File.ReadAllText(Path.Combine(AppContext.BaseDirectory, "../../../../PlotLine/Views/Development/StoryIntelligenceExperience.cshtml"));
|
||||
|
||||
@ -658,6 +658,7 @@ public sealed class WordCompanionService(
|
||||
}
|
||||
|
||||
return DiscoverCharacterCandidates(manuscriptText)
|
||||
.Where(IsAutoSelectedScanCharacterCandidate)
|
||||
.Select((candidate, index) => new ManuscriptScanCharacterCandidatePreview
|
||||
{
|
||||
TemporaryCharacterKey = $"c-{StableCandidateKey(candidate.Text, index)}",
|
||||
@ -995,7 +996,7 @@ public sealed class WordCompanionService(
|
||||
IReadOnlyList<ManuscriptScanCharacterCandidatePreview> candidates)
|
||||
=> candidates
|
||||
.Where(candidate => !string.IsNullOrWhiteSpace(candidate.Name))
|
||||
.Where(candidate => !string.Equals(candidate.Category, "Excluded", StringComparison.OrdinalIgnoreCase))
|
||||
.Where(IsAutoSelectedScanCharacterCandidate)
|
||||
.Where(candidate =>
|
||||
candidate.Name.Split(' ', StringSplitOptions.RemoveEmptyEntries).Length > 1
|
||||
|| candidate.QualityScore >= 4
|
||||
@ -1008,6 +1009,12 @@ public sealed class WordCompanionService(
|
||||
.ThenBy(candidate => candidate.Name, StringComparer.OrdinalIgnoreCase)
|
||||
.ToList();
|
||||
|
||||
private static bool IsAutoSelectedScanCharacterCandidate(WordCompanionCharacterCandidateDto candidate)
|
||||
=> string.Equals(candidate.Category, "ProbableCharacter", StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
private static bool IsAutoSelectedScanCharacterCandidate(ManuscriptScanCharacterCandidatePreview candidate)
|
||||
=> string.Equals(candidate.Category, "ProbableCharacter", StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
private static string StableCandidateKey(string name, int index)
|
||||
{
|
||||
var slug = Regex.Replace(name.ToLowerInvariant(), @"[^a-z0-9]+", "-").Trim('-');
|
||||
|
||||
@ -2349,12 +2349,11 @@
|
||||
const discovery = await postJson("/api/word-companion/manuscript/discover-characters", {
|
||||
projectId: preview.projectID,
|
||||
documentText: documentTextForDiscovery,
|
||||
includeExcluded: true
|
||||
includeExcluded: false
|
||||
});
|
||||
preview.characterCandidates = mapOnboardingCharacterCandidates(discovery?.candidates);
|
||||
preview.characterCandidateCount = preview.characterCandidates
|
||||
.filter((candidate) => String(candidate.category || "").toLowerCase() !== "excluded")
|
||||
.length;
|
||||
preview.characterCandidates = mapOnboardingCharacterCandidates(discovery?.candidates)
|
||||
.filter((candidate) => String(candidate.category || "").toLowerCase() === "probablecharacter");
|
||||
preview.characterCandidateCount = preview.characterCandidates.length;
|
||||
} catch (discoveryError) {
|
||||
console.warn("Unable to refine onboarding character candidates.", discoveryError);
|
||||
preview.characterCandidates = [];
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user