Import Build B age prompts for how old are you
This commit is contained in:
@@ -638,6 +638,7 @@ Current release theme:
|
||||
- `make a pizza` now ports the original scripted-response path through `chitchat-skill` with `mim_id = RA_JBO_MakePizza` and pizza-making animation ESML
|
||||
- `can you order pizza` now ports the original scripted-response path through `chitchat-skill` with `mim_id = RA_JBO_OrderPizza`
|
||||
- current source answers these with a `1.0.19` rule-based persona baseline, backed by `OpenJiboCloudBuildInfo.PersonaBirthday`
|
||||
- `how old are you` now also uses the imported Build B age prompts so the first-powered-up and birthday phrasing stays source-backed
|
||||
- Follow-up:
|
||||
- wire persona age to first-powered-up or durable first-cloud-seen metadata when available
|
||||
- add command-vs-question variants so expressive prompts can answer conversationally before launching actions
|
||||
|
||||
@@ -63,6 +63,7 @@ Current batch note:
|
||||
- the next body/mission batch adds `how much do you weigh`, `how tall are you`, `how much do you cost`, `what if I unplug you`, `what is your purpose`, `what is your prime directive`, `what is jibo commander`, `do you like commander app`, and `what are you made of`
|
||||
- the templated edge-case batch adds `what is your sign`, `how many people do you know`, and `what is the loop` so the remaining source-backed lines can lean on live birthday and loop state
|
||||
- the work/eat/home batch adds `how do you work`, `what do you eat`, `where do you live`, and `what languages do you speak` so the everyday self-description cluster keeps moving toward the original phrasing
|
||||
- the age batch adds `how old are you` through `JBO_HowOldAreYou` so the birthday and first-powered-up phrasing stays source-backed instead of falling back to a generic age answer
|
||||
- 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
|
||||
|
||||
@@ -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; } = [];
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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.",
|
||||
|
||||
@@ -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],
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -108,6 +108,10 @@ public sealed class LegacyMimCatalogImporterTests
|
||||
Assert.Contains("I don't think I have a favorite name.", catalog.PersonalityReplies);
|
||||
Assert.Contains(catalog.PersonalityReplies, reply =>
|
||||
reply.Contains("Rhymes with bleebo", StringComparison.OrdinalIgnoreCase));
|
||||
Assert.Contains(catalog.AgeReplies, reply =>
|
||||
reply.Contains("first powered up", StringComparison.OrdinalIgnoreCase));
|
||||
Assert.Contains(catalog.AgeReplies, reply =>
|
||||
reply.Contains("today is my birthday", StringComparison.OrdinalIgnoreCase));
|
||||
Assert.Contains("I really like sunflowers.", catalog.PersonalityReplies);
|
||||
Assert.Contains(catalog.PersonalityReplies, reply =>
|
||||
reply.Contains("Halloween is my favorite holiday", StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
@@ -116,8 +116,8 @@ public sealed class JiboInteractionServiceTests
|
||||
}
|
||||
});
|
||||
|
||||
Assert.Equal("robot_age", decision.IntentName);
|
||||
Assert.Equal("I count March 22, 2026 as my birthday, so I am 1 month old.", decision.ReplyText);
|
||||
Assert.Equal("robot_how_old_are_you", decision.IntentName);
|
||||
Assert.Contains("first powered up", decision.ReplyText, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
||||
Reference in New Issue
Block a user