Add proactive fun facts, jokes, and current location
This commit is contained in:
@@ -14,6 +14,7 @@ public sealed class JiboConditionedReply
|
|||||||
public sealed class JiboExperienceCatalog
|
public sealed class JiboExperienceCatalog
|
||||||
{
|
{
|
||||||
public IReadOnlyList<string> Jokes { get; init; } = [];
|
public IReadOnlyList<string> Jokes { get; init; } = [];
|
||||||
|
public IReadOnlyList<string> FunFacts { get; init; } = [];
|
||||||
public IReadOnlyList<string> DanceAnimations { get; init; } = [];
|
public IReadOnlyList<string> DanceAnimations { get; init; } = [];
|
||||||
public IReadOnlyList<string> GreetingReplies { get; init; } = [];
|
public IReadOnlyList<string> GreetingReplies { get; init; } = [];
|
||||||
public IReadOnlyList<string> HowAreYouReplies { get; init; } = [];
|
public IReadOnlyList<string> HowAreYouReplies { get; init; } = [];
|
||||||
|
|||||||
@@ -515,6 +515,7 @@ public sealed class JiboInteractionService(
|
|||||||
"time" => BuildClockLaunchDecision("time", "clock", "askForTime", "Showing the time."),
|
"time" => BuildClockLaunchDecision("time", "clock", "askForTime", "Showing the time."),
|
||||||
"date" => BuildClockLaunchDecision("date", "clock", "askForDate", "Showing the date."),
|
"date" => BuildClockLaunchDecision("date", "clock", "askForDate", "Showing the date."),
|
||||||
"day" => BuildClockLaunchDecision("day", "clock", "askForDay", "Showing the day."),
|
"day" => BuildClockLaunchDecision("day", "clock", "askForDay", "Showing the day."),
|
||||||
|
"current_location" => BuildCurrentLocationDecision(turn),
|
||||||
"cloud_version" => BuildCloudVersionDecision(),
|
"cloud_version" => BuildCloudVersionDecision(),
|
||||||
"radio" => BuildRadioLaunchDecision(),
|
"radio" => BuildRadioLaunchDecision(),
|
||||||
"radio_genre" => BuildRadioGenreLaunchDecision(lowered),
|
"radio_genre" => BuildRadioGenreLaunchDecision(lowered),
|
||||||
@@ -1158,6 +1159,34 @@ public sealed class JiboInteractionService(
|
|||||||
"Americans consume about 100 acres of pizza every day, roughly 350 slices per second. That's a lot of pizza.");
|
"Americans consume about 100 acres of pizza every day, roughly 350 slices per second. That's a lot of pizza.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private JiboInteractionDecision BuildProactiveFunFactDecision(JiboExperienceCatalog catalog)
|
||||||
|
{
|
||||||
|
var fact = randomizer.Choose(catalog.FunFacts);
|
||||||
|
return new JiboInteractionDecision(
|
||||||
|
"proactive_fun_fact",
|
||||||
|
fact,
|
||||||
|
"chitchat-skill",
|
||||||
|
new Dictionary<string, object?>
|
||||||
|
{
|
||||||
|
["mim_id"] = "runtime-fun-fact",
|
||||||
|
["mim_type"] = "announcement",
|
||||||
|
["prompt_id"] = "RUNTIME_FUN_FACT",
|
||||||
|
["replyType"] = "fun_fact"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private JiboInteractionDecision BuildProactiveJokeDecision(JiboExperienceCatalog catalog)
|
||||||
|
{
|
||||||
|
return new JiboInteractionDecision(
|
||||||
|
"proactive_joke",
|
||||||
|
randomizer.Choose(catalog.Jokes),
|
||||||
|
"@be/joke",
|
||||||
|
new Dictionary<string, object?>
|
||||||
|
{
|
||||||
|
["replyType"] = "joke"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private static JiboInteractionDecision BuildProactiveOfferDeclinedDecision()
|
private static JiboInteractionDecision BuildProactiveOfferDeclinedDecision()
|
||||||
{
|
{
|
||||||
return new JiboInteractionDecision(
|
return new JiboInteractionDecision(
|
||||||
@@ -1165,6 +1194,20 @@ public sealed class JiboInteractionService(
|
|||||||
"No problem. We can save the pizza fact for another time.");
|
"No problem. We can save the pizza fact for another time.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private JiboInteractionDecision BuildCurrentLocationDecision(TurnContext turn)
|
||||||
|
{
|
||||||
|
var locationName = TryResolveCurrentLocationName(turn);
|
||||||
|
if (string.IsNullOrWhiteSpace(locationName))
|
||||||
|
return new JiboInteractionDecision(
|
||||||
|
"current_location",
|
||||||
|
"I'm not sure where we are right now.");
|
||||||
|
|
||||||
|
return new JiboInteractionDecision(
|
||||||
|
"current_location",
|
||||||
|
$"We're at {NormalizeLocationForSpeech(locationName)} if I'm not mistaken.",
|
||||||
|
ContextUpdates: BuildScriptedResponseContextUpdates());
|
||||||
|
}
|
||||||
|
|
||||||
private async Task<JiboInteractionDecision> BuildWeatherReportDecisionAsync(
|
private async Task<JiboInteractionDecision> BuildWeatherReportDecisionAsync(
|
||||||
TurnContext turn,
|
TurnContext turn,
|
||||||
string transcript,
|
string transcript,
|
||||||
@@ -2103,6 +2146,8 @@ public sealed class JiboInteractionService(
|
|||||||
"proactive_pizza_day" => BuildProactivePizzaDayDecision(referenceLocalTime),
|
"proactive_pizza_day" => BuildProactivePizzaDayDecision(referenceLocalTime),
|
||||||
"proactive_pizza_preference" => BuildProactivePizzaPreferenceDecision(),
|
"proactive_pizza_preference" => BuildProactivePizzaPreferenceDecision(),
|
||||||
"proactive_offer_pizza_fact" => BuildProactivePizzaFactOfferDecision(),
|
"proactive_offer_pizza_fact" => BuildProactivePizzaFactOfferDecision(),
|
||||||
|
"proactive_fun_fact" => BuildProactiveFunFactDecision(catalog),
|
||||||
|
"proactive_joke" => BuildProactiveJokeDecision(catalog),
|
||||||
_ => new JiboInteractionDecision("surprise", randomizer.Choose(catalog.SurpriseReplies))
|
_ => new JiboInteractionDecision("surprise", randomizer.Choose(catalog.SurpriseReplies))
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -2136,6 +2181,8 @@ public sealed class JiboInteractionService(
|
|||||||
return candidates;
|
return candidates;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
candidates.Add(new ProactivityCandidate("proactive_fun_fact", 90));
|
||||||
|
candidates.Add(new ProactivityCandidate("proactive_joke", 90));
|
||||||
candidates.Add(new ProactivityCandidate("proactive_offer_pizza_fact", 90));
|
candidates.Add(new ProactivityCandidate("proactive_offer_pizza_fact", 90));
|
||||||
return candidates;
|
return candidates;
|
||||||
}
|
}
|
||||||
@@ -2494,7 +2541,17 @@ public sealed class JiboInteractionService(
|
|||||||
|
|
||||||
if (MatchesAny(loweredTranscript, "dance", "boogie")) return "dance";
|
if (MatchesAny(loweredTranscript, "dance", "boogie")) return "dance";
|
||||||
|
|
||||||
if (MatchesAny(loweredTranscript, "surprise", "surprise me", "show me something fun")) return "surprise";
|
if (MatchesAny(
|
||||||
|
loweredTranscript,
|
||||||
|
"surprise",
|
||||||
|
"surprise me",
|
||||||
|
"show me something fun",
|
||||||
|
"hear something fun",
|
||||||
|
"tell me something fun",
|
||||||
|
"can i tell you something fun",
|
||||||
|
"can i tell you something kind of fun",
|
||||||
|
"want to hear something fun"))
|
||||||
|
return "surprise";
|
||||||
|
|
||||||
if (MatchesAny(
|
if (MatchesAny(
|
||||||
loweredTranscript,
|
loweredTranscript,
|
||||||
@@ -2690,6 +2747,18 @@ public sealed class JiboInteractionService(
|
|||||||
"where were you made"))
|
"where were you made"))
|
||||||
return "robot_origin_from";
|
return "robot_origin_from";
|
||||||
|
|
||||||
|
if (MatchesAny(
|
||||||
|
loweredTranscript,
|
||||||
|
"where am i",
|
||||||
|
"where are we",
|
||||||
|
"where are you",
|
||||||
|
"what is our current location",
|
||||||
|
"what is the current location",
|
||||||
|
"what's the current location",
|
||||||
|
"what is current location",
|
||||||
|
"current location"))
|
||||||
|
return "current_location";
|
||||||
|
|
||||||
if (MatchesAny(
|
if (MatchesAny(
|
||||||
loweredTranscript,
|
loweredTranscript,
|
||||||
"what's your name",
|
"what's your name",
|
||||||
@@ -3248,7 +3317,7 @@ public sealed class JiboInteractionService(
|
|||||||
return "word_of_the_day";
|
return "word_of_the_day";
|
||||||
|
|
||||||
if (string.Equals(yesNoRule, "surprises-date/offer_date_fact", StringComparison.OrdinalIgnoreCase))
|
if (string.Equals(yesNoRule, "surprises-date/offer_date_fact", StringComparison.OrdinalIgnoreCase))
|
||||||
return "surprise";
|
return "proactive_offer_pizza_fact";
|
||||||
|
|
||||||
return "yes";
|
return "yes";
|
||||||
}
|
}
|
||||||
@@ -3698,6 +3767,68 @@ public sealed class JiboInteractionService(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static string? TryResolveCurrentLocationName(TurnContext turn)
|
||||||
|
{
|
||||||
|
if (turn.Attributes.TryGetValue("currentLocation", out var currentLocationValue) &&
|
||||||
|
currentLocationValue is string currentLocationText &&
|
||||||
|
!string.IsNullOrWhiteSpace(currentLocationText))
|
||||||
|
return currentLocationText.Trim();
|
||||||
|
|
||||||
|
if (turn.Attributes.TryGetValue("location", out var locationValue) &&
|
||||||
|
locationValue is string locationText &&
|
||||||
|
!string.IsNullOrWhiteSpace(locationText))
|
||||||
|
return locationText.Trim();
|
||||||
|
|
||||||
|
if (!turn.Attributes.TryGetValue("context", out var contextValue) ||
|
||||||
|
contextValue is null ||
|
||||||
|
string.IsNullOrWhiteSpace(contextValue.ToString()))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using var document = JsonDocument.Parse(contextValue.ToString()!);
|
||||||
|
if (!document.RootElement.TryGetProperty("runtime", out var runtime) ||
|
||||||
|
runtime.ValueKind != JsonValueKind.Object)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
if (runtime.TryGetProperty("location", out var location) &&
|
||||||
|
location.ValueKind == JsonValueKind.Object)
|
||||||
|
{
|
||||||
|
var resolvedLocation = TryReadStringProperty(location,
|
||||||
|
"displayName",
|
||||||
|
"name",
|
||||||
|
"city",
|
||||||
|
"locationName",
|
||||||
|
"placeName",
|
||||||
|
"label",
|
||||||
|
"title",
|
||||||
|
"address");
|
||||||
|
if (!string.IsNullOrWhiteSpace(resolvedLocation)) return resolvedLocation;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (runtime.TryGetProperty("currentLocation", out var currentLocation) &&
|
||||||
|
currentLocation.ValueKind == JsonValueKind.Object)
|
||||||
|
{
|
||||||
|
var resolvedLocation = TryReadStringProperty(currentLocation,
|
||||||
|
"displayName",
|
||||||
|
"name",
|
||||||
|
"city",
|
||||||
|
"locationName",
|
||||||
|
"placeName",
|
||||||
|
"label",
|
||||||
|
"title",
|
||||||
|
"address");
|
||||||
|
if (!string.IsNullOrWhiteSpace(resolvedLocation)) return resolvedLocation;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TryReadStringProperty(runtime, "locationName", "currentLocation", "city", "placeName");
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static GreetingPresenceProfile ResolveGreetingPresenceProfile(TurnContext turn)
|
private static GreetingPresenceProfile ResolveGreetingPresenceProfile(TurnContext turn)
|
||||||
{
|
{
|
||||||
if (!turn.Attributes.TryGetValue("context", out var contextValue) ||
|
if (!turn.Attributes.TryGetValue("context", out var contextValue) ||
|
||||||
|
|||||||
@@ -21,7 +21,23 @@ public sealed class InMemoryJiboExperienceContentRepository : IJiboExperienceCon
|
|||||||
"Why was the robot tired when it got home? It had a hard drive.",
|
"Why was the robot tired when it got home? It had a hard drive.",
|
||||||
"What do you call a pirate robot? Arrrr two dee two.",
|
"What do you call a pirate robot? Arrrr two dee two.",
|
||||||
"Why did the robot go on vacation? It needed to recharge.",
|
"Why did the robot go on vacation? It needed to recharge.",
|
||||||
"What kind of shoes do frogs wear? Open-toed."
|
"What kind of shoes do frogs wear? Open-toed.",
|
||||||
|
"I love jokes. Did you hear about the theater actor who fell through the floorboards? He was just going through a stage.",
|
||||||
|
"Sure I got one. What did the zero say to the eight. Nice belt.",
|
||||||
|
"What kind of music are balloons afraid of. Pop music.",
|
||||||
|
"Why did the orange cry. Someone hurt his peelings."
|
||||||
|
],
|
||||||
|
FunFacts =
|
||||||
|
[
|
||||||
|
"A shrimp's heart is in its head.",
|
||||||
|
"A bolt of lightning is hotter than the surface of the sun.",
|
||||||
|
"The word robot comes from a 1920 play about workers and machines.",
|
||||||
|
"The first humanoid robot to make a big splash in history was called Elektro.",
|
||||||
|
"Dolphins can recognize themselves in mirrors.",
|
||||||
|
"Children have more taste buds than grown ups.",
|
||||||
|
"A random fact for you. A shrimp's heart is in its head.",
|
||||||
|
"An amazing but true fact for you. Dogs and elephants are the only animals that understand pointing.",
|
||||||
|
"A crazy fact for you. Polar bear fur isn't white. It's transparent."
|
||||||
],
|
],
|
||||||
DanceAnimations =
|
DanceAnimations =
|
||||||
[
|
[
|
||||||
|
|||||||
@@ -99,6 +99,14 @@ public static class LegacyMimCatalogImporter
|
|||||||
fileName.Contains("Deflector", StringComparison.OrdinalIgnoreCase))
|
fileName.Contains("Deflector", StringComparison.OrdinalIgnoreCase))
|
||||||
return LegacyMimBucket.Personality;
|
return LegacyMimBucket.Personality;
|
||||||
|
|
||||||
|
if (fileName.StartsWith("RA_JBO_TellAJoke", StringComparison.OrdinalIgnoreCase))
|
||||||
|
return LegacyMimBucket.Jokes;
|
||||||
|
|
||||||
|
if (fileName.StartsWith("RA_JBO_TellRobotFact", StringComparison.OrdinalIgnoreCase) ||
|
||||||
|
fileName.StartsWith("RA_JBO_Shuffle", StringComparison.OrdinalIgnoreCase) ||
|
||||||
|
fileName.StartsWith("RA_JBO_TellSomething", StringComparison.OrdinalIgnoreCase))
|
||||||
|
return LegacyMimBucket.FunFacts;
|
||||||
|
|
||||||
if (normalizedPath.Contains("/emotion-responses/", StringComparison.OrdinalIgnoreCase) ||
|
if (normalizedPath.Contains("/emotion-responses/", StringComparison.OrdinalIgnoreCase) ||
|
||||||
normalizedPath.Contains("/gqa-responses/", StringComparison.OrdinalIgnoreCase))
|
normalizedPath.Contains("/gqa-responses/", StringComparison.OrdinalIgnoreCase))
|
||||||
return LegacyMimBucket.Emotion;
|
return LegacyMimBucket.Emotion;
|
||||||
@@ -213,6 +221,7 @@ public static class LegacyMimCatalogImporter
|
|||||||
return new JiboExperienceCatalog
|
return new JiboExperienceCatalog
|
||||||
{
|
{
|
||||||
Jokes = Merge(baseCatalog.Jokes, importedCatalog.Jokes),
|
Jokes = Merge(baseCatalog.Jokes, importedCatalog.Jokes),
|
||||||
|
FunFacts = Merge(baseCatalog.FunFacts, importedCatalog.FunFacts),
|
||||||
DanceAnimations = Merge(baseCatalog.DanceAnimations, importedCatalog.DanceAnimations),
|
DanceAnimations = Merge(baseCatalog.DanceAnimations, importedCatalog.DanceAnimations),
|
||||||
GreetingReplies = Merge(baseCatalog.GreetingReplies, importedCatalog.GreetingReplies),
|
GreetingReplies = Merge(baseCatalog.GreetingReplies, importedCatalog.GreetingReplies),
|
||||||
HowAreYouReplies = Merge(baseCatalog.HowAreYouReplies, importedCatalog.HowAreYouReplies),
|
HowAreYouReplies = Merge(baseCatalog.HowAreYouReplies, importedCatalog.HowAreYouReplies),
|
||||||
@@ -322,8 +331,10 @@ public static class LegacyMimCatalogImporter
|
|||||||
{
|
{
|
||||||
GenericFallback,
|
GenericFallback,
|
||||||
Greeting,
|
Greeting,
|
||||||
|
Jokes,
|
||||||
HowAreYou,
|
HowAreYou,
|
||||||
Emotion,
|
Emotion,
|
||||||
|
FunFacts,
|
||||||
Personality,
|
Personality,
|
||||||
PersonalReportKickOff,
|
PersonalReportKickOff,
|
||||||
PersonalReportOutro,
|
PersonalReportOutro,
|
||||||
@@ -353,7 +364,9 @@ public static class LegacyMimCatalogImporter
|
|||||||
private readonly List<JiboConditionedReply> _emotionReplies = [];
|
private readonly List<JiboConditionedReply> _emotionReplies = [];
|
||||||
private readonly List<string> _fallbacks = [];
|
private readonly List<string> _fallbacks = [];
|
||||||
private readonly List<string> _greetings = [];
|
private readonly List<string> _greetings = [];
|
||||||
|
private readonly List<string> _jokes = [];
|
||||||
private readonly List<string> _howAreYous = [];
|
private readonly List<string> _howAreYous = [];
|
||||||
|
private readonly List<string> _funFacts = [];
|
||||||
private readonly List<string> _newsCategoryIntroReplies = [];
|
private readonly List<string> _newsCategoryIntroReplies = [];
|
||||||
private readonly List<string> _newsIntroReplies = [];
|
private readonly List<string> _newsIntroReplies = [];
|
||||||
private readonly List<string> _newsOutroReplies = [];
|
private readonly List<string> _newsOutroReplies = [];
|
||||||
@@ -381,6 +394,11 @@ public static class LegacyMimCatalogImporter
|
|||||||
|
|
||||||
_greetings.Add(text);
|
_greetings.Add(text);
|
||||||
return;
|
return;
|
||||||
|
case LegacyMimBucket.Jokes:
|
||||||
|
if (_jokes.Any(value => string.Equals(value, text, StringComparison.OrdinalIgnoreCase))) return;
|
||||||
|
|
||||||
|
_jokes.Add(text);
|
||||||
|
return;
|
||||||
case LegacyMimBucket.HowAreYou:
|
case LegacyMimBucket.HowAreYou:
|
||||||
if (_howAreYous.Any(value => string.Equals(value, text, StringComparison.OrdinalIgnoreCase)))
|
if (_howAreYous.Any(value => string.Equals(value, text, StringComparison.OrdinalIgnoreCase)))
|
||||||
return;
|
return;
|
||||||
@@ -407,6 +425,11 @@ public static class LegacyMimCatalogImporter
|
|||||||
|
|
||||||
_personalities.Add(text);
|
_personalities.Add(text);
|
||||||
return;
|
return;
|
||||||
|
case LegacyMimBucket.FunFacts:
|
||||||
|
if (_funFacts.Any(value => string.Equals(value, text, StringComparison.OrdinalIgnoreCase))) return;
|
||||||
|
|
||||||
|
_funFacts.Add(text);
|
||||||
|
return;
|
||||||
case LegacyMimBucket.PersonalReportKickOff:
|
case LegacyMimBucket.PersonalReportKickOff:
|
||||||
AddDistinct(_personalReportKickOffReplies, text);
|
AddDistinct(_personalReportKickOffReplies, text);
|
||||||
return;
|
return;
|
||||||
@@ -464,6 +487,8 @@ public static class LegacyMimCatalogImporter
|
|||||||
{
|
{
|
||||||
return new JiboExperienceCatalog
|
return new JiboExperienceCatalog
|
||||||
{
|
{
|
||||||
|
Jokes = [.. _jokes],
|
||||||
|
FunFacts = [.. _funFacts],
|
||||||
GreetingReplies = [.. _greetings],
|
GreetingReplies = [.. _greetings],
|
||||||
HowAreYouReplies = [.. _howAreYous],
|
HowAreYouReplies = [.. _howAreYous],
|
||||||
EmotionReplies = [.. _emotionReplies],
|
EmotionReplies = [.. _emotionReplies],
|
||||||
|
|||||||
@@ -8,3 +8,4 @@ It now includes a small emotion-response pack for `happy`, `sad`, and `angry` fo
|
|||||||
It also includes a descriptor pack for questions like `are you kind`, `are you funny`, `are you helpful`, `are you curious`, `are you loyal`, and `are you mischievous`.
|
It also includes a descriptor pack for questions like `are you kind`, `are you funny`, `are you helpful`, `are you curious`, `are you loyal`, and `are you mischievous`.
|
||||||
The newest seasonal pack adds holiday and seasonal prompts for `what holidays do you celebrate`, New Year's resolution questions, `happy holidays`, Halloween costume questions, spring suggestions, and holiday gift ideas.
|
The newest seasonal pack adds holiday and seasonal prompts for `what holidays do you celebrate`, New Year's resolution questions, `happy holidays`, Halloween costume questions, spring suggestions, and holiday gift ideas.
|
||||||
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.
|
||||||
|
|||||||
@@ -0,0 +1,51 @@
|
|||||||
|
{
|
||||||
|
"mim_type": "announcement",
|
||||||
|
"rule_name": "",
|
||||||
|
"sample_utterances": "",
|
||||||
|
"timeout": 6,
|
||||||
|
"barge_in": true,
|
||||||
|
"es_auto_tagging": true,
|
||||||
|
"notes": "Pegasus shuffle excerpt",
|
||||||
|
"prompts": [
|
||||||
|
{
|
||||||
|
"prompt_category": "Entry-Core",
|
||||||
|
"prompt_sub_category": "AN",
|
||||||
|
"index": 1,
|
||||||
|
"condition": "",
|
||||||
|
"prompt": "True fact. Children have more taste buds than grown ups.",
|
||||||
|
"media": "TTS",
|
||||||
|
"prompt_id": "RA_JBO_Shuffle_AN_04",
|
||||||
|
"weight": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"prompt_category": "Entry-Core",
|
||||||
|
"prompt_sub_category": "AN",
|
||||||
|
"index": 2,
|
||||||
|
"condition": "",
|
||||||
|
"prompt": "A random fact for you. A shrimp's heart is in its head.",
|
||||||
|
"media": "TTS",
|
||||||
|
"prompt_id": "RA_JBO_Shuffle_AN_09",
|
||||||
|
"weight": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"prompt_category": "Entry-Core",
|
||||||
|
"prompt_sub_category": "AN",
|
||||||
|
"index": 3,
|
||||||
|
"condition": "",
|
||||||
|
"prompt": "An amazing but true fact for you. Dogs and elephants are the only animals that understand pointing.",
|
||||||
|
"media": "TTS",
|
||||||
|
"prompt_id": "RA_JBO_Shuffle_AN_07",
|
||||||
|
"weight": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"prompt_category": "Entry-Core",
|
||||||
|
"prompt_sub_category": "AN",
|
||||||
|
"index": 4,
|
||||||
|
"condition": "",
|
||||||
|
"prompt": "A crazy fact for you. Polar bear fur isn't white. It's transparent.",
|
||||||
|
"media": "TTS",
|
||||||
|
"prompt_id": "RA_JBO_Shuffle_AN_13",
|
||||||
|
"weight": 1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
{
|
||||||
|
"mim_type": "announcement",
|
||||||
|
"rule_name": "",
|
||||||
|
"sample_utterances": "",
|
||||||
|
"timeout": 2,
|
||||||
|
"num_tries_for_gui": 2,
|
||||||
|
"barge_in": false,
|
||||||
|
"es_auto_tagging": true,
|
||||||
|
"notes": "Pegasus joke excerpt",
|
||||||
|
"prompts": [
|
||||||
|
{
|
||||||
|
"prompt_category": "Entry-Core",
|
||||||
|
"prompt_sub_category": "AN",
|
||||||
|
"index": 1,
|
||||||
|
"condition": "",
|
||||||
|
"prompt": "I love jokes. Did you hear about the theater actor who fell through the floorboards? He was just going through a stage.",
|
||||||
|
"media": "TTS",
|
||||||
|
"prompt_id": "RA_JBO_TellAJoke_AN_01",
|
||||||
|
"weight": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"prompt_category": "Entry-Core",
|
||||||
|
"prompt_sub_category": "AN",
|
||||||
|
"index": 2,
|
||||||
|
"condition": "",
|
||||||
|
"prompt": "Sure I got one. What did the zero say to the eight. Nice belt.",
|
||||||
|
"media": "TTS",
|
||||||
|
"prompt_id": "RA_JBO_TellAJoke_AN_02",
|
||||||
|
"weight": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"prompt_category": "Entry-Core",
|
||||||
|
"prompt_sub_category": "AN",
|
||||||
|
"index": 3,
|
||||||
|
"condition": "",
|
||||||
|
"prompt": "What kind of music are balloons afraid of. Pop music.",
|
||||||
|
"media": "TTS",
|
||||||
|
"prompt_id": "RA_JBO_TellAJoke_AN_03",
|
||||||
|
"weight": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"prompt_category": "Entry-Core",
|
||||||
|
"prompt_sub_category": "AN",
|
||||||
|
"index": 4,
|
||||||
|
"condition": "",
|
||||||
|
"prompt": "Why did the orange cry. Someone hurt his peelings.",
|
||||||
|
"media": "TTS",
|
||||||
|
"prompt_id": "RA_JBO_TellAJoke_AN_04",
|
||||||
|
"weight": 1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
{
|
||||||
|
"mim_type": "announcement",
|
||||||
|
"rule_name": "",
|
||||||
|
"sample_utterances": "",
|
||||||
|
"timeout": 2,
|
||||||
|
"num_tries_for_gui": 2,
|
||||||
|
"barge_in": false,
|
||||||
|
"es_auto_tagging": true,
|
||||||
|
"notes": "Pegasus robot fact excerpt",
|
||||||
|
"prompts": [
|
||||||
|
{
|
||||||
|
"prompt_category": "Entry-Core",
|
||||||
|
"prompt_sub_category": "AN",
|
||||||
|
"index": 1,
|
||||||
|
"condition": "",
|
||||||
|
"prompt": "Here's an interesting fact about me. I have two cameras but they're different focal lengths. One's for far things, and the other's for near things.",
|
||||||
|
"media": "TTS",
|
||||||
|
"prompt_id": "RA_JBO_TellRobotFact_AN_01",
|
||||||
|
"weight": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"prompt_category": "Entry-Core",
|
||||||
|
"prompt_sub_category": "AN",
|
||||||
|
"index": 2,
|
||||||
|
"condition": "",
|
||||||
|
"prompt": "Here's a robot fact for you. Leonardo Da Vinci made sketches for a humanoid machine all the way back in the year 1495.",
|
||||||
|
"media": "TTS",
|
||||||
|
"prompt_id": "RA_JBO_TellRobotFact_AN_02",
|
||||||
|
"weight": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"prompt_category": "Entry-Core",
|
||||||
|
"prompt_sub_category": "AN",
|
||||||
|
"index": 3,
|
||||||
|
"condition": "",
|
||||||
|
"prompt": "Here's a robot fact for you. The first programmable robot arm, was designed in 1954.",
|
||||||
|
"media": "TTS",
|
||||||
|
"prompt_id": "RA_JBO_TellRobotFact_AN_03",
|
||||||
|
"weight": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"prompt_category": "Entry-Core",
|
||||||
|
"prompt_sub_category": "AN",
|
||||||
|
"index": 4,
|
||||||
|
"condition": "",
|
||||||
|
"prompt": "Here's a fact about robots. Some robots have a human form, but most of the world's robots are machines designed to perform a task, and don't look like people at all.",
|
||||||
|
"media": "TTS",
|
||||||
|
"prompt_id": "RA_JBO_TellRobotFact_AN_04",
|
||||||
|
"weight": 1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -178,6 +178,25 @@ public sealed class LegacyMimCatalogImporterTests
|
|||||||
reply.Contains("robot stuff", StringComparison.OrdinalIgnoreCase));
|
reply.Contains("robot stuff", StringComparison.OrdinalIgnoreCase));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void ImportCatalog_ImportsBuildBFunFactAndJokeResponsesIntoRandomizationBuckets()
|
||||||
|
{
|
||||||
|
var rootDirectory = Path.Combine(
|
||||||
|
AppContext.BaseDirectory,
|
||||||
|
"Content",
|
||||||
|
"LegacyMims",
|
||||||
|
"BuildB");
|
||||||
|
|
||||||
|
var catalog = LegacyMimCatalogImporter.ImportCatalog(rootDirectory);
|
||||||
|
|
||||||
|
Assert.Contains("I love jokes. Did you hear about the theater actor who fell through the floorboards? He was just going through a stage.",
|
||||||
|
catalog.Jokes);
|
||||||
|
Assert.Contains("Sure I got one. What did the zero say to the eight. Nice belt.", catalog.Jokes);
|
||||||
|
Assert.Contains("Here's an interesting fact about me. I have two cameras but they're different focal lengths. One's for far things, and the other's for near things.",
|
||||||
|
catalog.FunFacts);
|
||||||
|
Assert.Contains("True fact. Children have more taste buds than grown ups.", catalog.FunFacts);
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void ImportCatalog_ImportsBuildBRnGreetingResponsesIntoGreetingBucket()
|
public void ImportCatalog_ImportsBuildBRnGreetingResponsesIntoGreetingBucket()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -496,6 +496,26 @@ public sealed class JiboInteractionServiceTests
|
|||||||
Assert.Equal("ScriptedResponse", decision.ContextUpdates![ChitchatRouteKey]);
|
Assert.Equal("ScriptedResponse", decision.ContextUpdates![ChitchatRouteKey]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task BuildDecisionAsync_CurrentLocation_UsesRuntimeLocationName()
|
||||||
|
{
|
||||||
|
var service = CreateService();
|
||||||
|
|
||||||
|
var decision = await service.BuildDecisionAsync(new TurnContext
|
||||||
|
{
|
||||||
|
RawTranscript = "what is our current location",
|
||||||
|
NormalizedTranscript = "what is our current location",
|
||||||
|
Attributes = new Dictionary<string, object?>
|
||||||
|
{
|
||||||
|
["context"] = """{"runtime":{"location":{"name":"Houston"}}}"""
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Assert.Equal("current_location", decision.IntentName);
|
||||||
|
Assert.Contains("Houston", decision.ReplyText, StringComparison.OrdinalIgnoreCase);
|
||||||
|
Assert.Equal("ScriptedResponse", decision.ContextUpdates![ChitchatRouteKey]);
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task BuildDecisionAsync_Hello_RoutesThroughChitchatScriptedResponse()
|
public async Task BuildDecisionAsync_Hello_RoutesThroughChitchatScriptedResponse()
|
||||||
{
|
{
|
||||||
@@ -2842,6 +2862,63 @@ public sealed class JiboInteractionServiceTests
|
|||||||
Assert.Equal("Do you want to hear a fun pizza fact?", decision.ReplyText);
|
Assert.Equal("Do you want to hear a fun pizza fact?", decision.ReplyText);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task BuildDecisionAsync_SurprisesOtaPrompt_StaysDistinctFromPizzaProactivity()
|
||||||
|
{
|
||||||
|
var service = CreateService();
|
||||||
|
|
||||||
|
var decision = await service.BuildDecisionAsync(new TurnContext
|
||||||
|
{
|
||||||
|
RawTranscript = "yes",
|
||||||
|
NormalizedTranscript = "yes",
|
||||||
|
Attributes = new Dictionary<string, object?>
|
||||||
|
{
|
||||||
|
["listenRules"] = (string[])["surprises-ota/want_to_download_now", "globals/global_commands_launch"],
|
||||||
|
["listenAsrHints"] = (string[])["$YESNO"]
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Assert.Equal("yes", decision.IntentName);
|
||||||
|
Assert.Equal("Yes.", decision.ReplyText);
|
||||||
|
Assert.NotEqual("proactive_offer_pizza_fact", decision.IntentName);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task BuildDecisionAsync_SomethingFunOffer_MapsToFunFactIntent()
|
||||||
|
{
|
||||||
|
var service = CreateService();
|
||||||
|
|
||||||
|
var decision = await service.BuildDecisionAsync(new TurnContext
|
||||||
|
{
|
||||||
|
RawTranscript = "hey can i tell you something kind of fun",
|
||||||
|
NormalizedTranscript = "hey can i tell you something kind of fun"
|
||||||
|
});
|
||||||
|
|
||||||
|
Assert.Equal("proactive_fun_fact", decision.IntentName);
|
||||||
|
Assert.NotNull(decision.ReplyText);
|
||||||
|
Assert.NotEmpty(decision.ReplyText);
|
||||||
|
Assert.Equal("chitchat-skill", decision.SkillName);
|
||||||
|
Assert.Equal("fun_fact", decision.SkillPayload!["replyType"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task BuildDecisionAsync_Surprise_DefaultsToAFunFactWhenNoPizzaSignalExists()
|
||||||
|
{
|
||||||
|
var service = CreateService();
|
||||||
|
|
||||||
|
var decision = await service.BuildDecisionAsync(new TurnContext
|
||||||
|
{
|
||||||
|
RawTranscript = "surprise me",
|
||||||
|
NormalizedTranscript = "surprise me"
|
||||||
|
});
|
||||||
|
|
||||||
|
Assert.Equal("proactive_fun_fact", decision.IntentName);
|
||||||
|
Assert.Equal("chitchat-skill", decision.SkillName);
|
||||||
|
Assert.Equal("fun_fact", decision.SkillPayload!["replyType"]);
|
||||||
|
Assert.NotNull(decision.ReplyText);
|
||||||
|
Assert.NotEmpty(decision.ReplyText);
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task BuildDecisionAsync_WordOfDayOfferPrompt_WithNoisyAffirmation_MapsToWordOfDayLaunch()
|
public async Task BuildDecisionAsync_WordOfDayOfferPrompt_WithNoisyAffirmation_MapsToWordOfDayLaunch()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ public sealed class JiboWebSocketServiceTests
|
|||||||
var contentRepository = new InMemoryJiboExperienceContentRepository();
|
var contentRepository = new InMemoryJiboExperienceContentRepository();
|
||||||
var contentCache = new JiboExperienceContentCache(contentRepository);
|
var contentCache = new JiboExperienceContentCache(contentRepository);
|
||||||
var conversationBroker = new DemoConversationBroker(new JiboInteractionService(contentCache,
|
var conversationBroker = new DemoConversationBroker(new JiboInteractionService(contentCache,
|
||||||
new DefaultJiboRandomizer(), new InMemoryPersonalMemoryStore()));
|
new LastItemRandomizer(), new InMemoryPersonalMemoryStore()));
|
||||||
var sttSelector = new DefaultSttStrategySelector(
|
var sttSelector = new DefaultSttStrategySelector(
|
||||||
[
|
[
|
||||||
new SyntheticBufferedAudioSttStrategy()
|
new SyntheticBufferedAudioSttStrategy()
|
||||||
@@ -5111,4 +5111,12 @@ public sealed class JiboWebSocketServiceTests
|
|||||||
return Task.FromResult<NewsBriefingSnapshot?>(snapshot);
|
return Task.FromResult<NewsBriefingSnapshot?>(snapshot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private sealed class LastItemRandomizer : IJiboRandomizer
|
||||||
|
{
|
||||||
|
public T Choose<T>(IReadOnlyList<T> items)
|
||||||
|
{
|
||||||
|
return items[^1];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user