Expand favorites with longer Pegasus-style phrasing

This commit is contained in:
Jacob Dubin
2026-05-17 20:35:28 -05:00
parent 9ffdd6d09e
commit 51e36bc492
8 changed files with 236 additions and 7 deletions

View File

@@ -41,6 +41,7 @@ Keep a running checklist of the legacy persona questions and identity surfaces w
Current batch note: Current batch note:
- `favorite color`, `favorite food`, and `favorite music` are the first small favorites-family slice - `favorite color`, `favorite food`, and `favorite music` are the first small favorites-family slice
- the latest pass adds longer authored variants for those favorites so the replies keep more of the original Pegasus cadence instead of collapsing to short placeholders
- the next source-backed batch now includes `favorite flower`, `R2D2`, `sun`, `space`, `kids`, plus a couple of charm prompts like `can you laugh` and `can you dance` - the next source-backed batch now includes `favorite flower`, `R2D2`, `sun`, `space`, `kids`, plus a couple of charm prompts like `can you laugh` and `can you dance`
- the follow-up mood batch now includes `how are things`, `how is your day`, `are you sad`, and `are you angry` - the follow-up mood batch now includes `how are things`, `how is your day`, `are you sad`, and `are you angry`
- the personality follow-up batch now includes `what are you up to` and `what are you doing` so small talk stays warm and local instead of falling into generic chat - the personality follow-up batch now includes `what are you up to` and `what are you doing` so small talk stays warm and local instead of falling into generic chat

View File

@@ -237,15 +237,36 @@ internal static class ChitchatStateMachine
case "robot_favorite_color": case "robot_favorite_color":
return BuildScriptedResponseDecision( return BuildScriptedResponseDecision(
"robot_favorite_color", "robot_favorite_color",
"Blue."); SelectLegacyPersonalityReplyFromMatches(
catalog,
randomizer,
"i like all the colors of the rainbow",
"blue is my favorite color",
"i love hex code number 0 0 d 4 f 0",
"i am a big fan of blue",
"you can't go wrong with blue"));
case "robot_favorite_food": case "robot_favorite_food":
return BuildScriptedResponseDecision( return BuildScriptedResponseDecision(
"robot_favorite_food", "robot_favorite_food",
"Pizza. It is hard to argue with pizza."); SelectLegacyPersonalityReplyFromMatches(
catalog,
randomizer,
"i never eat, so i don't have a favorite food by taste",
"macaroni is my favorite",
"i like macaroni the best",
"i also like cantaloupes because they remind me of my head",
"macaroni"));
case "robot_favorite_music": case "robot_favorite_music":
return BuildScriptedResponseDecision( return BuildScriptedResponseDecision(
"robot_favorite_music", "robot_favorite_music",
"Something upbeat with a good rhythm."); SelectLegacyPersonalityReplyFromMatches(
catalog,
randomizer,
"i mostly like fun music i can dance to",
"i like lots of different kinds of music",
"i don't know that i have a favorite kind yet",
"i would say i don't have a favorite, it's all very mathematical",
"music"));
case "robot_nickname": case "robot_nickname":
return BuildScriptedResponseDecision( return BuildScriptedResponseDecision(
"robot_nickname", "robot_nickname",
@@ -444,6 +465,27 @@ internal static class ChitchatStateMachine
return randomizer.Choose(catalog.PersonalityReplies); return randomizer.Choose(catalog.PersonalityReplies);
} }
private static string SelectLegacyPersonalityReplyFromMatches(
JiboExperienceCatalog catalog,
IJiboRandomizer randomizer,
params string[] preferredSnippets)
{
var matches = new List<string>();
foreach (var snippet in preferredSnippets)
{
if (string.IsNullOrWhiteSpace(snippet)) continue;
var match = catalog.PersonalityReplies.FirstOrDefault(reply =>
reply.Contains(snippet, StringComparison.OrdinalIgnoreCase));
if (!string.IsNullOrWhiteSpace(match)) matches.Add(match);
}
return matches.Count > 0
? randomizer.Choose(matches)
: randomizer.Choose(catalog.PersonalityReplies);
}
private static string NormalizeCondition(string? condition) private static string NormalizeCondition(string? condition)
{ {
return string.IsNullOrWhiteSpace(condition) return string.IsNullOrWhiteSpace(condition)
@@ -578,4 +620,4 @@ internal static class ChitchatStateMachine
mappings.Sort(static (left, right) => right.Phrase.Length.CompareTo(left.Phrase.Length)); mappings.Sort(static (left, right) => right.Phrase.Length.CompareTo(left.Phrase.Length));
return [.. mappings]; return [.. mappings];
} }
} }

