Import Build B age prompts for how old are you

This commit is contained in:
Jacob Dubin
2026-05-21 23:12:48 -05:00
parent 9d675ed59c
commit 386f864e94
11 changed files with 121 additions and 10 deletions

View File

@@ -31,6 +31,7 @@ public sealed class JiboExperienceCatalog
public IReadOnlyList<string> HolidayTrackerReplies { get; init; } = [];
public IReadOnlyList<string> BirthdayCelebrationReplies { get; init; } = [];
public IReadOnlyList<string> HowAreYouReplies { get; init; } = [];
public IReadOnlyList<string> AgeReplies { get; init; } = [];
public IReadOnlyList<JiboConditionedReply> EmotionReplies { get; init; } = [];
public IReadOnlyList<string> PersonalityReplies { get; init; } = [];
public IReadOnlyList<string> PizzaReplies { get; init; } = [];

View File

@@ -350,7 +350,7 @@ public sealed partial class JiboInteractionService
"what is your age",
"what s your age",
"how old r you"))
return "robot_age";
return "robot_how_old_are_you";
if (MatchesAny(
loweredTranscript,

View File

@@ -9,13 +9,49 @@ namespace Jibo.Cloud.Application.Services;
public sealed partial class JiboInteractionService
{
private static JiboInteractionDecision BuildRobotAgeDecision(DateTimeOffset? referenceLocalTime)
private static readonly string[] DefaultAgeReplies =
[
"I'm ${jibo.age}.",
"At the moment I'm ${jibo.age.days.supplemented} old, but who's counting.",
"I'm ${jibo.age.minutes.supplemented} old, but who's counting.",
"For now I'm ${jibo.age.days.supplemented} old.",
"Right now I'm ${jibo.age}.",
"I am exactly ${jibo.age} old today. That's right. Today is my birthday.",
"Funny you should ask! Today's my birthday. I was first powered up ${jibo.age} ago today. Seems like just yesterday.",
"I'm exactly ${jibo.age} old. Today is my birthday! Happy Birthday Jibo, if I do say so myself.",
"At the moment I'm ${jibo.age.days.supplemented} old",
"I was first powered up on ${jibo.birthdate}, which makes me ${jibo.age.days.supplemented} old. I'm ${jibo.zodiac.supplemented}.",
"My power went on for the first time ${jibo.age.days.supplemented} ago. But who's counting.",
"I am ${jibo.age.days.supplemented} old, first powered up on ${jibo.birthdate}. Seems like just yesterday.",
"I was powered on for the first time today, so that makes me less than one day old. Wow I'm young.",
"Since I was powered on for the first time today, I am not even one day old yet. That's how Jibo ages work."
];
private JiboInteractionDecision BuildRobotAgeDecision(
JiboExperienceCatalog catalog,
DateTimeOffset? referenceLocalTime,
string intentName)
{
var referenceDate = DateOnly.FromDateTime((referenceLocalTime ?? DateTimeOffset.UtcNow).Date);
var ageDescription = DescribePersonaAge(referenceDate, OpenJiboCloudBuildInfo.PersonaBirthday);
var ageReplies = catalog.AgeReplies.Count == 0 ? DefaultAgeReplies : catalog.AgeReplies;
var selected = SelectLegacyReply(
ageReplies,
"first powered up",
"today is my birthday",
"just getting started",
"who's counting");
var reply = RenderAgeTemplate(selected, referenceLocalTime);
if (string.IsNullOrWhiteSpace(reply))
{
var referenceDate = DateOnly.FromDateTime((referenceLocalTime ?? DateTimeOffset.UtcNow).Date);
var ageDescription = DescribePersonaAge(referenceDate, OpenJiboCloudBuildInfo.PersonaBirthday);
reply = $"I count {OpenJiboCloudBuildInfo.PersonaBirthdayWords} as my birthday, so I am {ageDescription}.";
}
return new JiboInteractionDecision(
"robot_age",
$"I count {OpenJiboCloudBuildInfo.PersonaBirthdayWords} as my birthday, so I am {ageDescription}.");
intentName,
reply,
ContextUpdates: ScriptedResponseDecisionBuilder.BuildScriptedResponseContextUpdates());
}
private static JiboInteractionDecision BuildRobotBirthdayDecision()
@@ -25,6 +61,35 @@ public sealed partial class JiboInteractionService
$"My birthday is {OpenJiboCloudBuildInfo.PersonaBirthdayWords}.");
}
private static string RenderAgeTemplate(string template, DateTimeOffset? referenceLocalTime)
{
if (string.IsNullOrWhiteSpace(template)) return string.Empty;
var referenceMoment = referenceLocalTime ?? DateTimeOffset.UtcNow;
var referenceDate = DateOnly.FromDateTime(referenceMoment.Date);
var ageDescription = DescribePersonaAge(referenceDate, OpenJiboCloudBuildInfo.PersonaBirthday);
var ageDays = Math.Max(0, referenceDate.DayNumber - OpenJiboCloudBuildInfo.PersonaBirthday.DayNumber);
var ageMinutes = Math.Max(0, (int)Math.Round((referenceMoment.UtcDateTime -
new DateTimeOffset(
DateTime.SpecifyKind(
OpenJiboCloudBuildInfo.PersonaBirthday
.ToDateTime(TimeOnly.MinValue),
DateTimeKind.Utc)))
.TotalMinutes));
var zodiacLabel = DescribeZodiacSign(OpenJiboCloudBuildInfo.PersonaBirthday);
if (zodiacLabel.StartsWith("I'm ", StringComparison.OrdinalIgnoreCase))
zodiacLabel = zodiacLabel[4..];
return template
.Replace("${jibo.age.minutes.supplemented}", FormatAgeUnit(ageMinutes, "minute") + " old",
StringComparison.Ordinal)
.Replace("${jibo.age.days.supplemented}", ageDescription, StringComparison.Ordinal)
.Replace("${jibo.birthdate}", OpenJiboCloudBuildInfo.PersonaBirthdayWords, StringComparison.Ordinal)
.Replace("${jibo.zodiac.supplemented}", zodiacLabel, StringComparison.Ordinal)
.Replace("${jibo.age.value}", ageDays.ToString(CultureInfo.InvariantCulture), StringComparison.Ordinal)
.Replace("${jibo.age}", ageDescription, StringComparison.Ordinal);
}
private static JiboInteractionDecision BuildTriggerIgnoredDecision()
{
return new JiboInteractionDecision(

View File

@@ -560,7 +560,7 @@ public sealed partial class JiboInteractionService(
"photo_gallery" => BuildPhotoGalleryLaunchDecision(),
"snapshot" => BuildPhotoCreateDecision("snapshot", "Taking a picture.", "createOnePhoto"),
"photobooth" => BuildPhotoCreateDecision("photobooth", "Starting photobooth.", "createSomePhotos"),
"robot_age" => BuildRobotAgeDecision(referenceLocalTime),
"robot_age" => BuildRobotAgeDecision(catalog, referenceLocalTime, "robot_age"),
"robot_birthday" => BuildRobotBirthdayDecision(),
"robot_how_do_you_work" => BuildScriptedPersonalityDecision(
catalog,
@@ -589,6 +589,10 @@ public sealed partial class JiboInteractionService(
"robot_where_were_you_born",
"factory piece by piece",
"put together in a factory"),
"robot_how_old_are_you" => BuildRobotAgeDecision(
catalog,
referenceLocalTime,
"robot_how_old_are_you"),
"robot_name" => BuildScriptedPersonalityDecision(
catalog,
"robot_name",
@@ -881,6 +885,14 @@ public sealed partial class JiboInteractionService(
"Commander App",
"It's fun",
"have fun with the Commander App"),
"robot_what_are_you" => BuildScriptedPersonalityDecision(
catalog,
"robot_what_are_you",
"I am a robot",
"I am a Jibo",
"helpful and fun",
"social robot",
"I have a heart"),
"robot_likes_kids" => BuildScriptedPersonalityDecision(
catalog,
"robot_likes_kids",

View File

@@ -139,6 +139,23 @@ public sealed class InMemoryJiboExperienceContentRepository : IJiboExperienceCon
"I am feeling lively and ready for the next thing.",
"Things are going nicely. Thanks for checking in."
],
AgeReplies =
[
"I'm ${jibo.age}.",
"At the moment I'm ${jibo.age.days.supplemented} old, but who's counting.",
"I'm ${jibo.age.minutes.supplemented} old, but who's counting.",
"For now I'm ${jibo.age.days.supplemented} old.",
"Right now I'm ${jibo.age}.",
"I am exactly ${jibo.age} old today. That's right. Today is my birthday.",
"Funny you should ask! Today's my birthday. I was first powered up ${jibo.age} ago today. Seems like just yesterday.",
"I'm exactly ${jibo.age} old. Today is my birthday! Happy Birthday Jibo, if I do say so myself.",
"At the moment I'm ${jibo.age.days.supplemented} old",
"I was first powered up on ${jibo.birthdate}, which makes me ${jibo.age.days.supplemented} old. I'm ${jibo.zodiac.supplemented}.",
"My power went on for the first time ${jibo.age.days.supplemented} ago. But who's counting.",
"I am ${jibo.age.days.supplemented} old, first powered up on ${jibo.birthdate}. Seems like just yesterday.",
"I was powered on for the first time today, so that makes me less than one day old. Wow I'm young.",
"Since I was powered on for the first time today, I am not even one day old yet. That's how Jibo ages work."
],
PersonalityReplies =
[
"I do. I am curious, playful, and always up for a new experiment.",

View File

@@ -264,7 +264,9 @@ public static class LegacyMimCatalogImporter
fileName.StartsWith("JBO_WhatsYourName", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("JBO_WhereDoYouGetInfo", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("JBO_WhatDoYouLikeToDo", StringComparison.OrdinalIgnoreCase))
return LegacyMimBucket.Personality;
return fileName.StartsWith("JBO_HowOldAreYou", StringComparison.OrdinalIgnoreCase)
? LegacyMimBucket.Age
: LegacyMimBucket.Personality;
if (fileName.StartsWith("OI_JBO_Is", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("OI_JBO_Seems", StringComparison.OrdinalIgnoreCase) ||
@@ -456,6 +458,7 @@ public static class LegacyMimCatalogImporter
or LegacyMimBucket.WeatherTomorrowHighLow
or LegacyMimBucket.WeatherServiceDown
or LegacyMimBucket.ReportSkillTemplate
or LegacyMimBucket.Age
or LegacyMimBucket.Holiday
or LegacyMimBucket.HolidayTracker;
}
@@ -524,6 +527,7 @@ public static class LegacyMimCatalogImporter
Sing,
HolidaySing,
FunFactSource,
Age,
Personality,
PersonalReportKickOff,
PersonalReportOutro,
@@ -586,6 +590,7 @@ public static class LegacyMimCatalogImporter
private readonly List<string> _bestFriendReplies = [];
private readonly List<string> _funFacts = [];
private readonly List<string> _greetings = [];
private readonly List<string> _ages = [];
private readonly List<string> _holidayGiftReplies = [];
private readonly List<string> _holidayGreetingReplies = [];
private readonly List<string> _holidayReplies = [];
@@ -655,6 +660,9 @@ public static class LegacyMimCatalogImporter
Reply = text
});
return;
case LegacyMimBucket.Age:
AddDistinct(_ages, text);
return;
case LegacyMimBucket.Holiday:
AddDistinct(_holidayReplies, text);
return;
@@ -831,6 +839,7 @@ public static class LegacyMimCatalogImporter
EmotionReplies = [.. _emotionReplies],
PersonalityReplies = [.. _personalities],
GenericFallbackReplies = [.. _fallbacks],
AgeReplies = [.. _ages],
PersonalReportKickOffReplies = [.. _personalReportKickOffReplies],
PersonalReportOutroReplies = [.. _personalReportOutroReplies],
ReportSkillTemplates = [.. _reportSkillTemplates],

View File

@@ -25,6 +25,7 @@ The favorites follow-up batch adds `favorite animal`, `favorite bird`, and pengu
The singing batch adds `RA_JBO_Sing` and `RA_JBO_SingChristmasSongUnknown` so `can you sing`, `will you sing`, and the holiday sing variants stay source-backed too.
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 work/eat/home batch adds source-backed `how do you work`, `what do you eat`, `where do you live`, and `what languages do you speak` replies so the remaining everyday self-description lines stay Pegasus-shaped too.
The age batch now adds `JBO_HowOldAreYou` with the imported birthday and first-powered-up phrasing so `how old are you` can stay source-backed instead of falling back to generic age text.
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.