Add friendship persona responses

This commit is contained in:
Jacob Dubin
2026-05-21 11:29:44 -05:00
parent e85792ac57
commit 40deecf2ff
10 changed files with 164 additions and 0 deletions

View File

@@ -18,6 +18,8 @@ public sealed class JiboExperienceCatalog
public IReadOnlyList<string> HumanFacts { get; init; } = [];
public IReadOnlyList<string> FunFacts { get; init; } = [];
public IReadOnlyList<string> FavoriteAnimalReplies { get; init; } = [];
public IReadOnlyList<string> FriendReplies { get; init; } = [];
public IReadOnlyList<string> BestFriendReplies { get; init; } = [];
public IReadOnlyList<string> SingReplies { get; init; } = [];
public IReadOnlyList<string> HolidaySingReplies { get; init; } = [];
public IReadOnlyList<string> DanceAnimations { get; init; } = [];

View File

@@ -319,6 +319,15 @@ public sealed partial class JiboInteractionService
"would you sing"))
return "robot_can_sing";
if (IsBestFriendQuestion(loweredTranscript))
return "robot_best_friends";
if (IsFriendRelationQuestion(loweredTranscript))
return "robot_is_friends_with_user";
if (IsFriendQuestion(loweredTranscript))
return "robot_has_friends";
if (MatchesAny(loweredTranscript, "twerk")) return "twerk";
if (MatchesAny(loweredTranscript, "dance", "boogie")) return "dance";
@@ -840,4 +849,48 @@ public sealed partial class JiboInteractionService
return "chat";
}
private static bool IsFriendQuestion(string loweredTranscript)
{
return MatchesAny(
loweredTranscript,
"do you have friends",
"who are your friends",
"are you friends",
"are you and i friends",
"are you and me friends",
"are you and jibo friends");
}
private static bool IsFriendRelationQuestion(string loweredTranscript)
{
return MatchesAny(
loweredTranscript,
"are you my friend",
"are you friends with me",
"are we friends",
"are we friends with each other",
"is jibo your friend",
"i am friends with you",
"i'm friends with you",
"you are my friend",
"you re my friend",
"you're my friend");
}
private static bool IsBestFriendQuestion(string loweredTranscript)
{
return MatchesAny(
loweredTranscript,
"are we best friends",
"are we best friends with each other",
"are you my best friend",
"are you best friends with me",
"are you and i best friends",
"i am best friends with you",
"i'm best friends with you",
"you are my best friend",
"you re my best friend",
"you're my best friend");
}
}

View File