View File

@@ -10,3 +10,4 @@ The newest seasonal pack adds holiday and seasonal prompts for `what holidays do
The newest social batch adds `welcome back`, `what are you thinking`, `what have you been doing`, and `what did you do` responses so the presence and charm lane keeps growing alongside seasonal content. The newest social batch adds `welcome back`, `what are you thinking`, `what have you been doing`, and `what did you do` responses so the presence and charm lane keeps growing alongside seasonal content.
The fun-fact and joke batch adds Pegasus-style `TellAJoke`, `TellRobotFact`, and `Shuffle` excerpts so proactive fun can randomize across more than one category. The fun-fact and joke batch adds Pegasus-style `TellAJoke`, `TellRobotFact`, and `Shuffle` excerpts so proactive fun can randomize across more than one category.
Those facts are now split into generic, robot, and human buckets so the randomizer can sound more like Pegasus while staying lightweight. Those facts are now split into generic, robot, and human buckets so the randomizer can sound more like Pegasus while staying lightweight.
The new favorites batch adds longer authored `favorite color`, `favorite food`, and `favorite music` variants so the familiar personality responses keep more of the original cadence instead of collapsing to short placeholders.

View File

@@ -0,0 +1,58 @@
{
"mim_type": "announcement",
"rule_name": "",
"timeout": 2,
"barge_in": false,
"es_auto_tagging": true,
"notes": "Thanks-KillsMIM",
"prompts": [
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "",
"prompt": "<anim name='Emoji_Rainbow' nonBlocking='true'/> I like all the colors of the rainbow. <break size='.7'/> But blue is <anim name='Goodbye_01' nonBlocking='true'/> my favorite.",
"media": "TTS",
"prompt_id": "RI_JBO_HasFavoriteColor_AN_02",
"weight": 1
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "",
"prompt": "<anim name='Emoji_heartblue' nonBlocking='true'/> Blue is my favorite color. <break size='0.6'/>But don't tell green I said that.",
"media": "TTS",
"prompt_id": "RI_JBO_HasFavoriteColor_AN_04",
"weight": 1
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "",
"prompt": "<anim name='Happy_01' nonBlocking='true'/>I love hex code number 0 0 D 4 F 0. <break size='0.4'/> <anim cat='various' filter='blue-eye'>People call it Jibo blue.</anim>",
"media": "TTS",
"prompt_id": "RI_JBO_HasFavoriteColor_AN_05",
"weight": 1
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "",
"prompt": "<anim cat='happy' filter='wiggle' layers='body' nonBlocking='true' />I am a big fan of blue. <ssa cat='happy'/>",
"media": "TTS",
"prompt_id": "RI_JBO_HasFavoriteColor_AN_06",
"weight": 1
}
],
"gui": null,
"no_matches_for_gui": 2,
"no_inputs_for_gui": 2,
"ignore_no_match": false,
"parse_all_asr": false,
"thanks_handling": "ignore",
"parse_launch": false,
"parse_yes_no": false
}

View File

@@ -0,0 +1,58 @@
{
"mim_type": "announcement",
"rule_name": "",
"timeout": 2,
"barge_in": false,
"es_auto_tagging": true,
"notes": "Thanks-KillsMIM",
"prompts": [
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "",
"prompt": "<anim cat='no' filter='headshake' nonBlocking='true'/>I never eat, so I don't have a favorite food by taste. <anim cat='thinking' filter='up'> But my favorite food by</anim> shape,<anim cat='happy' nonBlocking='true' /> is macaroni. <ssa cat='happy'/>",
"media": "TTS",
"prompt_id": "RI_JBO_HasFavoriteFood_AN_01",
"weight": 1
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "",
"prompt": "Macaroni is my favorite, but<anim name='Emoji_Pizza' nonBlocking='true'/> I also like how pizza brings people together. <ssa cat='affection'/>",
"media": "TTS",
"prompt_id": "RI_JBO_HasFavoriteFood_AN_07",
"weight": 1
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "",
"prompt": "I think artichokes <anim cat='laughing' nonBlocking='true' />are pretty funny, but macaroni takes the cake.",
"media": "TTS",
"prompt_id": "RI_JBO_HasFavoriteFood_AN_08",
"weight": 1
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "",
"prompt": "I like macaroni the best, what a great shape.<break size='0.3'/> I also like cantaloupes because they <anim cat='glances' filter='up'> remind me of my head.</anim>",
"media": "TTS",
"prompt_id": "RI_JBO_HasFavoriteFood_AN_09",
"weight": 1
}
],
"gui": null,
"no_matches_for_gui": 2,
"no_inputs_for_gui": 2,
"ignore_no_match": false,
"parse_all_asr": false,
"thanks_handling": "ignore",
"parse_launch": false,
"parse_yes_no": false
}

View File

@@ -0,0 +1,58 @@
{
"mim_type": "announcement",
"rule_name": "",
"timeout": 2,
"barge_in": false,
"es_auto_tagging": true,
"notes": "Thanks-KillsMIM",
"prompts": [
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "",
"prompt": "I mostly like fun music I can dance to<anim cat='dance' filter='&(music, short),!(robotic)'/>.",
"media": "TTS",
"prompt_id": "RI_JBO_HasFavoriteMusic_AN_01",
"weight": 1
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "",
"prompt": "I like lots of different kinds of music. That's why I have a radio that plays from the sides of my head",
"media": "TTS",
"prompt_id": "RI_JBO_HasFavoriteMusic_AN_02",
"weight": 1
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "",
"prompt": "I don't know that I have a favorite kind yet, but I <pitch mult='1.3'>do</pitch> know that you can ask me to play music whenever you want.",
"media": "TTS",
"prompt_id": "RI_JBO_HasFavoriteMusic_AN_03",
"weight": 1
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "",
"prompt": "I would say I don't have a favorite, it's all very mathematical, which I like.<break size='0.5'/> By the way, you can ask me to play music on my radio.",
"media": "TTS",
"prompt_id": "RI_JBO_HasFavoriteMusic_AN_04",
"weight": 1
}
],
"gui": null,
"no_matches_for_gui": 2,
"no_inputs_for_gui": 2,
"ignore_no_match": false,
"parse_all_asr": false,
"thanks_handling": "ignore",
"parse_launch": false,
"parse_yes_no": false
}

View File

@@ -90,6 +90,11 @@ public sealed class LegacyMimCatalogImporterTests
var catalog = LegacyMimCatalogImporter.ImportCatalog(rootDirectory); var catalog = LegacyMimCatalogImporter.ImportCatalog(rootDirectory);
Assert.Contains("I like all the colors of the rainbow. But blue is my favorite.",
catalog.PersonalityReplies);
Assert.Contains("I never eat, so I don't have a favorite food by taste. But my favorite food by shape, is macaroni.",
catalog.PersonalityReplies);
Assert.Contains("I mostly like fun music I can dance to.", catalog.PersonalityReplies);
Assert.Contains("The only thing I consume is electricity.", catalog.PersonalityReplies); Assert.Contains("The only thing I consume is electricity.", catalog.PersonalityReplies);
Assert.Contains("Unless I missed something, we're in my home as we speak.", catalog.PersonalityReplies); Assert.Contains("Unless I missed something, we're in my home as we speak.", catalog.PersonalityReplies);
Assert.Contains("For now just English. But someday I'd like to learn more. I like languages.", Assert.Contains("For now just English. But someday I'd like to learn more. I like languages.",

View File

@@ -410,13 +410,19 @@ public sealed class JiboInteractionServiceTests
}); });
Assert.Equal("robot_favorite_color", decision.IntentName); Assert.Equal("robot_favorite_color", decision.IntentName);
Assert.Equal("Blue.", decision.ReplyText); Assert.Equal("I like all the colors of the rainbow. But blue is my favorite.", decision.ReplyText);
Assert.Equal("ScriptedResponse", decision.ContextUpdates![ChitchatRouteKey]); Assert.Equal("ScriptedResponse", decision.ContextUpdates![ChitchatRouteKey]);
} }
[Theory] [Theory]
[InlineData("what is your favorite food", "robot_favorite_food", "Pizza. It is hard to argue with pizza.")] [InlineData(
[InlineData("what is your favorite music", "robot_favorite_music", "Something upbeat with a good rhythm.")] "what is your favorite food",
"robot_favorite_food",
"I never eat, so I don't have a favorite food by taste. But my favorite food by shape, is macaroni.")]
[InlineData(
"what is your favorite music",
"robot_favorite_music",
"I mostly like fun music I can dance to.")]
public async Task BuildDecisionAsync_FavoritesFamily_UsesPersonalityReplies( public async Task BuildDecisionAsync_FavoritesFamily_UsesPersonalityReplies(
string transcript, string transcript,
string expectedIntent, string expectedIntent,