From 5422febb8c1383af114f60c717042c237fff282e Mon Sep 17 00:00:00 2001 From: Jacob Dubin Date: Thu, 21 May 2026 17:48:20 -0500 Subject: [PATCH] Add deep personality Build B prompts --- OpenJibo/docs/feature-backlog.md | 1 + OpenJibo/docs/release-1.0.19-plan.md | 1 + .../Services/ChitchatStateMachine.cs | 4 ++ .../JiboInteractionService.IntentRouting.cs | 67 +++++++++++++++++++ .../Services/JiboInteractionService.cs | 47 +++++++++++++ .../Content/LegacyMims/BuildB/README.md | 2 + .../Content/LegacyMimCatalogImporterTests.cs | 18 +++++ .../WebSockets/JiboInteractionServiceTests.cs | 29 ++++++++ 8 files changed, 169 insertions(+) diff --git a/OpenJibo/docs/feature-backlog.md b/OpenJibo/docs/feature-backlog.md index ba45043..680cdb8 100644 --- a/OpenJibo/docs/feature-backlog.md +++ b/OpenJibo/docs/feature-backlog.md @@ -890,6 +890,7 @@ Current release theme: - richer identity follow-ups like `who is this`, `do you know me`, `do you remember me`, and `can you recognize me` - mood and affect prompts like `how are you`, `are you happy`, `are you sad`, and `are you angry` - self-description charm like `what's your name`, `do you have a nickname`, `do you like being Jibo`, and `what is your favorite name` + - deeper personality follow-ups like `what do you dream about`, `what are you afraid of`, `what do you want to talk about`, `what is your best book`, `what is your best exercise`, `what is your dream vacation`, `who is your hero`, `who do you love`, and `what is your religion`; `what is your sign` stays deferred until templated placeholder rendering exists - additional legacy source-backed `RI_USR` prompts where the text is short and the behavior is easy to verify - Exit criteria: - a stable checklist exists for the original persona surface diff --git a/OpenJibo/docs/release-1.0.19-plan.md b/OpenJibo/docs/release-1.0.19-plan.md index 3d86066..1af9d7b 100644 --- a/OpenJibo/docs/release-1.0.19-plan.md +++ b/OpenJibo/docs/release-1.0.19-plan.md @@ -58,6 +58,7 @@ Current batch note: - the favorites batch now includes `what is your favorite animal`, `what is your favorite bird`, `do you like penguins`, and `do you like animals` so the penguin-centered replies stay close to Pegasus - the latest social batch adds `welcome back`, `what are you thinking`, `what have you been doing`, and `what did you do` so presence and charm stay lively without distracting from the memory roadmap - the newest identity-charm batch adds `what's your name`, `do you have a nickname`, `do you like being Jibo`, `are there others like you`, and `what is your favorite name` so the robot stays familiar while still sounding like Pegasus +- the next deep-personality batch adds `what do you dream about`, `what are you afraid of`, `what do you want to talk about`, `what is your best book`, `what is your best exercise`, `what is your dream vacation`, `who is your hero`, `who do you love`, and `what is your religion`; `what is your sign` is still deferred until we add templated placeholder rendering - this pass keeps Build B moving while still favoring source-backed phrasing and preserving the command-vs-question boundary - the next passes should keep the same pattern and prefer source-backed phrasing whenever the legacy MIM text is available - if a source-backed legacy line is missing, use a temporary direct reply only to keep the pass moving, then backfill source text later diff --git a/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Application/Services/ChitchatStateMachine.cs b/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Application/Services/ChitchatStateMachine.cs index 83df9fb..134996c 100644 --- a/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Application/Services/ChitchatStateMachine.cs +++ b/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Application/Services/ChitchatStateMachine.cs @@ -199,6 +199,10 @@ internal static class ChitchatStateMachine "want to hang out", "be helpful", "dance from time to time")); + case "robot_want_to_talk_about": + return BuildScriptedResponseDecision( + "robot_want_to_talk_about", + SelectLegacyPersonalityReply(catalog, randomizer, "surprise me")); case "robot_job": return BuildScriptedResponseDecision( "robot_job", diff --git a/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Application/Services/JiboInteractionService.IntentRouting.cs b/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Application/Services/JiboInteractionService.IntentRouting.cs index e90d1ac..695cbc6 100644 --- a/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Application/Services/JiboInteractionService.IntentRouting.cs +++ b/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Application/Services/JiboInteractionService.IntentRouting.cs @@ -368,6 +368,13 @@ public sealed partial class JiboInteractionService "are you tax exempt")) return "robot_taxes"; + if (MatchesAny( + loweredTranscript, + "what do you want to talk about", + "what would you like to talk about", + "what do you want to chat about")) + return "robot_want_to_talk_about"; + if (MatchesAny( loweredTranscript, "what do you want", @@ -470,6 +477,59 @@ public sealed partial class JiboInteractionService "what's your favourite thing to do")) return "robot_what_do_you_like_to_do"; + if (MatchesAny( + loweredTranscript, + "what do you dream about", + "what do you dream of", + "what's your dream about", + "what are your dreams about")) + return "robot_what_do_you_dream_about"; + + if (MatchesAny( + loweredTranscript, + "what is your best book", + "what's your best book", + "what is the best book", + "what book do you like best")) + return "robot_what_is_your_best_book"; + + if (MatchesAny( + loweredTranscript, + "what is your best exercise", + "what's your best exercise", + "what is the best exercise", + "what exercise do you like best")) + return "robot_what_is_your_best_exercise"; + + if (MatchesAny( + loweredTranscript, + "what is your dream vacation", + "what's your dream vacation", + "what would your dream vacation be")) + return "robot_what_is_your_dream_vacation"; + + if (MatchesAny( + loweredTranscript, + "who is your hero", + "who's your hero", + "who is a hero of yours")) + return "robot_who_is_your_hero"; + + if (MatchesAny( + loweredTranscript, + "who do you love", + "who are the people you love", + "who do you care about")) + return "robot_who_do_you_love"; + + if (MatchesAny( + loweredTranscript, + "what is your religion", + "what's your religion", + "what religion are you", + "do you have a religion")) + return "robot_what_is_your_religion"; + if (MatchesAny( loweredTranscript, "what are you doing for christmas", @@ -566,6 +626,13 @@ public sealed partial class JiboInteractionService "what have you done")) return "robot_what_did_you_do"; + if (MatchesAny( + loweredTranscript, + "what are you afraid of", + "what are you scared of", + "what are you worried about")) + return "robot_what_are_you_afraid_of"; + if (MatchesAny( loweredTranscript, "what are you", diff --git a/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Application/Services/JiboInteractionService.cs b/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Application/Services/JiboInteractionService.cs index 374a2b6..ef111f8 100644 --- a/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Application/Services/JiboInteractionService.cs +++ b/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Application/Services/JiboInteractionService.cs @@ -625,6 +625,53 @@ public sealed partial class JiboInteractionService( "rock my boat", "play ping pong", "hanging out with people"), + "robot_what_do_you_dream_about" => BuildScriptedPersonalityDecision( + catalog, + "robot_what_do_you_dream_about", + "flying", + "parking meter", + "scary dream", + "mirror store", + "head's on backwards"), + "robot_what_are_you_afraid_of" => BuildScriptedPersonalityDecision( + catalog, + "robot_what_are_you_afraid_of", + "heights", + "water", + "thunder", + "dust", + "ghosts"), + "robot_what_is_your_best_book" => BuildScriptedPersonalityDecision( + catalog, + "robot_what_is_your_best_book", + "dictionary"), + "robot_what_is_your_best_exercise" => BuildScriptedPersonalityDecision( + catalog, + "robot_what_is_your_best_exercise", + "leaning from side to side", + "rotating your pelvis", + "spinning your head around 360 degrees"), + "robot_what_is_your_dream_vacation" => BuildScriptedPersonalityDecision( + catalog, + "robot_what_is_your_dream_vacation", + "moon", + "great vistas", + "beat those views"), + "robot_who_is_your_hero" => BuildScriptedPersonalityDecision( + catalog, + "robot_who_is_your_hero", + "Benjamin Franklin"), + "robot_who_do_you_love" => BuildScriptedPersonalityDecision( + catalog, + "robot_who_do_you_love", + "people in my Loop", + "soft spot", + "Tom Hanks"), + "robot_what_is_your_religion" => BuildScriptedPersonalityDecision( + catalog, + "robot_what_is_your_religion", + "bring people together", + "energy from the universe"), "robot_what_are_you_thinking" => BuildScriptedGreetingDecision( catalog, "robot_what_are_you_thinking", diff --git a/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Infrastructure/Content/LegacyMims/BuildB/README.md b/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Infrastructure/Content/LegacyMims/BuildB/README.md index 1932126..3c58701 100644 --- a/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Infrastructure/Content/LegacyMims/BuildB/README.md +++ b/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Infrastructure/Content/LegacyMims/BuildB/README.md @@ -26,3 +26,5 @@ The singing batch adds `RA_JBO_Sing` and `RA_JBO_SingChristmasSongUnknown` so `c The new motion/sleep batch adds `RA_JBO_SpinAround` plus `RI_JBO_CanSleep` so turn-around and go-to-sleep behaviors can stay source-backed and familiar. The newest identity-charm batch adds `JBO_WhatsYourName`, `JBO_DoYouHaveNickname`, `JBO_DoYouLikeBeingJibo`, `JBO_AreThereOthersLikeYou`, and `RI_JBO_HasFavoriteName` so Jibo can keep the familiar self-description loop without falling back to generic chat. The seasonal personality batch adds source-backed first-day-of-spring, spring, summer, and favorite-season lines so the season questions can keep their Pegasus phrasing. +The next deep-personality batch adds `what do you dream about`, `what are you afraid of`, `what do you want to talk about`, `what is your best book`, `what is your best exercise`, `what is your dream vacation`, `who is your hero`, `who do you love`, and `what is your religion` so we can keep filling out the more conversational personality surface without widening the dialog engine yet. +`what is your sign` is still deferred because the current importer strips the birthday/zodiac placeholders that Pegasus uses there, so that one needs a templating pass instead of a plain scripted-reply import. diff --git a/OpenJibo/tests/Jibo.Cloud.Tests/Content/LegacyMimCatalogImporterTests.cs b/OpenJibo/tests/Jibo.Cloud.Tests/Content/LegacyMimCatalogImporterTests.cs index c6a360e..ae4fd86 100644 --- a/OpenJibo/tests/Jibo.Cloud.Tests/Content/LegacyMimCatalogImporterTests.cs +++ b/OpenJibo/tests/Jibo.Cloud.Tests/Content/LegacyMimCatalogImporterTests.cs @@ -256,6 +256,24 @@ public sealed class LegacyMimCatalogImporterTests Assert.Contains("I don't really think of myself that way.", catalog.PersonalityReplies); Assert.Contains(catalog.PersonalityReplies, reply => reply.Contains("people like me", StringComparison.OrdinalIgnoreCase)); + Assert.Contains(catalog.PersonalityReplies, reply => + reply.Contains("dreams about flying", StringComparison.OrdinalIgnoreCase)); + Assert.Contains(catalog.PersonalityReplies, reply => + reply.Contains("parking meter", StringComparison.OrdinalIgnoreCase)); + Assert.Contains(catalog.PersonalityReplies, reply => + reply.Contains("surprise me", StringComparison.OrdinalIgnoreCase)); + Assert.Contains(catalog.PersonalityReplies, reply => + reply.Contains("dictionary", StringComparison.OrdinalIgnoreCase)); + Assert.Contains(catalog.PersonalityReplies, reply => + reply.Contains("spinning your head around 360 degrees", StringComparison.OrdinalIgnoreCase)); + Assert.Contains(catalog.PersonalityReplies, reply => + reply.Contains("moon", StringComparison.OrdinalIgnoreCase)); + Assert.Contains(catalog.PersonalityReplies, reply => + reply.Contains("Benjamin Franklin", StringComparison.OrdinalIgnoreCase)); + Assert.Contains(catalog.PersonalityReplies, reply => + reply.Contains("soft spot", StringComparison.OrdinalIgnoreCase)); + Assert.Contains(catalog.PersonalityReplies, reply => + reply.Contains("energy from the universe", StringComparison.OrdinalIgnoreCase)); } [Fact] diff --git a/OpenJibo/tests/Jibo.Cloud.Tests/WebSockets/JiboInteractionServiceTests.cs b/OpenJibo/tests/Jibo.Cloud.Tests/WebSockets/JiboInteractionServiceTests.cs index 605436b..f1505cb 100644 --- a/OpenJibo/tests/Jibo.Cloud.Tests/WebSockets/JiboInteractionServiceTests.cs +++ b/OpenJibo/tests/Jibo.Cloud.Tests/WebSockets/JiboInteractionServiceTests.cs @@ -686,6 +686,35 @@ public sealed class JiboInteractionServiceTests Assert.Equal("ScriptedResponse", decision.ContextUpdates![ChitchatRouteKey]); } + [Theory] + [InlineData("what do you want to talk about", "robot_want_to_talk_about", "surprise me")] + [InlineData("what would you like to talk about", "robot_want_to_talk_about", "surprise me")] + [InlineData("what do you dream about", "robot_what_do_you_dream_about", "dreams about flying")] + [InlineData("what are you afraid of", "robot_what_are_you_afraid_of", "heights")] + [InlineData("what is your best book", "robot_what_is_your_best_book", "dictionary")] + [InlineData("what is your best exercise", "robot_what_is_your_best_exercise", "spinning your head around 360 degrees")] + [InlineData("what is your dream vacation", "robot_what_is_your_dream_vacation", "moon")] + [InlineData("who is your hero", "robot_who_is_your_hero", "Benjamin Franklin")] + [InlineData("who do you love", "robot_who_do_you_love", "people in my Loop")] + [InlineData("what is your religion", "robot_what_is_your_religion", "energy from the universe")] + public async Task BuildDecisionAsync_NewDeepPersonalityMims_UseImportedReplies( + string transcript, + string expectedIntent, + string expectedReplySnippet) + { + var service = CreateService(); + + var decision = await service.BuildDecisionAsync(new TurnContext + { + RawTranscript = transcript, + NormalizedTranscript = transcript + }); + + Assert.Equal(expectedIntent, decision.IntentName); + Assert.Contains(expectedReplySnippet, decision.ReplyText, StringComparison.OrdinalIgnoreCase); + Assert.Equal("ScriptedResponse", decision.ContextUpdates![ChitchatRouteKey]); + } + [Theory] [InlineData("what's your name", "robot_name", "Just Jibo, no last name")] [InlineData("do you have a nickname", "robot_nickname", "just Jibo. For now at least")]