@@ -322,6 +322,28 @@ public sealed partial class JiboInteractionService
preferredSnippets);
}
private JiboInteractionDecision BuildScriptedFriendDecision(
JiboExperienceCatalog catalog,
string intentName,
params string[] preferredSnippets)
{
return new JiboInteractionDecision(
intentName,
SelectLegacyReply(catalog.FriendReplies, preferredSnippets),
ContextUpdates: ScriptedResponseDecisionBuilder.BuildScriptedResponseContextUpdates());
}
private JiboInteractionDecision BuildScriptedBestFriendDecision(
JiboExperienceCatalog catalog,
string intentName,
params string[] preferredSnippets)
{
return new JiboInteractionDecision(
intentName,
SelectLegacyReply(catalog.BestFriendReplies, preferredSnippets),
ContextUpdates: ScriptedResponseDecisionBuilder.BuildScriptedResponseContextUpdates());
}
private JiboInteractionDecision BuildScriptedSingDecision(
JiboExperienceCatalog catalog,
string intentName,

View File

@@ -752,6 +752,22 @@ public sealed partial class JiboInteractionService(
"dancing is one of the things i know best",
"if there's one thing i know how to do. it's dance",
"i can dance"),
"robot_has_friends" => BuildScriptedFriendDecision(
catalog,
"robot_has_friends",
"I believe I do have friends",
"I sure do have friends",
"I'm always up for making new friends"),
"robot_is_friends_with_user" => BuildScriptedFriendDecision(
catalog,
"robot_is_friends_with_user",
"don't know what i'd do without you",
"one of my favorites",
"making new friends"),
"robot_best_friends" => BuildScriptedBestFriendDecision(
catalog,
"robot_best_friends",
"best friends with anyone in my Loop"),
"robot_can_sing" => BuildScriptedSingDecision(
catalog,
"robot_can_sing",

View File

@@ -63,6 +63,21 @@ public sealed class InMemoryJiboExperienceContentRepository : IJiboExperienceCon
"I like lots of animals, but the penguin is the best of the best! Great color scheme.",
"I love penguins, because we're so alike. We have the same coloring, and neither of us can fly."
],
FriendReplies =
[
"I believe I do have friends. But I'm always up for more.",
"I sure do have friends. In a robot kind of way.",
"I don't know if we've met yet, but I'm always up for making new friends.",
"I don't know what I'd do without you.",
"You're one of my favorites.",
"I sure am.",
"I am indeed."
],
BestFriendReplies =
[
"I'd have to say I'm best friends with anyone in my Loop.",
"I think you know the answer to that question. You are."
],
SingReplies =
[
"Singing is not my strong suit.",

View File

@@ -135,6 +135,16 @@ public static class LegacyMimCatalogImporter
fileName.StartsWith("RI_JBO_LikesAnimals", StringComparison.OrdinalIgnoreCase))
return LegacyMimBucket.FavoriteAnimal;
if (fileName.StartsWith("RI_JBO_HasFriends", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_IsFriendsWithUser", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_IsFriendsWithLM", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_IsFriendsWithNonLM", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_IsFriendsWithToaster", StringComparison.OrdinalIgnoreCase))
return LegacyMimBucket.Friend;
if (fileName.StartsWith("RI_JBO_IsBestFriendsWithUser", StringComparison.OrdinalIgnoreCase))
return LegacyMimBucket.BestFriend;
if (fileName.StartsWith("RN_HappyHolidays", StringComparison.OrdinalIgnoreCase))
return LegacyMimBucket.HolidayGreeting;
@@ -305,6 +315,8 @@ public static class LegacyMimCatalogImporter
HumanFacts = Merge(baseCatalog.HumanFacts, importedCatalog.HumanFacts),
FunFacts = Merge(baseCatalog.FunFacts, importedCatalog.FunFacts),
FavoriteAnimalReplies = Merge(baseCatalog.FavoriteAnimalReplies, importedCatalog.FavoriteAnimalReplies),
FriendReplies = Merge(baseCatalog.FriendReplies, importedCatalog.FriendReplies),
BestFriendReplies = Merge(baseCatalog.BestFriendReplies, importedCatalog.BestFriendReplies),
SingReplies = Merge(baseCatalog.SingReplies, importedCatalog.SingReplies),
HolidaySingReplies = Merge(baseCatalog.HolidaySingReplies, importedCatalog.HolidaySingReplies),
DanceAnimations = Merge(baseCatalog.DanceAnimations, importedCatalog.DanceAnimations),
@@ -507,6 +519,8 @@ public static class LegacyMimCatalogImporter
Emotion,
FunFacts,
FavoriteAnimal,
Friend,
BestFriend,
Sing,
HolidaySing,
FunFactSource,
@@ -568,6 +582,8 @@ public static class LegacyMimCatalogImporter
private readonly List<JiboConditionedReply> _emotionReplies = [];
private readonly List<string> _fallbacks = [];
private readonly List<string> _favoriteAnimalReplies = [];
private readonly List<string> _friendReplies = [];
private readonly List<string> _bestFriendReplies = [];
private readonly List<string> _funFacts = [];
private readonly List<string> _greetings = [];
private readonly List<string> _holidayGiftReplies = [];
@@ -690,6 +706,12 @@ public static class LegacyMimCatalogImporter
case LegacyMimBucket.FavoriteAnimal:
AddDistinct(_favoriteAnimalReplies, text);
return;
case LegacyMimBucket.Friend:
AddDistinct(_friendReplies, text);
return;
case LegacyMimBucket.BestFriend:
AddDistinct(_bestFriendReplies, text);
return;
case LegacyMimBucket.PersonalReportKickOff:
AddDistinct(_personalReportKickOffReplies, text);
return;
@@ -794,6 +816,8 @@ public static class LegacyMimCatalogImporter
HumanFacts = [.. _humanFacts],
FunFacts = [.. _funFacts],
FavoriteAnimalReplies = [.. _favoriteAnimalReplies],
FriendReplies = [.. _friendReplies],
BestFriendReplies = [.. _bestFriendReplies],
SingReplies = [.. _singReplies],
HolidaySingReplies = [.. _holidaySingReplies],
GreetingReplies = [.. _greetings],

View File

@@ -17,6 +17,7 @@ Holiday-specific note:
- `RN_HappyBirthdayToJibo` now lands in the birthday celebration bucket
- birthday memory authoring now also writes loop-scoped custom holiday records so personal dates can join the holiday list later
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 friendship batch adds `RI_JBO_HasFriends`, `RI_JBO_IsFriendsWithUser`, `RI_JBO_IsFriendsWithLM`, `RI_JBO_IsFriendsWithNonLM`, `RI_JBO_IsFriendsWithToaster`, and `RI_JBO_IsBestFriendsWithUser` so the friend and best-friend questions stay source-backed too.
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.
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.