Restrict loop name fallback for multi-person greetings

This commit is contained in:
Jacob Dubin
2026-05-21 23:21:36 -05:00
parent b99ee5d794
commit 90b48314d3
2 changed files with 37 additions and 2 deletions

View File

@@ -169,14 +169,24 @@ public sealed partial class JiboInteractionService
var tenantRememberedName = personalMemoryStore.GetName(ResolveTenantScope(turn)); var tenantRememberedName = personalMemoryStore.GetName(ResolveTenantScope(turn));
if (!string.IsNullOrWhiteSpace(tenantRememberedName)) return ToDisplayName(tenantRememberedName); if (!string.IsNullOrWhiteSpace(tenantRememberedName)) return ToDisplayName(tenantRememberedName);
if (!string.IsNullOrWhiteSpace(presence.PrimaryPersonId) && var primaryPersonId = presence.PrimaryPersonId;
presence.LoopUserFirstNames.TryGetValue(presence.PrimaryPersonId, out var firstName) && if (CanUseLoopFirstNameFallback(presence) &&
!string.IsNullOrWhiteSpace(primaryPersonId) &&
presence.LoopUserFirstNames.TryGetValue(primaryPersonId, out var firstName) &&
!string.IsNullOrWhiteSpace(firstName)) !string.IsNullOrWhiteSpace(firstName))
return ToDisplayName(firstName); return ToDisplayName(firstName);
return null; return null;
} }
private static bool CanUseLoopFirstNameFallback(GreetingPresenceProfile presence)
{
if (string.IsNullOrWhiteSpace(presence.PrimaryPersonId)) return false;
if (presence.PeoplePresentIds.Count > 1) return false;
return true;
}
private static string ToDisplayName(string value) private static string ToDisplayName(string value)
{ {
var trimmed = value.Trim(); var trimmed = value.Trim();

View File

@@ -349,6 +349,31 @@ public sealed class JiboInteractionServiceTests
greeting.LastGreetingIntent == "proactive_greeting"); greeting.LastGreetingIntent == "proactive_greeting");
} }
[Fact]
public async Task BuildDecisionAsync_TriggerWithMultiplePeople_DoesNotBorrowLoopFirstName()
{
var cloudStateStore = new InMemoryCloudStateStore();
var service = CreateService(cloudStateStore: cloudStateStore);
var decision = await service.BuildDecisionAsync(new TurnContext
{
RawTranscript = string.Empty,
NormalizedTranscript = string.Empty,
Attributes = new Dictionary<string, object?>
{
["messageType"] = "TRIGGER",
["triggerSource"] = "PRESENCE",
["context"] =
"""{"runtime":{"perception":{"speaker":"person-1","peoplePresent":[{"id":"person-1"},{"id":"person-2"}]},"loop":{"users":[{"id":"person-1","firstName":"jake"},{"id":"person-2","firstName":"sam"}]}}}"""
}
});
Assert.Equal("proactive_greeting", decision.IntentName);
Assert.DoesNotContain("Jake", decision.ReplyText, StringComparison.Ordinal);
Assert.DoesNotContain("Sam", decision.ReplyText, StringComparison.Ordinal);
Assert.Contains("I am glad to see you", decision.ReplyText, StringComparison.OrdinalIgnoreCase);
}
[Fact] [Fact]
public async Task BuildDecisionAsync_TriggerInTheMorning_UsesGoodMorningProactiveTone() public async Task BuildDecisionAsync_TriggerInTheMorning_UsesGoodMorningProactiveTone()
{ {