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 IReadOnlyList<string> Jokes { get; init; } = [];
|
||||
public IReadOnlyList<string> FunFacts { get; init; } = [];
|
||||
public IReadOnlyList<string> DanceAnimations { get; init; } = [];
|
||||
public IReadOnlyList<string> GreetingReplies { get; init; } = [];
|
||||
public IReadOnlyList<string> HowAreYouReplies { get; init; } = [];
|
||||
@@ -46,4 +47,4 @@ public sealed class JiboExperienceCatalog
|
||||
public IReadOnlyList<string> GenericFallbackReplies { get; init; } = [];
|
||||
public IReadOnlyList<string> DanceReplies { get; init; } = [];
|
||||
public IReadOnlyList<string> DanceQuestionReplies { get; init; } = [];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -515,6 +515,7 @@ public sealed class JiboInteractionService(
|
||||
"time" => BuildClockLaunchDecision("time", "clock", "askForTime", "Showing the time."),
|
||||
"date" => BuildClockLaunchDecision("date", "clock", "askForDate", "Showing the date."),
|
||||
"day" => BuildClockLaunchDecision("day", "clock", "askForDay", "Showing the day."),
|
||||
"current_location" => BuildCurrentLocationDecision(turn),
|
||||
"cloud_version" => BuildCloudVersionDecision(),
|
||||
"radio" => BuildRadioLaunchDecision(),
|
||||
"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.");
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
return new JiboInteractionDecision(
|
||||
@@ -1165,6 +1194,20 @@ public sealed class JiboInteractionService(
|
||||
"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(
|
||||
TurnContext turn,
|
||||
string transcript,
|
||||
@@ -2103,6 +2146,8 @@ public sealed class JiboInteractionService(
|
||||
"proactive_pizza_day" => BuildProactivePizzaDayDecision(referenceLocalTime),
|
||||
"proactive_pizza_preference" => BuildProactivePizzaPreferenceDecision(),
|
||||
"proactive_offer_pizza_fact" => BuildProactivePizzaFactOfferDecision(),
|
||||
"proactive_fun_fact" => BuildProactiveFunFactDecision(catalog),
|
||||
"proactive_joke" => BuildProactiveJokeDecision(catalog),
|
||||
_ => new JiboInteractionDecision("surprise", randomizer.Choose(catalog.SurpriseReplies))
|
||||
};
|
||||
}
|
||||
@@ -2136,6 +2181,8 @@ public sealed class JiboInteractionService(
|
||||
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));
|
||||
return candidates;
|
||||
}
|
||||
@@ -2494,7 +2541,17 @@ public sealed class JiboInteractionService(
|
||||
|
||||
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(
|
||||
loweredTranscript,
|
||||
@@ -2690,6 +2747,18 @@ public sealed class JiboInteractionService(
|
||||
"where were you made"))
|
||||
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(
|
||||
loweredTranscript,
|
||||
"what's your name",
|
||||
@@ -3248,7 +3317,7 @@ public sealed class JiboInteractionService(
|
||||
return "word_of_the_day";
|
||||
|
||||
if (string.Equals(yesNoRule, "surprises-date/offer_date_fact", StringComparison.OrdinalIgnoreCase))
|
||||
return "surprise";
|
||||
return "proactive_offer_pizza_fact";
|
||||
|
||||
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)
|
||||
{
|
||||
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.",
|
||||
"What do you call a pirate robot? Arrrr two dee two.",
|
||||
"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 =
|
||||
[
|
||||
@@ -214,4 +230,4 @@ public sealed class InMemoryJiboExperienceContentRepository : IJiboExperienceCon
|
||||
|
||||
return candidates.Where(Directory.Exists).ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,6 +99,14 @@ public static class LegacyMimCatalogImporter
|
||||
fileName.Contains("Deflector", StringComparison.OrdinalIgnoreCase))
|
||||
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) ||
|
||||
normalizedPath.Contains("/gqa-responses/", StringComparison.OrdinalIgnoreCase))
|
||||
return LegacyMimBucket.Emotion;
|
||||
@@ -213,6 +221,7 @@ public static class LegacyMimCatalogImporter
|
||||
return new JiboExperienceCatalog
|
||||
{
|
||||
Jokes = Merge(baseCatalog.Jokes, importedCatalog.Jokes),
|
||||
FunFacts = Merge(baseCatalog.FunFacts, importedCatalog.FunFacts),
|
||||
DanceAnimations = Merge(baseCatalog.DanceAnimations, importedCatalog.DanceAnimations),
|
||||
GreetingReplies = Merge(baseCatalog.GreetingReplies, importedCatalog.GreetingReplies),
|
||||
HowAreYouReplies = Merge(baseCatalog.HowAreYouReplies, importedCatalog.HowAreYouReplies),
|
||||
@@ -322,8 +331,10 @@ public static class LegacyMimCatalogImporter
|
||||
{
|
||||
GenericFallback,
|
||||
Greeting,
|
||||
Jokes,
|
||||
HowAreYou,
|
||||
Emotion,
|
||||
FunFacts,
|
||||
Personality,
|
||||
PersonalReportKickOff,
|
||||
PersonalReportOutro,
|
||||
@@ -353,7 +364,9 @@ public static class LegacyMimCatalogImporter
|
||||
private readonly List<JiboConditionedReply> _emotionReplies = [];
|
||||
private readonly List<string> _fallbacks = [];
|
||||
private readonly List<string> _greetings = [];
|
||||
private readonly List<string> _jokes = [];
|
||||
private readonly List<string> _howAreYous = [];
|
||||
private readonly List<string> _funFacts = [];
|
||||
private readonly List<string> _newsCategoryIntroReplies = [];
|
||||
private readonly List<string> _newsIntroReplies = [];
|
||||
private readonly List<string> _newsOutroReplies = [];
|
||||
@@ -381,6 +394,11 @@ public static class LegacyMimCatalogImporter
|
||||
|
||||
_greetings.Add(text);
|
||||
return;
|
||||
case LegacyMimBucket.Jokes:
|
||||
if (_jokes.Any(value => string.Equals(value, text, StringComparison.OrdinalIgnoreCase))) return;
|
||||
|
||||
_jokes.Add(text);
|
||||
return;
|
||||
case LegacyMimBucket.HowAreYou:
|
||||
if (_howAreYous.Any(value => string.Equals(value, text, StringComparison.OrdinalIgnoreCase)))
|
||||
return;
|
||||
@@ -407,6 +425,11 @@ public static class LegacyMimCatalogImporter
|
||||
|
||||
_personalities.Add(text);
|
||||
return;
|
||||
case LegacyMimBucket.FunFacts:
|
||||
if (_funFacts.Any(value => string.Equals(value, text, StringComparison.OrdinalIgnoreCase))) return;
|
||||
|
||||
_funFacts.Add(text);
|
||||
return;
|
||||
case LegacyMimBucket.PersonalReportKickOff:
|
||||
AddDistinct(_personalReportKickOffReplies, text);
|
||||
return;
|
||||
@@ -464,6 +487,8 @@ public static class LegacyMimCatalogImporter
|
||||
{
|
||||
return new JiboExperienceCatalog
|
||||
{
|
||||
Jokes = [.. _jokes],
|
||||
FunFacts = [.. _funFacts],
|
||||
GreetingReplies = [.. _greetings],
|
||||
HowAreYouReplies = [.. _howAreYous],
|
||||
EmotionReplies = [.. _emotionReplies],
|
||||
@@ -524,4 +549,4 @@ public static class LegacyMimCatalogImporter
|
||||
|
||||
[JsonPropertyName("weight")] public double? Weight { get; init; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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`.
|
||||
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 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));
|
||||
}
|
||||
|
||||
[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]
|
||||
public void ImportCatalog_ImportsBuildBRnGreetingResponsesIntoGreetingBucket()
|
||||
{
|
||||
@@ -465,4 +484,4 @@ public sealed class LegacyMimCatalogImporterTests
|
||||
|
||||
return rootDirectory;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -496,6 +496,26 @@ public sealed class JiboInteractionServiceTests
|
||||
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]
|
||||
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);
|
||||
}
|
||||
|
||||
[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]
|
||||
public async Task BuildDecisionAsync_WordOfDayOfferPrompt_WithNoisyAffirmation_MapsToWordOfDayLaunch()
|
||||
{
|
||||
|
||||
@@ -21,7 +21,7 @@ public sealed class JiboWebSocketServiceTests
|
||||
var contentRepository = new InMemoryJiboExperienceContentRepository();
|
||||
var contentCache = new JiboExperienceContentCache(contentRepository);
|
||||
var conversationBroker = new DemoConversationBroker(new JiboInteractionService(contentCache,
|
||||
new DefaultJiboRandomizer(), new InMemoryPersonalMemoryStore()));
|
||||
new LastItemRandomizer(), new InMemoryPersonalMemoryStore()));
|
||||
var sttSelector = new DefaultSttStrategySelector(
|
||||
[
|
||||
new SyntheticBufferedAudioSttStrategy()
|
||||
@@ -5111,4 +5111,12 @@ public sealed class JiboWebSocketServiceTests
|
||||
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