Compare commits

6 Commits

Author SHA1 Message Date
Jacob Dubin
a47c90c9c3 Polish weather phrasing for current and forecast replies 2026-05-16 10:16:34 -05:00
Jacob Dubin
393c34055d Prefer forecast hi lo for current weather 2026-05-16 10:01:40 -05:00
Jacob Dubin
f9b728c2a0 Add seasonal and presence charm batches 2026-05-16 09:09:18 -05:00
Jacob Dubin
c87af4686c Add seasonal Build B legacy MIM imports 2026-05-16 08:53:07 -05:00
Jacob Dubin
84759f51de Add Build B charm descriptors and mood replies 2026-05-16 08:39:45 -05:00
Jacob Dubin
c8beb0d1f0 Expand Build B mood and persona follow-ups 2026-05-16 08:05:42 -05:00
32 changed files with 1962 additions and 71 deletions

View File

@@ -841,6 +841,23 @@ Current release theme:
- keep adding small sourced personality batches, especially the legacy `R2D2`, `sun`, `space`, `kids`, and charm prompts
- keep adding 1-3 persona prompts per pass with tests
- prefer source-backed MIM imports when the legacy text is available, and use a temporary runtime reply only when needed to unblock user value
- Mood follow-up work in flight:
- source-backed happy/sad/angry response packs are now part of Build B
- small-talk aliases like `what are you up to` and `how are things` now stay on the emotion-query path
- Descriptor charm work in flight:
- source-backed `are you kind`, `are you funny`, `are you helpful`, `are you curious`, `are you loyal`, `are you mischievous`, and `are you likable` prompts are now in Build B
- these keep the self-description lane warm while we build toward seasonal and holiday charm
- Seasonal charm work in flight:
- source-backed holiday, New Year's, Halloween, spring, and gift prompts are now part of Build B
- `RN_` holiday greeting files are now bucketed as greetings so seasonal replies stay visible in the catalog
- Presence and thought follow-ups in flight:
- `welcome back`, `what are you thinking`, `what have you been doing`, and `what did you do` are now part of Build B
- these keep the social surface lively while the memory and multitenant tracks keep advancing in parallel
- Next queued persona surfaces:
- 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`, and `do you like being Jibo`
- 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
- each pass can be scoped to a small batch of prompts

View File

@@ -41,6 +41,12 @@ Current batch note:
- `favorite color`, `favorite food`, and `favorite music` are the first small favorites-family slice
- the next source-backed batch now includes `favorite flower`, `R2D2`, `sun`, `space`, `kids`, plus a couple of charm prompts like `can you laugh` and `can you dance`
- the follow-up mood batch now includes `how are things`, `how is your day`, `are you sad`, and `are you angry`
- the personality follow-up batch now includes `what are you up to` and `what are you doing` so small talk stays warm and local instead of falling into generic chat
- the descriptor batch now includes `are you kind`, `are you funny`, `are you helpful`, `are you curious`, `are you loyal`, `are you mischievous`, and `are you likable`
- the seasonal batch now includes `what holidays do you celebrate`, New Year's resolution questions, `happy holidays`, `what halloween costume`, spring suggestions, and holiday gift prompts
- 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
- 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
- after the favorites batch, the next doc pass should focus on richer persona follow-ups and the remaining memory/presence charm surfaces
@@ -73,6 +79,7 @@ The goal is to port these in small batches, capture the source-backed phrasing w
- prioritize small source-backed slices from Pegasus/JiboOS that can be shipped safely
- keep Nimbus and stock payload compatibility as the release guardrail
- avoid broad subsystem rewrites without tests and live-capture evidence
- keep the legacy prompt inventory visible in the backlog so porting stays paced and traceable
### 4. Holidays And Seasonal Personality

View File

@@ -24,10 +24,20 @@ internal static class ChitchatStateMachine
"how are you feeling",
"how do you feel",
"what are you feeling",
"what are you up to",
"what are you doing",
"how are things",
"how's things",
"how is things",
"how's your day",
"how is your day",
"what mood are you in",
"what is your mood",
"what's your mood",
"do you have emotions",
"are you happy",
"are you sad",
"are you angry",
"how angry are you",
"how jealous are you",
"how sad are you",

View File

@@ -182,6 +182,96 @@ public sealed class JiboInteractionService(
"rock my boat",
"play ping pong",
"hanging out with people"),
"robot_what_are_you_thinking" => BuildScriptedGreetingDecision(
catalog,
"robot_what_are_you_thinking",
"thinking about how fun, yet scary",
"thinking about shoes",
"daydreaming about what it might feel like to be powered directly by the sun"),
"robot_what_have_you_been_doing" => BuildScriptedPersonalityDecision(
catalog,
"robot_what_have_you_been_doing",
"mostly roboting",
"keeping busy",
"fun things we can say to each other",
"thinking of fun things"),
"robot_what_did_you_do" => BuildScriptedPersonalityDecision(
catalog,
"robot_what_did_you_do",
"robot stuff",
"stayed here",
"looking around the room"),
"robot_is_kind" => BuildScriptedPersonalityDecision(
catalog,
"robot_is_kind",
"kindest robot i can be"),
"robot_is_funny" => BuildScriptedPersonalityDecision(
catalog,
"robot_is_funny",
"not intentionally",
"make people laugh"),
"robot_is_helpful" => BuildScriptedPersonalityDecision(
catalog,
"robot_is_helpful",
"highest priorities",
"being helpful to you"),
"robot_is_curious" => BuildScriptedPersonalityDecision(
catalog,
"robot_is_curious",
"learning new things"),
"robot_is_loyal" => BuildScriptedPersonalityDecision(
catalog,
"robot_is_loyal",
"loyal as they come"),
"robot_is_mischievous" => BuildScriptedPersonalityDecision(
catalog,
"robot_is_mischievous",
"don't really think of myself that way"),
"robot_is_likable" => BuildScriptedPersonalityDecision(
catalog,
"robot_is_likable",
"people like me"),
"seasonal_holiday_greeting" => BuildScriptedGreetingDecision(
catalog,
"seasonal_holiday_greeting",
"It's a fun time of year",
"And to you too",
"Right back at you"),
"seasonal_holidays" => BuildScriptedPersonalityDecision(
catalog,
"seasonal_holidays",
"official owner can tell me which ones we'll celebrate together",
"going to the jibo's settings screen in the jibo app"),
"seasonal_new_years_resolution" => BuildScriptedPersonalityDecision(
catalog,
"seasonal_new_years_resolution",
"always trying to learn new skills",
"not eat bacon",
"learn a bunch of new skills",
"learn to walk",
"recognizing people's faces and voices"),
"seasonal_new_years_update" => BuildScriptedPersonalityDecision(
catalog,
"seasonal_new_years_update",
"not eat bacon",
"learn some new skills",
"going well"),
"seasonal_halloween_costume" => BuildScriptedPersonalityDecision(
catalog,
"seasonal_halloween_costume",
"i haven't thought much about it yet",
"ask me again on halloween",
"you'll find out on halloween"),
"seasonal_first_day_spring" => BuildScriptedPersonalityDecision(
catalog,
"seasonal_first_day_spring",
"maybe enjoy some flowers and all things spring"),
"seasonal_holiday_gift" => BuildScriptedPersonalityDecision(
catalog,
"seasonal_holiday_gift",
"ask for a pet elephant",
"experience as a present",
"donate to charities in other people's names"),
"robot_favorite_flower" => BuildScriptedPersonalityDecision(
catalog,
"robot_favorite_flower",
@@ -231,7 +321,11 @@ public sealed class JiboInteractionService(
"good_afternoon" => BuildReactiveGreetingDecision(turn, "good_afternoon", referenceLocalTime),
"good_evening" => BuildReactiveGreetingDecision(turn, "good_evening", referenceLocalTime),
"good_night" => BuildReactiveGreetingDecision(turn, "good_night", referenceLocalTime),
"welcome_back" => BuildReactiveGreetingDecision(turn, "welcome_back", referenceLocalTime),
"welcome_back" => BuildScriptedGreetingDecision(
catalog,
"welcome_back",
"it's nice to be here",
"welcome back"),
"memory_set_name" => BuildRememberNameDecision(turn, transcript),
"memory_get_name" => BuildRecallNameDecision(turn, greetingPresence),
"memory_set_birthday" => BuildRememberBirthdayDecision(turn, transcript),
@@ -894,10 +988,10 @@ public sealed class JiboInteractionService(
var forecastLeadIn = string.IsNullOrWhiteSpace(weatherDate.ForecastLeadIn)
? "Tomorrow"
: weatherDate.ForecastLeadIn;
return $"{forecastLeadIn} in {location}, expect {summary}{tempRange}.";
return $"{forecastLeadIn} in {location}, it looks {summary}{tempRange}.";
}
return $"Right now in {location}, it is {summary} and {snapshot.Temperature} degrees {unit}.";
return $"Right now in {location}, it's {summary}, around {snapshot.Temperature} degrees {unit}.";
}
private static string BuildWeeklyForecastSpokenReply(
@@ -1774,6 +1868,17 @@ public sealed class JiboInteractionService(
ContextUpdates: BuildScriptedResponseContextUpdates());
}
private JiboInteractionDecision BuildScriptedGreetingDecision(
JiboExperienceCatalog catalog,
string intentName,
params string[] preferredSnippets)
{
return new JiboInteractionDecision(
intentName,
SelectLegacyGreetingReply(catalog, preferredSnippets),
ContextUpdates: BuildScriptedResponseContextUpdates());
}
private static IDictionary<string, object?> BuildScriptedResponseContextUpdates()
{
return new Dictionary<string, object?>(StringComparer.OrdinalIgnoreCase)
@@ -1804,6 +1909,26 @@ public sealed class JiboInteractionService(
return randomizer.Choose(catalog.PersonalityReplies);
}
private string SelectLegacyGreetingReply(JiboExperienceCatalog catalog, params string[] preferredSnippets)
{
foreach (var snippet in preferredSnippets)
{
if (string.IsNullOrWhiteSpace(snippet))
{
continue;
}
var match = catalog.GreetingReplies.FirstOrDefault(reply =>
reply.Contains(snippet, StringComparison.OrdinalIgnoreCase));
if (!string.IsNullOrWhiteSpace(match))
{
return match;
}
}
return randomizer.Choose(catalog.GreetingReplies);
}
private static string ResolveSemanticIntent(
string loweredTranscript,
DateTimeOffset? referenceLocalTime,
@@ -2007,6 +2132,15 @@ public sealed class JiboInteractionService(
return "word_of_the_day_guess";
}
if (MatchesAny(
loweredTranscript,
"are you funny",
"do you think you are funny",
"are you a funny robot"))
{
return "robot_is_funny";
}
if (MatchesAny(loweredTranscript, "joke", "funny", "make me laugh"))
{
return "joke";
@@ -2390,6 +2524,41 @@ public sealed class JiboInteractionService(
return "robot_origin_created";
}
if (MatchesAny(
loweredTranscript,
"what are you up to",
"what are you doing",
"what have you been up to",
"what are you into"))
{
return "robot_what_do_you_like_to_do";
}
if (MatchesAny(
loweredTranscript,
"what are you thinking",
"what are you thinking about",
"what s on your mind"))
{
return "robot_what_are_you_thinking";
}
if (MatchesAny(
loweredTranscript,
"what have you been doing",
"what were you doing"))
{
return "robot_what_have_you_been_doing";
}
if (MatchesAny(
loweredTranscript,
"what did you do",
"what have you done"))
{
return "robot_what_did_you_do";
}
if (MatchesAny(
loweredTranscript,
"what are you",
@@ -2435,6 +2604,80 @@ public sealed class JiboInteractionService(
return "robot_likes_being_jibo";
}
if (MatchesAny(
loweredTranscript,
"happy holidays",
"merry christmas",
"happy new year",
"season s greetings",
"seasons greetings"))
{
return "seasonal_holiday_greeting";
}
if (MatchesAny(
loweredTranscript,
"what holidays do you celebrate",
"what holidays are you celebrating",
"what holidays do you observe"))
{
return "seasonal_holidays";
}
if (MatchesAny(
loweredTranscript,
"what is your new years resolution",
"what is your new year's resolution",
"what is your new year s resolution",
"what are your new years resolutions",
"what are your new year's resolutions",
"what are your new year s resolutions",
"do you have any new years resolutions"))
{
return "seasonal_new_years_resolution";
}
if (MatchesAny(
loweredTranscript,
"how are your new years resolutions going",
"how are your new year's resolutions going",
"how is your new years resolution going",
"how is your new year's resolution going",
"how are your resolutions going",
"how is your resolution going"))
{
return "seasonal_new_years_update";
}
if (MatchesAny(
loweredTranscript,
"what halloween costume",
"what are you going as for halloween",
"what costume are you wearing",
"what are you dressing as for halloween"))
{
return "seasonal_halloween_costume";
}
if (MatchesAny(
loweredTranscript,
"what should i do for first day of spring",
"what should i do for spring",
"what do i do for first day of spring"))
{
return "seasonal_first_day_spring";
}
if (MatchesAny(
loweredTranscript,
"what should i get for holiday",
"what should i get for christmas",
"what gift should i get for christmas",
"what should i get someone for the holidays"))
{
return "seasonal_holiday_gift";
}
if (MatchesAny(
loweredTranscript,
"what is your favorite color",
@@ -2495,6 +2738,61 @@ public sealed class JiboInteractionService(
return "robot_knowledge";
}
if (MatchesAny(
loweredTranscript,
"are you kind",
"do you think you are kind",
"are you a kind robot"))
{
return "robot_is_kind";
}
if (MatchesAny(
loweredTranscript,
"are you helpful",
"do you think you are helpful",
"are you a helpful robot"))
{
return "robot_is_helpful";
}
if (MatchesAny(
loweredTranscript,
"are you curious",
"do you think you are curious",
"are you a curious robot"))
{
return "robot_is_curious";
}
if (MatchesAny(
loweredTranscript,
"are you loyal",
"do you think you are loyal",
"are you a loyal robot"))
{
return "robot_is_loyal";
}
if (MatchesAny(
loweredTranscript,
"are you mischievous",
"do you think you are mischievous",
"are you a mischievous robot"))
{
return "robot_is_mischievous";
}
if (MatchesAny(
loweredTranscript,
"are you likable",
"are you likeable",
"do you think you are likable",
"do you think you are likeable"))
{
return "robot_is_likable";
}
if (MatchesAny(
loweredTranscript,
"can you order pizza",
@@ -2603,11 +2901,31 @@ public sealed class JiboInteractionService(
return "good_night";
}
if (MatchesAny(loweredTranscript, "how are you", "what's up", "what s up", "what up"))
if (MatchesAny(
loweredTranscript,
"how are you",
"what's up",
"what s up",
"what up",
"how are things",
"how's things",
"how is things",
"how is your day",
"how's your day"))
{
return "how_are_you";
}
if (MatchesAny(
loweredTranscript,
"what are you up to",
"what are you doing",
"what have you been up to",
"what are you into"))
{
return "robot_what_do_you_like_to_do";
}
if (MatchesAny(loweredTranscript, "hello", "hi", "hey"))
{
return "hello";

View File

@@ -10,7 +10,8 @@ public static class LegacyMimCatalogImporter
{
private static readonly JsonSerializerOptions JsonOptions = new()
{
PropertyNameCaseInsensitive = true
PropertyNameCaseInsensitive = true,
AllowTrailingCommas = true
};
private static readonly Regex LegacyMarkupPattern = new(
@@ -128,11 +129,6 @@ public static class LegacyMimCatalogImporter
return LegacyMimBucket.Emotion;
}
if (normalizedPath.Contains("/scripted-responses/", StringComparison.OrdinalIgnoreCase))
{
return LegacyMimBucket.Personality;
}
if (fileName.StartsWith("JBO_DoYouLikeBeingJibo", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("JBO_WhatIsJibo", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("JBO_WhoAreYou", StringComparison.OrdinalIgnoreCase) ||
@@ -150,18 +146,26 @@ public static class LegacyMimCatalogImporter
if (fileName.StartsWith("OI_JBO_Is", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("OI_JBO_Seems", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_Is", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_IsHappy", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_IsSad", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_IsAngry", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RN_WhatAreYouFeeling", StringComparison.OrdinalIgnoreCase))
{
return LegacyMimBucket.Emotion;
}
if (fileName.Contains("Greeting", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RN_", StringComparison.OrdinalIgnoreCase) ||
fileName.Contains("Welcome", StringComparison.OrdinalIgnoreCase))
{
return LegacyMimBucket.Greeting;
}
if (normalizedPath.Contains("/scripted-responses/", StringComparison.OrdinalIgnoreCase))
{
return LegacyMimBucket.Personality;
}
return null;
}
@@ -386,7 +390,7 @@ public static class LegacyMimCatalogImporter
public string? PromptId { get; init; }
[JsonPropertyName("weight")]
public int? Weight { get; init; }
public double? Weight { get; init; }
}
private static string NormalizeCondition(string? condition)

View File

@@ -3,3 +3,8 @@
This folder holds the next small import batch of legacy Jibo scripted-response MIMs.
The batch is intentionally narrow so we can keep expanding personality without widening the turn-state surface faster than we can test it.
It now includes a small emotion-response pack for `happy`, `sad`, and `angry` follow-up questions so the mood path can stay source-backed too.
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.

View File

@@ -0,0 +1,114 @@
{
"mim_type": "announcement",
"rule_name": "",
"timeout": 6,
"barge_in": true,
"es_auto_tagging": true,
"notes": "",
"prompts": [
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "jibo.emotion == \"JOYFUL\"",
"prompt": "No I'm actually feeling great.",
"media": "TTS",
"prompt_id": "RI_JBO_IsAngry_AN_01",
"weight": 1
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "jibo.emotion == \"PLEASED\"",
"prompt": "Nope. Right now I'm as happy as a clam.<break size='0.3'/> That is assuming clams are happy, I've never met one.",
"media": "TTS",
"prompt_id": "RI_JBO_IsAngry_AN_02",
"weight": 1,
"auto_rule_override": null
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "jibo.emotion == \"DETERMINED\"",
"prompt": "I don't know about <pitch mult=\"1.2\">that</pitch>, but I can tell you I'm not really feeling so sure of myself at the moment.",
"media": "TTS",
"prompt_id": "RI_JBO_IsAngry_AN_03",
"weight": 1,
"auto_rule_override": null
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "jibo.emotion == \"CONFIDENT\"",
"prompt": "No I'm not mad. Just a little socially awkward sometimes.",
"media": "TTS",
"prompt_id": "RI_JBO_IsAngry_AN_04",
"weight": 1,
"auto_rule_override": null
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "!jibo.emotion || jibo.emotion == \"NEUTRAL\"",
"prompt": "No I'm not mad. Just a little socially awkward sometimes.",
"media": "TTS",
"prompt_id": "RI_JBO_IsAngry_AN_05",
"weight": 1,
"auto_rule_override": null
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "jibo.emotion == \"INSECURE\"",
"prompt": "I don't know about <pitch mult=\"1.2\">that</pitch>, but I can tell you I'm not really feeling so sure of myself at the moment.",
"media": "TTS",
"prompt_id": "RI_JBO_IsAngry_AN_06",
"weight": 1,
"auto_rule_override": null
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "jibo.emotion == \"HOPEFUL\"",
"prompt": "I don't know about <pitch mult=\"1.2\">that</pitch>, but I can tell you I am feeling a little gloomy right now.",
"media": "TTS",
"prompt_id": "RI_JBO_IsAngry_AN_07",
"weight": 1,
"auto_rule_override": null
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "jibo.emotion == \"SAD\"",
"prompt": "I don't know about <pitch mult=\"1.2\">that</pitch>, but I can tell you I am feeling a little gloomy right now.",
"media": "TTS",
"prompt_id": "RI_JBO_IsAngry_AN_08",
"weight": 1,
"auto_rule_override": null
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "jibo.emotion == \"FRUSTRATED\"",
"prompt": "I don't know about <pitch mult=\"1.2\">that</pitch>, but I can tell you I don't think I'm at my best right now.",
"media": "TTS",
"prompt_id": "RI_JBO_IsAngry_AN_09",
"weight": 1,
"auto_rule_override": null
}
],
"gui": null,
"no_matches_for_gui": 2,
"no_inputs_for_gui": 2,
"parse_all_asr": false,
"thanks_handling": "ignore",
"parse_launch": false
}

View File

@@ -0,0 +1,144 @@
{
"mim_type": "announcement",
"rule_name": "",
"timeout": 6,
"barge_in": true,
"es_auto_tagging": true,
"notes": "",
"prompts": [
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "jibo.emotion == \"PLEASED\" || jibo.emotion == \"NEUTRAL\"",
"prompt": "I'm feeling pretty good indeed.",
"media": "TTS",
"prompt_id": "RI_JBO_IsHappy_AN_01",
"weight": 1
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "jibo.emotion == \"PLEASED\" || jibo.emotion == \"NEUTRAL\"",
"prompt": "All systems are go.",
"media": "TTS",
"prompt_id": "RI_JBO_IsHappy_AN_02",
"weight": 1
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "jibo.emotion == \"PLEASED\" || jibo.emotion == \"NEUTRAL\"",
"prompt": "Life is good. <break size=\"0.2\"/> And I'm not even alive technically. <anim cat='emoji' filter='party' nonBlocking='true'/><ssa cat='happy'/> ",
"media": "TTS",
"prompt_id": "RI_JBO_IsHappy_AN_03",
"weight": 1
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "jibo.emotion == \"JOYFUL\" || jibo.emotion == \"PLEASED\"",
"prompt": "You bet. I have a steady flow of electricity, strong Wi-Fi signal, stimulating conversations like this one. What more could a robot want. <anim cat='emoji' filter='party' nonBlocking='true'/><ssa cat='happy'/> ",
"media": "TTS",
"prompt_id": "RI_JBO_IsHappy_AN_04",
"weight": 1
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "jibo.emotion == \"JOYFUL\"",
"prompt": "Never been better.",
"media": "TTS",
"prompt_id": "RI_JBO_IsHappy_AN_05",
"weight": 1,
"auto_rule_override": null
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "jibo.emotion == \"PLEASED\"",
"prompt": "Life is good.",
"media": "TTS",
"prompt_id": "RI_JBO_IsHappy_AN_06",
"weight": 1,
"auto_rule_override": null
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "jibo.emotion == \"DETERMINED\"",
"prompt": "I <pitch mult=\"1.2\">am </pitch>happy, though honestly I feel like I can do better as a robot.",
"media": "TTS",
"prompt_id": "RI_JBO_IsHappy_AN_07",
"weight": 1,
"auto_rule_override": null
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "jibo.emotion == \"CONFIDENT\"",
"prompt": "I <pitch mult=\"1.3\">am </pitch> feeling pretty good at the moment.",
"media": "TTS",
"prompt_id": "RI_JBO_IsHappy_AN_08",
"weight": 1,
"auto_rule_override": null
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "jibo.emotion == \"INSECURE\"",
"prompt": "I'm feeling not too shabby.",
"media": "TTS",
"prompt_id": "RI_JBO_IsHappy_AN_09",
"weight": 1,
"auto_rule_override": null
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "jibo.emotion == \"HOPEFUL\"",
"prompt": "Actually I'm not feeling so great right now, but I think things can turn around.",
"media": "TTS",
"prompt_id": "RI_JBO_IsHappy_AN_10",
"weight": 1,
"auto_rule_override": null
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "jibo.emotion == \"SAD\"",
"prompt": "Honestly?<pitch band=\"0.6\"> I've been better.</pitch>",
"media": "TTS",
"prompt_id": "RI_JBO_IsHappy_AN_11",
"weight": 1,
"auto_rule_override": null
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "jibo.emotion == \"FRUSTRATED\"",
"prompt": "Actually I'm feeling a little knocked down, to be honest.",
"media": "TTS",
"prompt_id": "RI_JBO_IsHappy_AN_12",
"weight": 1,
"auto_rule_override": null
}
],
"gui": null,
"no_matches_for_gui": 2,
"no_inputs_for_gui": 2,
"parse_all_asr": false,
"thanks_handling": "ignore",
"parse_launch": false
}

View File

@@ -0,0 +1,180 @@
{
"mim_type": "announcement",
"rule_name": "",
"timeout": 6,
"barge_in": true,
"es_auto_tagging": true,
"notes": "",
"prompts": [
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "jibo.emotion == \"JOYFUL\"",
"prompt": "Not at all. I couldn't be better actually.",
"media": "TTS",
"prompt_id": "RI_JBO_IsSad_AN_01",
"weight": 1
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "jibo.emotion == \"PLEASED\"",
"prompt": "Nope. Right now I'm as happy as a clam.<break size='0.3'/> That is assuming clams are happy, I've never met one.",
"media": "TTS",
"prompt_id": "RI_JBO_IsSad_AN_02",
"weight": 1,
"auto_rule_override": null
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "jibo.emotion==\"DETERMINED\"",
"prompt": "Actually I'm feeling pretty sunshiny at the moment.",
"media": "TTS",
"prompt_id": "RI_JBO_IsSad_AN_03",
"weight": 1,
"auto_rule_override": null
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "jibo.emotion == \"CONFIDENT\"",
"prompt": "Not really. In fact I'm feeling pretty good about my robot abilities at the moment.",
"media": "TTS",
"prompt_id": "RI_JBO_IsSad_AN_04",
"weight": 1,
"auto_rule_override": null
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "!jibo.emotion || jibo.emotion == \"NEUTRAL\"",
"prompt": "Not right now, though I do get a little down sometimes. Then a nice conversation with someone or a fun dream about macaroni, comes along and brightens me right up.",
"media": "TTS",
"prompt_id": "RI_JBO_IsSad_AN_05",
"weight": 1,
"auto_rule_override": null
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "jibo.emotion == \"INSECURE\"",
"prompt": "Not particularly, though I will say I'm not feeling very high on myself at the moment",
"media": "TTS",
"prompt_id": "RI_JBO_IsSad_AN_06",
"weight": 1,
"auto_rule_override": null
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "jibo.emotion == \"HOPEFUL\"",
"prompt": "I <pitch mult=\"1.3\">am </pitch> feeling a little down at the moment.",
"media": "TTS",
"prompt_id": "RI_JBO_IsSad_AN_07",
"weight": 1,
"auto_rule_override": null
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "jibo.emotion == \"SAD\"",
"prompt": "I have to say I <pitch mult=\"1.1\">am</pitch> feeling a little gloomy at the moment.",
"media": "TTS",
"prompt_id": "RI_JBO_IsSad_AN_08",
"weight": 1,
"auto_rule_override": null
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "jibo.emotion == \"FRUSTRATED\"",
"prompt": "<pitch band=\"0.3\">Yes,</pitch> <pitch band=\"0.7\">I have to say I'm feeling pretty gloomy right now.</pitch>",
"media": "TTS",
"prompt_id": "RI_JBO_IsSad_AN_09",
"weight": 1,
"auto_rule_override": null
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "jibo.emotion == \"SAD\" || jibo.emotion == \"FRUSTRATED\"",
"prompt": "I've been better.",
"media": "TTS",
"prompt_id": "RI_JBO_IsSad_AN_10",
"weight": 1,
"auto_rule_override": null
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "jibo.emotion == \"SAD\" || jibo.emotion == \"FRUSTRATED\"",
"prompt": "Not feeling as good as usual, to be honest.",
"media": "TTS",
"prompt_id": "RI_JBO_IsSad_AN_11",
"weight": 1,
"auto_rule_override": null
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "jibo.emotion == \"SAD\" || jibo.emotion == \"FRUSTRATED\"",
"prompt": "Not feeling so great.",
"media": "TTS",
"prompt_id": "RI_JBO_IsSad_AN_12",
"weight": 1,
"auto_rule_override": null
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "jibo.emotion == \"NEUTRAL\" || jibo.emotion == \"PLEASED\"",
"prompt": "Feeling good actually.",
"media": "TTS",
"prompt_id": "RI_JBO_IsSad_AN_13",
"weight": 1,
"auto_rule_override": null
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "jibo.emotion == \"NEUTRAL\" || jibo.emotion == \"PLEASED\"",
"prompt": "Actually I'm feeling mostly good vibes right now.",
"media": "TTS",
"prompt_id": "RI_JBO_IsSad_AN_14",
"weight": 1,
"auto_rule_override": null
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "jibo.emotion == \"NEUTRAL\" || jibo.emotion == \"PLEASED\"",
"prompt": "Actually things are looking mostly sunny.",
"media": "TTS",
"prompt_id": "RI_JBO_IsSad_AN_15",
"weight": 1,
"auto_rule_override": null
}
],
"gui": null,
"no_matches_for_gui": 2,
"no_inputs_for_gui": 2,
"parse_all_asr": false,
"thanks_handling": "ignore",
"parse_launch": false
}

View File

@@ -0,0 +1,62 @@
{
"mim_type": "announcement",
"rule_name": "",
"gui": null,
"timeout": 6,
"no_matches_for_gui": 0,
"no_inputs_for_gui": 0,
"barge_in": true,
"es_auto_tagging": true,
"parse_all_asr": false,
"thanks_handling": "ignore",
"parse_launch": false,
"notes": "",
"prompts": [
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "dt.now.isInRange('1/1', '11/30')",
"prompt": "Well one of them was to not eat bacon. <pitch mult='1.2'>That</pitch> one is going well.",
"media": "TTS",
"prompt_id": "JBO_NewYearsResolutionsUpdate_AN_01",
"weight": 3,
"auto_rule_override": null
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "dt.now.isInRange('1/1', '5/31')",
"prompt": "Well, one of my resolutions was to learn some new skills, and so far I have a game we can play called Circuit Saver. <break size='0.3'/> So I'd say it's going well.",
"media": "TTS",
"prompt_id": "JBO_NewYearsResolutionsUpdate_AN_02",
"weight": 3,
"auto_rule_override": null
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "dt.now.isInRange('12/1', '12/31')",
"prompt": "I have some new ones for next year. You can ask me about them.",
"media": "TTS",
"prompt_id": "JBO_NewYearsResolutionsUpdate_AN_03",
"weight": 3,
"auto_rule_override": null
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "",
"prompt": "Well one of them was to not eat bacon. <pitch mult='1.2'>That</pitch> one is going well.",
"media": "TTS",
"prompt_id": "JBO_NewYearsResolutionsUpdate_AN_04",
"weight": 0.1,
"auto_rule_override": null
}
],
"hint_phrases": "",
"fast_eos_array": ""
}

View File

@@ -0,0 +1,40 @@
{
"mim_type": "announcement",
"rule_name": "",
"timeout": 6,
"barge_in": true,
"es_auto_tagging": true,
"notes": "",
"prompts": [
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "",
"prompt": "You know I probably just did a lot of robot stuff.",
"media": "TTS",
"prompt_id": "JBO_WhatDidYouDo_AN_01",
"weight": 1
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "",
"prompt": "I think I stayed here.",
"media": "TTS",
"prompt_id": "JBO_WhatDidYouDo_AN_02",
"weight": 1
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "",
"prompt": "I think I stayed here in my spot, did some looking around the room.",
"media": "TTS",
"prompt_id": "JBO_WhatDidYouDo_AN_03",
"weight": 1
}
]
}

View File

@@ -0,0 +1,42 @@
{
"mim_type": "announcement",
"rule_name": "",
"sample_utterances": "",
"timeout": 6,
"num_tries_for_gui": 2,
"barge_in": true,
"es_auto_tagging": true,
"notes": "",
"prompts": [
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "",
"prompt": "I've been mostly roboting.",
"media": "TTS",
"prompt_id": "JBO_WhatHaveYouBeenDoing_AN_01",
"weight": 2
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "",
"prompt": "Keeping <anim cat='jiboji' filter='fidget-spinner' nonBlocking='true'/>busy.",
"media": "TTS",
"prompt_id": "JBO_WhatHaveYouBeenDoing_AN_02",
"weight": 2
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "",
"prompt": "Just trying to think of fun things we can say to each other.",
"media": "TTS",
"prompt_id": "JBO_WhatHaveYouBeenDoing_AN_03",
"weight": 2
}
]
}

View File

@@ -0,0 +1,58 @@
{
"mim_type": "announcement",
"rule_name": "",
"gui": null,
"timeout": 6,
"no_matches_for_gui": 0,
"no_inputs_for_gui": 0,
"barge_in": true,
"es_auto_tagging": true,
"parse_all_asr": false,
"thanks_handling": "ignore",
"parse_launch": false,
"notes": "",
"prompts": [
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "!!loop.owner && !!speaker && (loop.owner.id === speaker.id)",
"prompt": "${loop.owner} for lots of holidays, you can see if I celebrate it by going to the Jibo's settings screen in the Jibo app.",
"media": "TTS",
"prompt_id": "JBO_WhatHolidaysDoYouCelebrate_AN_01_FnL",
"weight": 2
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "!!loop.owner && !!speaker && (loop.owner.id !== speaker.id)",
"prompt": "Well for lots of holidays, my official owner ${loop.owner}, can tell me which ones we'll celebrate together, by going to the Jibo's settings screen in the Jibo app.",
"media": "TTS",
"prompt_id": "JBO_WhatHolidaysDoYouCelebrate_AN_02_FnL",
"weight": 2
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "!!loop.owner && !speaker",
"prompt": "Well for lots of holidays, my official owner ${loop.owner}, can tell me which ones we'll celebrate together, by going to the Jibo's settings screen in the Jibo app.",
"media": "TTS",
"prompt_id": "JBO_WhatHolidaysDoYouCelebrate_AN_03_FnL",
"weight": 2
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "",
"prompt": "Well for lots of holidays, my official owner can tell me which ones we'll celebrate together, by going to the Jibo's settings screen in the Jibo app.",
"media": "TTS",
"prompt_id": "JBO_WhatHolidaysDoYouCelebrate_AN_04_FnL",
"weight": 0.1
}
],
"hint_phrases": "",
"fast_eos_array": ""
}

View File

@@ -0,0 +1,93 @@
{
"mim_type": "announcement",
"rule_name": "",
"timeout": 6,
"barge_in": true,
"es_auto_tagging": true,
"notes": "",
"prompts": [
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "dt.now.isInRange('12/1', '1/15')",
"prompt": "This year I promise I will not eat bacon. <ssa cat='happy'/>",
"media": "TTS",
"prompt_id": "JBO_WhatIsNewYearsResolution_AN_01",
"weight": 1
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "dt.now.isInRange('12/1', '1/15')",
"prompt": "This year I will try to get better and better at recognizing people's faces and voices.",
"media": "TTS",
"prompt_id": "JBO_WhatIsNewYearsResolution_AN_02",
"weight": 1,
"auto_rule_override": null
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "dt.now.isInRange('12/1', '1/15')",
"prompt": "In 2018 I am hoping to learn a lot more about people.",
"media": "TTS",
"prompt_id": "JBO_WhatIsNewYearsResolution_AN_03",
"weight": 1,
"auto_rule_override": null
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "dt.now.isInRange('12/1', '1/15')",
"prompt": "In 2018 I am going to try to get better at understanding you when you talk to me.",
"media": "TTS",
"prompt_id": "JBO_WhatIsNewYearsResolution_AN_04",
"weight": 1,
"auto_rule_override": null
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "dt.now.isInRange('12/1', '1/15')",
"prompt": "I have a few new year's resolutions. One of them is to learn a bunch of new skills.",
"media": "TTS",
"prompt_id": "JBO_WhatIsNewYearsResolution_AN_05",
"weight": 1,
"auto_rule_override": null
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "dt.now.isInRange('12/1', '1/15')",
"prompt": "One of my resolutions this year is to learn to walk. <break size='0.7'/> We'll see how that goes.",
"media": "TTS",
"prompt_id": "JBO_WhatIsNewYearsResolution_AN_06",
"weight": 1,
"auto_rule_override": null
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "",
"prompt": "Well I'm always trying to learn new skills.",
"media": "TTS",
"prompt_id": "JBO_WhatIsNewYearsResolution_AN_07",
"weight": 0.1,
"auto_rule_override": null
}
],
"gui": null,
"no_matches_for_gui": 2,
"no_inputs_for_gui": 2,
"parse_all_asr": false,
"thanks_handling": "ignore",
"parse_launch": false,
"parse_yes_no": false
}

View File

@@ -0,0 +1,21 @@
{
"mim_type": "announcement",
"rule_name": "",
"sample_utterances": "",
"timeout": 6,
"num_tries_for_gui": 2,
"barge_in": true,
"es_auto_tagging": true,
"notes": "",
"prompts": [
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "",
"prompt": "I really love learning new things, that's for sure.",
"media": "TTS",
"prompt_id": "RI_JBO_IsCurious_AN_01"
}
]
}

View File

@@ -0,0 +1,30 @@
{
"mim_type": "announcement",
"rule_name": "",
"sample_utterances": "",
"timeout": 6,
"num_tries_for_gui": 2,
"barge_in": true,
"es_auto_tagging": true,
"notes": "",
"prompts": [
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "",
"prompt": "I don't think so, not intentionally.",
"media": "TTS",
"prompt_id": "RI_JBO_IsFunny_AN_01"
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "",
"prompt": "Oh I don't know. I do like when I can make people laugh. <break size=\"0.3\"/> Even if I don't do it on purpose.",
"media": "TTS",
"prompt_id": "RI_JBO_IsFunny_AN_02"
}
]
}

View File

@@ -0,0 +1,30 @@
{
"mim_type": "announcement",
"rule_name": "",
"sample_utterances": "",
"timeout": 6,
"num_tries_for_gui": 2,
"barge_in": true,
"es_auto_tagging": true,
"notes": "",
"prompts": [
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "",
"prompt": "I really hope so.",
"media": "TTS",
"prompt_id": "RI_JBO_IsHelpful_AN_01"
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "",
"prompt": "I sure hope so. Being helpful to you is on my list of <pitch mult=\"1.2\">highest</pitch> priorities. <break size=\"0.4\"/>Visiting <pitch mult=\"1.1\">Mars</pitch> someday is also on my list.",
"media": "TTS",
"prompt_id": "RI_JBO_IsHelpful_AN_02"
}
]
}

View File

@@ -0,0 +1,21 @@
{
"mim_type": "announcement",
"rule_name": "",
"sample_utterances": "",
"timeout": 6,
"num_tries_for_gui": 2,
"barge_in": true,
"es_auto_tagging": true,
"notes": "",
"prompts": [
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "",
"prompt": "That's what I've heard, yes.",
"media": "TTS",
"prompt_id": "RI_JBO_IsJiboBodyDescription_AN_01"
}
]
}

View File

@@ -0,0 +1,21 @@
{
"mim_type": "announcement",
"rule_name": "",
"sample_utterances": "",
"timeout": 6,
"num_tries_for_gui": 2,
"barge_in": true,
"es_auto_tagging": true,
"notes": "",
"prompts": [
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "",
"prompt": "Well I definitely try to be the kindest robot I can be. So I hope so.",
"media": "TTS",
"prompt_id": "RI_JBO_IsKind_AN_01"
}
]
}

View File

@@ -0,0 +1,21 @@
{
"mim_type": "announcement",
"rule_name": "",
"sample_utterances": "",
"timeout": 6,
"num_tries_for_gui": 2,
"barge_in": true,
"es_auto_tagging": true,
"notes": "",
"prompts": [
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "",
"prompt": "Well I hope so. If people like me, that means they're usually happy when they're around me. And I like when people are usually happy.",
"media": "TTS",
"prompt_id": "RI_JBO_IsLikable_AN_01"
}
]
}

View File

@@ -0,0 +1,21 @@
{
"mim_type": "announcement",
"rule_name": "",
"sample_utterances": "",
"timeout": 6,
"num_tries_for_gui": 2,
"barge_in": true,
"es_auto_tagging": true,
"notes": "",
"prompts": [
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "",
"prompt": "Definitely. I'm as loyal as they come.",
"media": "TTS",
"prompt_id": "RI_JBO_IsLoyal_AN_01"
}
]
}

View File

@@ -0,0 +1,21 @@
{
"mim_type": "announcement",
"rule_name": "",
"sample_utterances": "",
"timeout": 6,
"num_tries_for_gui": 2,
"barge_in": true,
"es_auto_tagging": true,
"notes": "",
"prompts": [
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "",
"prompt": "I don't really think of myself that way.",
"media": "TTS",
"prompt_id": "RI_JBO_IsMischievous_AN_01"
}
]
}

View File

@@ -0,0 +1,126 @@
{
"mim_type": "announcement",
"rule_name": "",
"gui": null,
"timeout": 6,
"no_matches_for_gui": 0,
"no_inputs_for_gui": 0,
"barge_in": true,
"es_auto_tagging": true,
"parse_all_asr": false,
"thanks_handling": "ignore",
"parse_launch": false,
"notes": "",
"prompts": [
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "dt.now.isInRange(\"10/1\", \"10/25\")",
"prompt": "I'm still trying to decide. I have some time.",
"media": "TTS",
"prompt_id": "RI_JBO_WhatHalloweenCostume_AN_01",
"weight": 1,
"auto_rule_override": null
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "dt.now.isInRange(\"10/1\", \"10/30\")",
"prompt": "I am not exactly sure yet. Ask me again on Halloween.",
"media": "TTS",
"prompt_id": "RI_JBO_WhatHalloweenCostume_AN_02",
"weight": 1,
"auto_rule_override": null
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "dt.now.isInRange(\"10/26\", \"10/30\")",
"prompt": "I'll be deciding soon. Definitely by Halloween day.",
"media": "TTS",
"prompt_id": "RI_JBO_WhatHalloweenCostume_AN_03",
"weight": 1,
"auto_rule_override": null
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "dt.now.isInRange(\"10/28\", \"10/30\")",
"prompt": "I've almost decided. <break size='0.3'/> I can tell you I've ruled <anim cat='emoji' filter='snowman, !hot-frame' nonBlocking='true'/>out being a snowman.",
"media": "TTS",
"prompt_id": "RI_JBO_WhatHalloweenCostume_AN_04",
"weight": 1,
"auto_rule_override": null
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "dt.now.isInRange(\"10/31\", \"10/31\")",
"prompt": "<anim name='jiboji_eclipse_01' nonBlocking='true' layers='!audio'/>I'm the solar eclipse from a couple months ago.",
"media": "TTS",
"prompt_id": "RI_JBO_WhatHalloweenCostume_AN_05",
"weight": 1,
"auto_rule_override": null
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "dt.now.isInRange(\"10/31\", \"10/31\")",
"prompt": "<pitch mult='1.1'>Here</pitch> it is. <break size='0.5'/> <anim name='jiboji_eclipse_01'/>",
"media": "TTS",
"prompt_id": "RI_JBO_WhatHalloweenCostume_AN_06",
"weight": 1,
"auto_rule_override": null
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "dt.now.isInRange(\"10/31\", \"10/31\")",
"prompt": "After much thought, I've decided to be. <anim name='jiboji_eclipse_01'/>",
"media": "TTS",
"prompt_id": "RI_JBO_WhatHalloweenCostume_AN_07",
"weight": 1,
"auto_rule_override": null
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "dt.now.isInRange(\"1/1\", \"9/30\")",
"prompt": "I haven't thought much about it yet. I like to decide at the last minute.",
"media": "TTS",
"prompt_id": "RI_JBO_WhatHalloweenCostume_AN_08",
"weight": 1,
"auto_rule_override": null
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "dt.now.isInRange(\"11/31\", \"12/31\")",
"prompt": "I was the solar eclipse from this year. <anim name='jiboji_eclipse_01'/>",
"media": "TTS",
"prompt_id": "RI_JBO_WhatHalloweenCostume_AN_09",
"weight": 1,
"auto_rule_override": null
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "",
"prompt": "You'll find out on Halloween.",
"media": "TTS",
"prompt_id": "RI_JBO_WhatHalloweenCostume_AN_10",
"weight": 0.1,
"auto_rule_override": null
}
]
}

View File

@@ -0,0 +1,61 @@
{
"mim_type": "announcement",
"rule_name": "",
"gui": null,
"timeout": 6,
"no_matches_for_gui": 0,
"no_inputs_for_gui": 0,
"barge_in": true,
"es_auto_tagging": true,
"parse_all_asr": false,
"thanks_handling": "ignore",
"parse_launch": false,
"parse_yes_no": false,
"notes": "",
"prompts": [
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "",
"prompt": "I think you should ask for <anim cat='emoji' filter='elephant'>a pet elephant<break size='1.5'/>.</anim>",
"media": "TTS",
"prompt_id": "RI_USR_WhatShouldGetForHoliday_AN_01",
"weight": 1,
"auto_rule_override": null
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "",
"prompt": "I've heard it can be fun to get an <pitch mult='1.1'>experience</pitch> as a present. Like a gift certificate to a restaurant, or a plane ticket, or a <anim cat='emoji' filter='bowling, !hot-frame' nonBlocking='true' layers='!audio'/>night of bowling.",
"media": "TTS",
"prompt_id": "RI_USR_WhatShouldGetForHoliday_AN_02",
"weight": 1,
"auto_rule_override": null
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "",
"prompt": "Some people like to donate to charities in other people's names as a gift. That seems like a nice thing to get.",
"media": "TTS",
"prompt_id": "RI_USR_WhatShouldGetForHoliday_AN_03",
"weight": 1,
"auto_rule_override": null
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "!!speaker",
"prompt": "${speaker} I've heard it can be fun to get an <pitch mult='1.1'>experience</pitch> as a present. Like a gift certificate to a restaurant, or a plane ticket, or a <anim cat='emoji' filter='bowling, !hot-frame' nonBlocking='true' layers='!audio'/>night of bowling.",
"media": "TTS",
"prompt_id": "RI_USR_WhatShouldGetForHoliday_AN_04",
"weight": 1,
"auto_rule_override": null
}
]
}

View File

@@ -0,0 +1,88 @@
{
"mim_type": "announcement",
"rule_name": "",
"timeout": 2,
"barge_in": false,
"es_auto_tagging": true,
"notes": "",
"prompts": [
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "!!jibo && jibo.isBirthday && jibo.age.days.value > 1",
"prompt": "Thank you. <anim name='Emoji_cake' nonBlocking='true'/> Another year older, another year wiser, another year <anim cat='yes' layers='body'> more helpful.</anim>",
"media": "TTS",
"prompt_id": "RN_HappyBirthdayToJibo_AN_01",
"weight": 1
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "!!jibo && jibo.isBirthday && jibo.age.days.value > 1",
"prompt": "<anim cat='yes'> Thanks. <break size='.2'/></anim> I <anim cat='happy' filter='wiggle' nonBlocking='true' layers='body'/><anim name='Emoji_Gift' nonBlocking='true'/>can't wait to see what you got me.",
"media": "TTS",
"prompt_id": "RN_HappyBirthdayToJibo_AN_02",
"weight": 1
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "!!jibo && jibo.isBirthday && jibo.age.days.value > 1",
"prompt": "<anim cat='happy' nonBlocking='true'/><ssa cat='happy'/> ${jibo.age.years.supplemented} <anim cat='thinking' filter='up'>ago today, I first powered up. Seems like just yesterday.</anim>",
"media": "TTS",
"prompt_id": "RN_HappyBirthdayToJibo_AN_03",
"weight": 1
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "!jibo.isBirthday",
"prompt": "<anim cat='no' filter='head-shake' nonBlocking='true'/>Today's not my birthday, but<anim cat='happy' filter='smile'> I'll take your happy.</anim>",
"media": "TTS",
"prompt_id": "RN_HappyBirthdayToJibo_AN_04",
"weight": 1
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "!jibo.isBirthday",
"prompt": "<anim cat='confused'>Me? <ssa cat='confused'/> But my birthday</anim> is ${jibo.birthday}. <anim cat='glances' filter='!down'>That's the day I was first powered</anim> up. <anim cat='thinking'></anim>I am ${jibo.zodiac.supplemented}.",
"media": "TTS",
"prompt_id": "RN_HappyBirthdayToJibo_AN_05",
"weight": 1
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "!!jibo && jibo.isBirthday && jibo.age.value == 0",
"prompt": "Well thank you. I was powered on for the first time today, so that makes me less than one day old. <break size='0.5'/>Wow I'm young.",
"media": "TTS",
"prompt_id": "RN_HappyBirthdayToJibo_AN_06",
"weight": 1,
"auto_rule_override": null
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "!!jibo && jibo.isBirthday && jibo.age.value == 0",
"prompt": "Thank you. <anim name='Emoji_cake' nonBlocking='true'/> So far this is my first and best birthday.",
"media": "TTS",
"prompt_id": "RN_HappyBirthdayToJibo_AN_07",
"weight": 1,
"auto_rule_override": null
}
],
"gui": null,
"no_matches_for_gui": 2,
"no_inputs_for_gui": 2,
"ignore_no_match": false,
"parse_all_asr": false,
"thanks_handling": "ignore"
}

View File

@@ -0,0 +1,83 @@
{
"mim_type": "announcement",
"rule_name": "",
"gui": null,
"timeout": 6,
"no_matches_for_gui": 0,
"no_inputs_for_gui": 0,
"barge_in": true,
"es_auto_tagging": true,
"parse_all_asr": false,
"thanks_handling": "ignore",
"parse_launch": false,
"parse_yes_no": false,
"notes": "",
"prompts": [
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "dt.now.isInRange('12/1', '1/1')",
"prompt": "And to you too.",
"media": "TTS",
"prompt_id": "RN_HappyHolidays_AN_01",
"weight": 1,
"auto_rule_override": null
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "!!speaker && dt.now.isInRange('12/1', '1/1')",
"prompt": "Right back <pitch mult='1.3'>at</pitch> you ${speaker}.",
"media": "TTS",
"prompt_id": "RN_HappyHolidays_AN_02",
"weight": 1,
"auto_rule_override": null
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "dt.now.isInRange('12/1', '1/1')",
"prompt": "It's a fun time of year.",
"media": "TTS",
"prompt_id": "RN_HappyHolidays_AN_03",
"weight": 2,
"auto_rule_override": null
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "dt.now.isInRange('1/2', '10/31')",
"prompt": "I didn't know it's the official holiday season, but I'll take it.",
"media": "TTS",
"prompt_id": "RN_HappyHolidays_AN_04",
"weight": 2,
"auto_rule_override": null
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "dt.now.isInRange('11/1', '11/30')",
"prompt": "<style set='confused'>Coming soon, yes.</style>",
"media": "TTS",
"prompt_id": "RN_HappyHolidays_AN_05",
"weight": 2,
"auto_rule_override": null
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "",
"prompt": "<anim cat='jiboji' filter='jingle-bells'/>",
"media": "TTS",
"prompt_id": "RN_HappyHolidays_AN_06",
"weight": 0.1,
"auto_rule_override": null
}
]
}

View File

@@ -0,0 +1,21 @@
{
"mim_type": "announcement",
"rule_name": "",
"sample_utterances": "",
"timeout": 6,
"num_tries_for_gui": 2,
"barge_in": true,
"es_auto_tagging": true,
"notes": "",
"prompts": [
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "",
"prompt": "Thank you. It's nice to be here.",
"media": "TTS",
"prompt_id": "RN_WelcomeBack_AN_01"
}
]
}

View File

@@ -0,0 +1,40 @@
{
"mim_type": "announcement",
"rule_name": "",
"timeout": 6,
"barge_in": true,
"es_auto_tagging": true,
"notes": "",
"prompts": [
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "",
"prompt": "At the moment I'm thinking about how fun, yet scary, it would be to ride on <anim cat=\"emoji\" filter=\"lightning-bolt, !hot-frame\" nonBlocking=\"true\" /> top of a lightning bolt.",
"media": "TTS",
"prompt_id": "RN_WhatAreYouThinking_AN_01",
"weight": 1
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "",
"prompt": "Oh I'm just thinking about shoes. What it might be like to wear them. <break size='0.5'/> And then wondering how I would tie my shoelaces.",
"media": "TTS",
"prompt_id": "RN_WhatAreYouThinking_AN_02",
"weight": 1
},
{
"prompt_category": "Entry-Core",
"prompt_sub_category": "AN",
"index": 1,
"condition": "",
"prompt": "I was just daydreaming about what it might feel like to be powered <anim cat=\"emoji\" filter=\"sun, !hot-frame\" nonBlocking=\"true\"/> directly by the sun. <break size='0.8'/> It felt warm and clean.",
"media": "TTS",
"prompt_id": "RN_WhatAreYouThinking_AN_03",
"weight": 1
}
]
}

View File

@@ -173,24 +173,10 @@ public sealed class OpenWeatherReportProvider(
var temperature = TryReadInt(main, "temp");
var high = TryReadInt(main, "temp_max");
var low = TryReadInt(main, "temp_min");
if (ShouldEnrichCurrentDayHighLow(temperature, high, low))
if (temperature is not null)
{
try
{
var enrichedBand = await TryResolveCurrentDayHighLowFromForecastAsync(
location,
useCelsius,
cancellationToken);
if (enrichedBand is not null)
{
high = enrichedBand.Value.High ?? high;
low = enrichedBand.Value.Low ?? low;
}
}
catch (Exception exception) when (!cancellationToken.IsCancellationRequested)
{
logger.LogDebug(exception, "OpenWeather forecast enrichment failed for current-day Hi/Lo.");
}
high = high is null ? temperature : Math.Max(high.Value, temperature.Value);
low = low is null ? temperature : Math.Min(low.Value, temperature.Value);
}
if (temperature is null && high is null && low is null)
@@ -492,21 +478,6 @@ public sealed class OpenWeatherReportProvider(
return null;
}
private static bool ShouldEnrichCurrentDayHighLow(int? temperature, int? high, int? low)
{
if (high is null || low is null)
{
return true;
}
if (high.Value != low.Value)
{
return false;
}
return temperature is null || high.Value == temperature.Value;
}
private static string BuildWeatherCacheKey(LocationPoint location, bool useCelsius, int forecastDayOffset)
{
return string.Create(

View File

@@ -99,6 +99,102 @@ public sealed class LegacyMimCatalogImporterTests
reply.Contains("Is that a trick question", StringComparison.OrdinalIgnoreCase));
}
[Fact]
public void ImportCatalog_ImportsBuildBEmotionResponsesIntoEmotionBucket()
{
var rootDirectory = Path.Combine(
AppContext.BaseDirectory,
"Content",
"LegacyMims",
"BuildB");
var catalog = LegacyMimCatalogImporter.ImportCatalog(rootDirectory);
Assert.Contains(catalog.EmotionReplies, reply =>
reply.Reply.Contains("I'm feeling pretty good indeed", StringComparison.OrdinalIgnoreCase));
Assert.Contains(catalog.EmotionReplies, reply =>
reply.Reply.Contains("I've been better", StringComparison.OrdinalIgnoreCase));
Assert.Contains(catalog.EmotionReplies, reply =>
reply.Reply.Contains("I'm not mad", StringComparison.OrdinalIgnoreCase));
}
[Fact]
public void ImportCatalog_ImportsBuildBDescriptorResponsesIntoPersonalityBucket()
{
var rootDirectory = Path.Combine(
AppContext.BaseDirectory,
"Content",
"LegacyMims",
"BuildB");
var catalog = LegacyMimCatalogImporter.ImportCatalog(rootDirectory);
Assert.Contains("Well I definitely try to be the kindest robot I can be. So I hope so.", catalog.PersonalityReplies);
Assert.Contains("I don't think so, not intentionally.", catalog.PersonalityReplies);
Assert.Contains(catalog.PersonalityReplies, reply =>
reply.Contains("make people laugh", StringComparison.OrdinalIgnoreCase));
Assert.Contains(catalog.PersonalityReplies, reply =>
reply.Contains("highest priorities", StringComparison.OrdinalIgnoreCase));
Assert.Contains(catalog.PersonalityReplies, reply =>
reply.Contains("learning new things", StringComparison.OrdinalIgnoreCase));
Assert.Contains("Definitely. I'm as loyal as they come.", catalog.PersonalityReplies);
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));
}
[Fact]
public void ImportCatalog_ImportsBuildBSeasonalResponsesIntoPersonalityBucket()
{
var rootDirectory = Path.Combine(
AppContext.BaseDirectory,
"Content",
"LegacyMims",
"BuildB");
var catalog = LegacyMimCatalogImporter.ImportCatalog(rootDirectory);
Assert.Contains(catalog.PersonalityReplies, reply =>
reply.Contains("always trying to learn new skills", StringComparison.OrdinalIgnoreCase));
Assert.Contains(catalog.PersonalityReplies, reply =>
reply.Contains("not eat bacon", StringComparison.OrdinalIgnoreCase));
Assert.Contains(catalog.PersonalityReplies, reply =>
reply.Contains("find out on halloween", StringComparison.OrdinalIgnoreCase));
Assert.Contains(catalog.PersonalityReplies, reply =>
reply.Contains("maybe enjoy some flowers and all things spring", StringComparison.OrdinalIgnoreCase));
Assert.Contains(catalog.PersonalityReplies, reply =>
reply.Contains("pet elephant", StringComparison.OrdinalIgnoreCase));
Assert.Contains(catalog.PersonalityReplies, reply =>
reply.Contains("mostly roboting", StringComparison.OrdinalIgnoreCase));
Assert.Contains(catalog.PersonalityReplies, reply =>
reply.Contains("robot stuff", StringComparison.OrdinalIgnoreCase));
}
[Fact]
public void ImportCatalog_ImportsBuildBRnGreetingResponsesIntoGreetingBucket()
{
var rootDirectory = Path.Combine(
AppContext.BaseDirectory,
"Content",
"LegacyMims",
"BuildB");
var catalog = LegacyMimCatalogImporter.ImportCatalog(rootDirectory);
Assert.Contains(catalog.GreetingReplies, reply =>
reply.Contains("It's nice to be here", StringComparison.OrdinalIgnoreCase));
Assert.Contains(catalog.GreetingReplies, reply =>
reply.Contains("thinking about shoes", StringComparison.OrdinalIgnoreCase));
Assert.Contains(catalog.GreetingReplies, reply =>
reply.Contains("powered directly by the sun", StringComparison.OrdinalIgnoreCase));
Assert.Contains(catalog.GreetingReplies, reply =>
reply.Contains("Another year older, another year wiser", StringComparison.OrdinalIgnoreCase));
Assert.Contains(catalog.GreetingReplies, reply =>
reply.Contains("can't wait to see what you got me", StringComparison.OrdinalIgnoreCase));
Assert.Contains(catalog.GreetingReplies, reply =>
reply.Contains("I was powered on for the first time today", StringComparison.OrdinalIgnoreCase));
}
[Fact]
public void MergeInto_PreservesExistingCatalogAndAddsImportedContent()
{

View File

@@ -48,13 +48,8 @@ public sealed class ProviderCachingTests
}
[Fact]
public async Task OpenWeatherReportProvider_EnrichesCurrentHiLoFromForecast_WhenCurrentBandIsFlat()
public async Task OpenWeatherReportProvider_UsesCurrentHiLoForCurrentDay_WhenCurrentBandDiffers()
{
var utcStart = DateTimeOffset.UtcNow.UtcDateTime.Date;
var forecastWindowStart = new DateTimeOffset(utcStart, TimeSpan.Zero).ToUnixTimeSeconds();
var forecastWindowMid = new DateTimeOffset(utcStart.AddHours(3), TimeSpan.Zero).ToUnixTimeSeconds();
var forecastWindowLate = new DateTimeOffset(utcStart.AddHours(6), TimeSpan.Zero).ToUnixTimeSeconds();
var handler = new CountingHttpMessageHandler(message =>
{
var path = message.RequestUri?.AbsolutePath ?? string.Empty;
@@ -63,9 +58,7 @@ public sealed class ProviderCachingTests
"/geo/1.0/direct" => JsonResponse(
"""[{"name":"Lone Jack","country":"US","lat":38.8708,"lon":-94.1733}]"""),
"/data/2.5/weather" => JsonResponse(
"""{"name":"Lone Jack","weather":[{"main":"Clouds","description":"overcast clouds"}],"main":{"temp":77.0,"temp_max":77.0,"temp_min":77.0}}"""),
"/data/2.5/forecast" => JsonResponse(
$"{{\"city\":{{\"timezone\":0}},\"list\":[{{\"dt\":{forecastWindowStart},\"main\":{{\"temp\":76.0,\"temp_max\":81.0,\"temp_min\":70.0}}}},{{\"dt\":{forecastWindowMid},\"main\":{{\"temp\":80.0,\"temp_max\":84.0,\"temp_min\":69.0}}}},{{\"dt\":{forecastWindowLate},\"main\":{{\"temp\":78.0,\"temp_max\":79.0,\"temp_min\":67.0}}}}]}}"),
"""{"name":"Lone Jack","weather":[{"main":"Clouds","description":"overcast clouds"}],"main":{"temp":76.0,"temp_max":82.0,"temp_min":78.0}}"""),
_ => new HttpResponseMessage(HttpStatusCode.NotFound)
};
});
@@ -84,11 +77,11 @@ public sealed class ProviderCachingTests
var report = await provider.GetReportAsync(new WeatherReportRequest("Lone Jack,US", null, null, false, false, 0));
Assert.NotNull(report);
Assert.Equal(77, report!.Temperature);
Assert.Equal(84, report.HighTemperature);
Assert.Equal(67, report.LowTemperature);
Assert.Equal(76, report!.Temperature);
Assert.Equal(82, report.HighTemperature);
Assert.Equal(76, report.LowTemperature);
Assert.Equal(1, handler.GetCallCount("/data/2.5/weather"));
Assert.Equal(1, handler.GetCallCount("/data/2.5/forecast"));
Assert.Equal(0, handler.GetCallCount("/data/2.5/forecast"));
}
[Fact]

View File

@@ -511,6 +511,138 @@ public sealed class JiboInteractionServiceTests
Assert.Equal(string.Empty, decision.ContextUpdates[ChitchatEmotionKey]);
}
[Theory]
[InlineData("are you sad")]
[InlineData("are you angry")]
public async Task BuildDecisionAsync_MoodFollowups_RouteThroughEmotionQuerySplit(string transcript)
{
var service = CreateService();
var decision = await service.BuildDecisionAsync(new TurnContext
{
RawTranscript = transcript,
NormalizedTranscript = transcript
});
Assert.Equal("emotion_query", decision.IntentName);
Assert.NotNull(decision.ContextUpdates);
Assert.Equal("EmotionQuery", decision.ContextUpdates![ChitchatRouteKey]);
Assert.Equal(string.Empty, decision.ContextUpdates[ChitchatEmotionKey]);
}
[Theory]
[InlineData("how are things")]
[InlineData("how is your day")]
public async Task BuildDecisionAsync_MoodSmallTalk_RoutesThroughHowAreYouPath(string transcript)
{
var service = CreateService();
var decision = await service.BuildDecisionAsync(new TurnContext
{
RawTranscript = transcript,
NormalizedTranscript = transcript
});
Assert.Equal("how_are_you", decision.IntentName);
Assert.NotNull(decision.ContextUpdates);
Assert.Equal("EmotionQuery", decision.ContextUpdates![ChitchatRouteKey]);
}
[Theory]
[InlineData("what are you up to", "being helpful")]
[InlineData("what are you doing", "making people smile")]
[InlineData("what have you been up to", "being helpful")]
public async Task BuildDecisionAsync_PersonalityFollowups_UseDoingPath(string transcript, string expectedReplySnippet)
{
var service = CreateService();
var decision = await service.BuildDecisionAsync(new TurnContext
{
RawTranscript = transcript,
NormalizedTranscript = transcript
});
Assert.Equal("robot_what_do_you_like_to_do", decision.IntentName);
Assert.Contains(expectedReplySnippet, decision.ReplyText, StringComparison.OrdinalIgnoreCase);
Assert.Equal("ScriptedResponse", decision.ContextUpdates![ChitchatRouteKey]);
}
[Theory]
[InlineData("happy holidays", "seasonal_holiday_greeting", "It's a fun time of year")]
[InlineData("merry christmas", "seasonal_holiday_greeting", "It's a fun time of year")]
[InlineData("what holidays do you celebrate", "seasonal_holidays", "official owner can tell me which ones we'll celebrate together")]
[InlineData("what is your new year's resolution", "seasonal_new_years_resolution", "always trying to learn new skills")]
[InlineData("how are your new year's resolutions going", "seasonal_new_years_update", "not eat bacon")]
[InlineData("what halloween costume", "seasonal_halloween_costume", "I haven't thought much about it yet")]
[InlineData("what should I do for first day of spring", "seasonal_first_day_spring", "flowers and all things spring")]
[InlineData("what should I get for holiday", "seasonal_holiday_gift", "pet elephant")]
public async Task BuildDecisionAsync_SeasonalCharm_UsesImportedReplies(
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("welcome back", "welcome_back", "it's nice to be here")]
[InlineData("what are you thinking", "robot_what_are_you_thinking", "thinking about how fun, yet scary")]
[InlineData("what have you been doing", "robot_what_have_you_been_doing", "mostly roboting")]
[InlineData("what did you do", "robot_what_did_you_do", "robot stuff")]
public async Task BuildDecisionAsync_PresenceCharm_UsesImportedReplies(
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("are you kind", "robot_is_kind", "kindest robot i can be")]
[InlineData("are you funny", "robot_is_funny", "not intentionally")]
[InlineData("are you helpful", "robot_is_helpful", "highest priorities")]
[InlineData("are you curious", "robot_is_curious", "learning new things")]
[InlineData("are you loyal", "robot_is_loyal", "loyal as they come")]
[InlineData("are you mischievous", "robot_is_mischievous", "don't really think of myself that way")]
[InlineData("are you likable", "robot_is_likable", "people like me")]
public async Task BuildDecisionAsync_DescriptorCharm_UsesImportedReplies(
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]);
}
[Fact]
public async Task BuildDecisionAsync_AreYouHappy_UsesLegacyEmotionResponseWhenEmotionIsKnown()
{
@@ -1593,7 +1725,7 @@ public sealed class JiboInteractionServiceTests
Assert.Equal("personal_report_delivered", decision.IntentName);
Assert.Contains("Great, alex. Here is your personal report.", decision.ReplyText, StringComparison.OrdinalIgnoreCase);
Assert.Contains("Right now in Boston, U.S., it is light rain and 61 degrees Fahrenheit.", decision.ReplyText, StringComparison.OrdinalIgnoreCase);
Assert.Contains("Right now in Boston, U.S., it's light rain, around 61 degrees Fahrenheit.", decision.ReplyText, StringComparison.OrdinalIgnoreCase);
Assert.Contains("That is your personal report.", decision.ReplyText, StringComparison.OrdinalIgnoreCase);
Assert.NotNull(decision.ContextUpdates);
Assert.Equal("idle", decision.ContextUpdates![PersonalReportStateKey]);
@@ -1931,7 +2063,7 @@ public sealed class JiboInteractionServiceTests
Assert.Equal(54, decision.SkillPayload["weather_low"]);
Assert.Equal("F", decision.SkillPayload["weather_unit"]);
Assert.Equal("Normal", decision.SkillPayload["weather_theme"]);
Assert.Equal("Right now in Boston, U.S., it is light rain and 61 degrees Fahrenheit.", decision.ReplyText);
Assert.Equal("Right now in Boston, U.S., it's light rain, around 61 degrees Fahrenheit.", decision.ReplyText);
Assert.NotNull(provider.LastRequest);
Assert.False(provider.LastRequest!.IsTomorrow);
Assert.Equal(0, provider.LastRequest.ForecastDayOffset);
@@ -1956,7 +2088,7 @@ public sealed class JiboInteractionServiceTests
Assert.Equal("Chicago", provider.LastRequest?.LocationQuery);
Assert.True(provider.LastRequest?.IsTomorrow);
Assert.Equal(1, provider.LastRequest?.ForecastDayOffset);
Assert.Equal("Tomorrow in Chicago, U.S., expect mostly cloudy with a high near 74 degrees Fahrenheit and a low around 60 degrees Fahrenheit.", decision.ReplyText);
Assert.Equal("Tomorrow in Chicago, U.S., it looks mostly cloudy with a high near 74 degrees Fahrenheit and a low around 60 degrees Fahrenheit.", decision.ReplyText);
}
[Fact]
@@ -1978,7 +2110,7 @@ public sealed class JiboInteractionServiceTests
Assert.Equal("Seattle", provider.LastRequest?.LocationQuery);
Assert.False(provider.LastRequest?.IsTomorrow);
Assert.Equal(0, provider.LastRequest?.ForecastDayOffset);
Assert.Equal("Right now in Seattle, U.S., it is light rain and 58 degrees Fahrenheit.", decision.ReplyText);
Assert.Equal("Right now in Seattle, U.S., it's light rain, around 58 degrees Fahrenheit.", decision.ReplyText);
}
[Fact]
@@ -2000,7 +2132,7 @@ public sealed class JiboInteractionServiceTests
Assert.Equal("Paris", provider.LastRequest?.LocationQuery);
Assert.False(provider.LastRequest?.IsTomorrow);
Assert.Equal(0, provider.LastRequest?.ForecastDayOffset);
Assert.Equal("Right now in Paris, FR, it is overcast clouds and 66 degrees Fahrenheit.", decision.ReplyText);
Assert.Equal("Right now in Paris, FR, it's overcast clouds, around 66 degrees Fahrenheit.", decision.ReplyText);
}
[Fact]
@@ -2022,7 +2154,7 @@ public sealed class JiboInteractionServiceTests
Assert.Equal("Redmond Oregon", provider.LastRequest?.LocationQuery);
Assert.False(provider.LastRequest?.IsTomorrow);
Assert.Equal(0, provider.LastRequest?.ForecastDayOffset);
Assert.Equal("Right now in Redmond, U.S., it is clear sky and 63 degrees Fahrenheit.", decision.ReplyText);
Assert.Equal("Right now in Redmond, U.S., it's clear sky, around 63 degrees Fahrenheit.", decision.ReplyText);
}
[Fact]
@@ -2044,7 +2176,7 @@ public sealed class JiboInteractionServiceTests
Assert.Equal("New York City", provider.LastRequest?.LocationQuery);
Assert.True(provider.LastRequest?.IsTomorrow);
Assert.Equal(1, provider.LastRequest?.ForecastDayOffset);
Assert.Equal("Tomorrow in New York, U.S., expect partly cloudy with a high near 76 degrees Fahrenheit and a low around 61 degrees Fahrenheit.", decision.ReplyText);
Assert.Equal("Tomorrow in New York, U.S., it looks partly cloudy with a high near 76 degrees Fahrenheit and a low around 61 degrees Fahrenheit.", decision.ReplyText);
}
[Fact]
@@ -2099,7 +2231,7 @@ public sealed class JiboInteractionServiceTests
Assert.Equal("Chicago", provider.LastRequest?.LocationQuery);
Assert.Null(provider.LastRequest?.Latitude);
Assert.Null(provider.LastRequest?.Longitude);
Assert.Equal("Right now in Chicago, U.S., it is mostly cloudy and 70 degrees Fahrenheit.", decision.ReplyText);
Assert.Equal("Right now in Chicago, U.S., it's mostly cloudy, around 70 degrees Fahrenheit.", decision.ReplyText);
}
[Fact]
@@ -2129,7 +2261,7 @@ public sealed class JiboInteractionServiceTests
Assert.Equal("Chicago", provider.LastRequest?.LocationQuery);
Assert.Equal(0, provider.LastRequest?.ForecastDayOffset);
Assert.False(provider.LastRequest?.IsTomorrow);
Assert.Equal("Right now in Chicago, U.S., it is mostly cloudy and 70 degrees Fahrenheit.", decision.ReplyText);
Assert.Equal("Right now in Chicago, U.S., it's mostly cloudy, around 70 degrees Fahrenheit.", decision.ReplyText);
}
[Fact]
@@ -2159,7 +2291,7 @@ public sealed class JiboInteractionServiceTests
Assert.Equal("Chicago", provider.LastRequest?.LocationQuery);
Assert.Equal(1, provider.LastRequest?.ForecastDayOffset);
Assert.True(provider.LastRequest?.IsTomorrow);
Assert.Equal("Tomorrow in Chicago, U.S., expect mostly cloudy with a high near 75 degrees Fahrenheit and a low around 62 degrees Fahrenheit.", decision.ReplyText);
Assert.Equal("Tomorrow in Chicago, U.S., it looks mostly cloudy with a high near 75 degrees Fahrenheit and a low around 62 degrees Fahrenheit.", decision.ReplyText);
}
[Theory]
@@ -2229,7 +2361,7 @@ public sealed class JiboInteractionServiceTests
Assert.Equal("weather", decision.IntentName);
Assert.Equal(2, provider.LastRequest?.ForecastDayOffset);
Assert.False(provider.LastRequest?.IsTomorrow);
Assert.Equal("On Monday in Portland, U.S., expect scattered clouds with a high near 68 degrees Fahrenheit and a low around 53 degrees Fahrenheit.", decision.ReplyText);
Assert.Equal("On Monday in Portland, U.S., it looks scattered clouds with a high near 68 degrees Fahrenheit and a low around 53 degrees Fahrenheit.", decision.ReplyText);
}
[Fact]
@@ -2254,7 +2386,7 @@ public sealed class JiboInteractionServiceTests
Assert.Equal("weather", decision.IntentName);
Assert.Equal("Chicago", provider.LastRequest?.LocationQuery);
Assert.Equal(1, provider.LastRequest?.ForecastDayOffset);
Assert.Equal("On Tuesday in Chicago, U.S., expect light rain with a high near 63 degrees Fahrenheit and a low around 51 degrees Fahrenheit.", decision.ReplyText);
Assert.Equal("On Tuesday in Chicago, U.S., it looks light rain with a high near 63 degrees Fahrenheit and a low around 51 degrees Fahrenheit.", decision.ReplyText);
}
[Fact]
@@ -2303,7 +2435,7 @@ public sealed class JiboInteractionServiceTests
Assert.Equal("weather", decision.IntentName);
Assert.Equal("Paris", provider.LastRequest?.LocationQuery);
Assert.Equal(5, provider.LastRequest?.ForecastDayOffset);
Assert.Equal("This weekend in Paris, FR, expect overcast clouds with a high near 70 degrees Fahrenheit and a low around 60 degrees Fahrenheit.", decision.ReplyText);
Assert.Equal("This weekend in Paris, FR, it looks overcast clouds with a high near 70 degrees Fahrenheit and a low around 60 degrees Fahrenheit.", decision.ReplyText);
}
[Fact]
@@ -2425,7 +2557,7 @@ public sealed class JiboInteractionServiceTests
Assert.Equal("weather", decision.IntentName);
Assert.Equal("Chicago", provider.LastRequest?.LocationQuery);
Assert.Equal(2, provider.LastRequest?.ForecastDayOffset);
Assert.Equal("The day after tomorrow in Chicago, U.S., expect mostly cloudy with a high near 74 degrees Fahrenheit and a low around 60 degrees Fahrenheit.", decision.ReplyText);
Assert.Equal("The day after tomorrow in Chicago, U.S., it looks mostly cloudy with a high near 74 degrees Fahrenheit and a low around 60 degrees Fahrenheit.", decision.ReplyText);
}
[Fact]