refactors

This commit is contained in:
Jacob Dubin
2026-05-21 07:20:31 -05:00
parent 6138ef1c3e
commit c4c512497c
31 changed files with 164 additions and 172 deletions

View File

@@ -11,4 +11,4 @@ public sealed record CalendarReportSnapshot(
IReadOnlyList<string> EventSummaries,
IReadOnlyList<string> EventTimesOnAt,
IReadOnlyList<string> TomorrowEventSummaries,
bool HasServiceError = false);
bool HasServiceError = false);

View File

@@ -49,4 +49,4 @@ public interface ICloudStateStore
IReadOnlyList<CalendarEventRecord> GetCalendarEvents(string? loopId = null);
CalendarEventRecord UpsertCalendarEvent(CalendarEventRecord calendarEvent);
void UpdateRobot(DeviceRegistration registration);
}
}

View File

@@ -15,4 +15,4 @@ public sealed record CommuteReportSnapshot(
bool EventIsEarly = false,
int MinutesUntilWork = 0,
int ExtraMinutes = 0,
bool RequiresSetup = false);
bool RequiresSetup = false);

View File

@@ -5,4 +5,4 @@ namespace Jibo.Cloud.Application.Abstractions;
public interface IHolidayCalendarProvider
{
IReadOnlyList<HolidayRecord> GetPublicHolidays(string? countryCode, int year);
}
}

View File

@@ -11,24 +11,24 @@ public sealed class JiboConditionedReply
public string Reply { get; init; } = string.Empty;
}
public sealed class JiboExperienceCatalog
{
public IReadOnlyList<string> Jokes { get; init; } = [];
public IReadOnlyList<string> RobotFacts { get; init; } = [];
public IReadOnlyList<string> HumanFacts { get; init; } = [];
public IReadOnlyList<string> FunFacts { get; init; } = [];
public IReadOnlyList<string> FavoriteAnimalReplies { get; init; } = [];
public IReadOnlyList<string> DanceAnimations { get; init; } = [];
public IReadOnlyList<string> GreetingReplies { get; init; } = [];
public IReadOnlyList<string> HolidayReplies { get; init; } = [];
public IReadOnlyList<string> HolidaySeasonReplies { get; init; } = [];
public IReadOnlyList<string> HolidayGreetingReplies { get; init; } = [];
public IReadOnlyList<string> HolidayGiftReplies { get; init; } = [];
public IReadOnlyList<string> HolidayTrackerReplies { get; init; } = [];
public IReadOnlyList<string> BirthdayCelebrationReplies { get; init; } = [];
public IReadOnlyList<string> HowAreYouReplies { get; init; } = [];
public IReadOnlyList<JiboConditionedReply> EmotionReplies { get; init; } = [];
public IReadOnlyList<string> PersonalityReplies { get; init; } = [];
public sealed class JiboExperienceCatalog
{
public IReadOnlyList<string> Jokes { get; init; } = [];
public IReadOnlyList<string> RobotFacts { get; init; } = [];
public IReadOnlyList<string> HumanFacts { get; init; } = [];
public IReadOnlyList<string> FunFacts { get; init; } = [];
public IReadOnlyList<string> FavoriteAnimalReplies { get; init; } = [];
public IReadOnlyList<string> DanceAnimations { get; init; } = [];
public IReadOnlyList<string> GreetingReplies { get; init; } = [];
public IReadOnlyList<string> HolidayReplies { get; init; } = [];
public IReadOnlyList<string> HolidaySeasonReplies { get; init; } = [];
public IReadOnlyList<string> HolidayGreetingReplies { get; init; } = [];
public IReadOnlyList<string> HolidayGiftReplies { get; init; } = [];
public IReadOnlyList<string> HolidayTrackerReplies { get; init; } = [];
public IReadOnlyList<string> BirthdayCelebrationReplies { get; init; } = [];
public IReadOnlyList<string> HowAreYouReplies { get; init; } = [];
public IReadOnlyList<JiboConditionedReply> EmotionReplies { get; init; } = [];
public IReadOnlyList<string> PersonalityReplies { get; init; } = [];
public IReadOnlyList<string> PizzaReplies { get; init; } = [];
public IReadOnlyList<string> SurpriseReplies { get; init; } = [];
public IReadOnlyList<string> PersonalReportReplies { get; init; } = [];
@@ -70,4 +70,4 @@ public sealed class JiboConditionedReply
public IReadOnlyList<string> GenericFallbackReplies { get; init; } = [];
public IReadOnlyList<string> DanceReplies { get; init; } = [];
public IReadOnlyList<string> DanceQuestionReplies { get; init; } = [];
}
}

View File

@@ -743,4 +743,4 @@ public sealed class JiboCloudProtocolService(ICloudStateStore stateStore, IMedia
return Task.FromResult<MediaContentSnapshot?>(null);
}
}
}
}

View File

@@ -518,9 +518,7 @@ public sealed class JiboInteractionService(
randomizer,
selected => RenderHolidayTemplate(selected, turn, greetingPresence),
out var seasonalHolidayDecision))
{
return seasonalHolidayDecision;
}
return semanticIntent switch
{
@@ -1665,7 +1663,7 @@ public sealed class JiboInteractionService(
if (minutesLeft > 0 && minutesLeft < 30)
{
var minutesTemplate = ChooseShortestTemplate(catalog.CommuteMinutesLeftReplies)
?? "That's in about ${skill.commute.minsLeft} minutes.";
?? "That's in about ${skill.commute.minsLeft} minutes.";
reply = $"{reply} {RenderCommuteTemplate(minutesTemplate, durationText, minutesLeftText)}";
}
@@ -1682,10 +1680,7 @@ public sealed class JiboInteractionService(
private string ChooseCommuteAppSetupReply(JiboExperienceCatalog catalog)
{
return SelectLegacyReply(
catalog.CommuteAppSetupReplies,
[
"I need your commute settings before I can give you a commute report."
]);
catalog.CommuteAppSetupReplies, "I need your commute settings before I can give you a commute report.");
}
private static string ChooseCommuteTemplate(
@@ -2147,14 +2142,12 @@ public sealed class JiboInteractionService(
"Your calendar says ${skill.calendar.eventSummaries.shift()}, ${skill.calendar.eventTimesOnAt.shift()}.");
if (template.Contains("${skill.calendar.eventSummaries.shift()}", StringComparison.OrdinalIgnoreCase) ||
template.Contains("${skill.calendar.eventTimesOnAt.shift()}", StringComparison.OrdinalIgnoreCase))
{
return template
.Replace("${skill.calendar.eventSummaries.shift()}", summary, StringComparison.OrdinalIgnoreCase)
.Replace("${skill.calendar.eventTimesOnAt.shift()}", time, StringComparison.OrdinalIgnoreCase)
.Replace("${speaker}", string.Empty, StringComparison.OrdinalIgnoreCase)
.Replace(" ", " ", StringComparison.Ordinal)
.Trim();
}
return $"Your calendar says {summary}, {time}.";
}
@@ -2171,7 +2164,8 @@ public sealed class JiboInteractionService(
.Replace(" ", " ", StringComparison.Ordinal)
.Trim();
return $"Looking at your calendar, there's nothing scheduled for the rest of the day today. Here's what's going on tomorrow: {snapshot.TomorrowEventSummaries[0]}.";
return
$"Looking at your calendar, there's nothing scheduled for the rest of the day today. Here's what's going on tomorrow: {snapshot.TomorrowEventSummaries[0]}.";
}
return ChooseCalendarNothingReply(catalog);
@@ -2191,7 +2185,7 @@ public sealed class JiboInteractionService(
return loweredMode switch
{
"calendar summary" => lowered.Contains("event", StringComparison.OrdinalIgnoreCase) ||
lowered.Contains("summary", StringComparison.OrdinalIgnoreCase),
lowered.Contains("summary", StringComparison.OrdinalIgnoreCase),
"calendar tomorrow" => lowered.Contains("tomorrow", StringComparison.OrdinalIgnoreCase),
_ => true
};
@@ -5802,4 +5796,4 @@ public sealed record JiboInteractionDecision(
string ReplyText,
string? SkillName = null,
IDictionary<string, object?>? SkillPayload = null,
IDictionary<string, object?>? ContextUpdates = null);
IDictionary<string, object?>? ContextUpdates = null);

View File

@@ -333,7 +333,7 @@ internal static class PersonalReportOrchestrator
reportText,
"report-skill",
BuildPersonalReportSkillPayload(reportText, weatherSkillPayload),
ContextUpdates: BuildContextUpdates(
BuildContextUpdates(
IdleState,
0,
0,
@@ -782,4 +782,4 @@ internal static class PersonalReportOrchestrator
bool CalendarEnabled,
bool CommuteEnabled,
bool NewsEnabled);
}
}

View File

@@ -1,5 +1,4 @@
using Jibo.Cloud.Application.Abstractions;
using Jibo.Runtime.Abstractions;
namespace Jibo.Cloud.Application.Services;
@@ -137,4 +136,4 @@ internal static class ScriptedResponseDecisionBuilder
return replies.Count == 0 ? string.Empty : randomizer.Choose(replies);
}
}
}

View File

@@ -1,7 +1,4 @@
using System.Collections.Generic;
using System.Linq;
using Jibo.Cloud.Application.Abstractions;
using Jibo.Runtime.Abstractions;
namespace Jibo.Cloud.Application.Services;
@@ -590,4 +587,4 @@ internal static class SeasonalHolidayRouteBuilder
{
return phrases.Any(phrase => loweredTranscript.Contains(phrase, StringComparison.OrdinalIgnoreCase));
}
}
}

View File

@@ -13,4 +13,4 @@ public sealed class CalendarEventRecord
public string Source { get; init; } = "manual";
public string? MemberId { get; init; }
public DateTimeOffset Created { get; init; } = DateTimeOffset.UtcNow;
}
}

View File

@@ -15,4 +15,4 @@ public sealed class CommuteProfileRecord
public int TypicalDurationMinutes { get; init; } = 25;
public DateTimeOffset Created { get; init; } = DateTimeOffset.UtcNow;
public DateTimeOffset Updated { get; init; } = DateTimeOffset.UtcNow;
}
}

View File

@@ -15,4 +15,4 @@ public sealed class HolidayRecord
public string Source { get; init; } = "nager-date";
public string CountryCode { get; init; } = "US";
public DateTimeOffset Created { get; init; } = DateTimeOffset.UtcNow;
}
}

View File

@@ -167,4 +167,4 @@ public sealed class LocalWhisperCppBufferedAudioSttStrategy(
return !checkFileExists || File.Exists(path);
}
}
}

View File

@@ -1,6 +1,5 @@
using Jibo.Cloud.Application.Abstractions;
using Jibo.Cloud.Domain.Models;
using Jibo.Cloud.Infrastructure.Persistence;
using Jibo.Runtime.Abstractions;
namespace Jibo.Cloud.Infrastructure.Calendar;
@@ -31,9 +30,9 @@ public sealed class CloudStateCalendarReportProvider(ICloudStateStore cloudState
foreach (var entry in calendarEvents
.Select(calendarEvent => (
Summary: calendarEvent.Summary,
calendarEvent.Summary,
TimeLabel: calendarEvent.TimeLabel ?? "all day",
Date: calendarEvent.Date))
calendarEvent.Date))
.Concat(ToCalendarEntries(holidays)))
{
if (entry.Date == today)
@@ -65,11 +64,9 @@ public sealed class CloudStateCalendarReportProvider(ICloudStateStore cloudState
IEnumerable<HolidayRecord> holidays)
{
foreach (var holiday in holidays)
{
yield return (
holiday.Name,
"all day",
holiday.Date);
}
}
}
}

View File

@@ -11,4 +11,4 @@ public sealed class UnavailableCalendarReportProvider : ICalendarReportProvider
{
return Task.FromResult<CalendarReportSnapshot?>(null);
}
}
}

View File

@@ -28,10 +28,8 @@ public sealed class CloudStateCommuteReportProvider(ICloudStateStore cloudStateS
commute ??= commuteProfiles.FirstOrDefault(profile => profile.IsEnabled);
if (commute is null || !commute.IsComplete)
{
return Task.FromResult<CommuteReportSnapshot?>(
new CommuteReportSnapshot(string.Empty, string.Empty, 0, RequiresSetup: true));
}
var now = DateTimeOffset.Now;
var workTarget = ResolveWorkTarget(now, commute);
@@ -149,4 +147,4 @@ public sealed class CloudStateCommuteReportProvider(ICloudStateStore cloudStateS
return null;
}
}
}

View File

@@ -331,4 +331,4 @@ public sealed class InMemoryJiboExperienceContentRepository : IJiboExperienceCon
return candidates.Where(Directory.Exists).ToArray();
}
}
}

View File

@@ -338,16 +338,22 @@ public static class LegacyMimCatalogImporter
CommuteConfirmSpeakerReplies = Merge(baseCatalog.CommuteConfirmSpeakerReplies,
importedCatalog.CommuteConfirmSpeakerReplies),
CommuteNowReplies = Merge(baseCatalog.CommuteNowReplies, importedCatalog.CommuteNowReplies),
CommuteMinutesLeftReplies = Merge(baseCatalog.CommuteMinutesLeftReplies, importedCatalog.CommuteMinutesLeftReplies),
CommuteMinutesLeftReplies = Merge(baseCatalog.CommuteMinutesLeftReplies,
importedCatalog.CommuteMinutesLeftReplies),
CommuteDepartTimeNormalReplies = Merge(baseCatalog.CommuteDepartTimeNormalReplies,
importedCatalog.CommuteDepartTimeNormalReplies),
CommuteDepartTimeNotNormalReplies = Merge(baseCatalog.CommuteDepartTimeNotNormalReplies,
importedCatalog.CommuteDepartTimeNotNormalReplies),
CommuteDriveNormalReplies = Merge(baseCatalog.CommuteDriveNormalReplies, importedCatalog.CommuteDriveNormalReplies),
CommuteDriveLateReplies = Merge(baseCatalog.CommuteDriveLateReplies, importedCatalog.CommuteDriveLateReplies),
CommuteDriveHurryReplies = Merge(baseCatalog.CommuteDriveHurryReplies, importedCatalog.CommuteDriveHurryReplies),
CommuteDrivePoorReplies = Merge(baseCatalog.CommuteDrivePoorReplies, importedCatalog.CommuteDrivePoorReplies),
CommuteDriveTerribleReplies = Merge(baseCatalog.CommuteDriveTerribleReplies, importedCatalog.CommuteDriveTerribleReplies),
CommuteDriveNormalReplies = Merge(baseCatalog.CommuteDriveNormalReplies,
importedCatalog.CommuteDriveNormalReplies),
CommuteDriveLateReplies =
Merge(baseCatalog.CommuteDriveLateReplies, importedCatalog.CommuteDriveLateReplies),
CommuteDriveHurryReplies =
Merge(baseCatalog.CommuteDriveHurryReplies, importedCatalog.CommuteDriveHurryReplies),
CommuteDrivePoorReplies =
Merge(baseCatalog.CommuteDrivePoorReplies, importedCatalog.CommuteDrivePoorReplies),
CommuteDriveTerribleReplies = Merge(baseCatalog.CommuteDriveTerribleReplies,
importedCatalog.CommuteDriveTerribleReplies),
CommuteTransportNormalReplies = Merge(baseCatalog.CommuteTransportNormalReplies,
importedCatalog.CommuteTransportNormalReplies),
CommuteTransportLateReplies = Merge(baseCatalog.CommuteTransportLateReplies,
@@ -420,9 +426,9 @@ public static class LegacyMimCatalogImporter
return string.IsNullOrWhiteSpace(condition) ? string.Empty : WhitespacePattern.Replace(condition.Trim(), " ");
}
private static bool IsTemplateBucket(LegacyMimBucket bucket)
{
return bucket is LegacyMimBucket.PersonalReportKickOff
private static bool IsTemplateBucket(LegacyMimBucket bucket)
{
return bucket is LegacyMimBucket.PersonalReportKickOff
or LegacyMimBucket.PersonalReportOutro
or LegacyMimBucket.WeatherIntro
or LegacyMimBucket.WeatherTomorrowIntro
@@ -432,48 +438,48 @@ public static class LegacyMimCatalogImporter
or LegacyMimBucket.ReportSkillTemplate
or LegacyMimBucket.Holiday
or LegacyMimBucket.HolidayTracker;
}
}
private static bool IsHolidaySeasonFile(string fileName)
{
return fileName.StartsWith("RI_JBO_HowIsHolidaySeason", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_LikesHolidaySeason", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_HowIsThanksgiving", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_LikesThanksgiving", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_LooksForwardToThanksgiving", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_PlansForThanksgiving", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_HowIsChristmas", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_LikesChristmas", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_LooksForwardToChristmas", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_PlansForChristmas", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_HowIsHanukkah", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_LikesHanukkah", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_LooksForwardToHanukkah", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_PlansForHanukkah", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_HowIsPassover", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_LikesPassover", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_LooksForwardToPassover", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_PlansForPassover", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_HowIsNewYears", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_LikesNewYears", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_LooksForwardToNewYears", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_PlansForNewYears", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_HowIsValentinesDay", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_LikesValentinesDay", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_LooksForwardToValentinesDay", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_PlansForValentinesDay", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_HowIsKwanzaa", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_LikesKwanzaa", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_LooksForwardToKwanzaa", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_PlansForKwanzaa", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_HowIsEaster", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_LikesEaster", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_LooksForwardToEaster", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_PlansForEaster", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_HowIsOrthodoxEaster", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_LikesOrthodoxEaster", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_LooksForwardToOrthodoxEaster", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_PlansForOrthodoxEaster", StringComparison.OrdinalIgnoreCase);
fileName.StartsWith("RI_JBO_LikesHolidaySeason", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_HowIsThanksgiving", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_LikesThanksgiving", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_LooksForwardToThanksgiving", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_PlansForThanksgiving", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_HowIsChristmas", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_LikesChristmas", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_LooksForwardToChristmas", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_PlansForChristmas", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_HowIsHanukkah", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_LikesHanukkah", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_LooksForwardToHanukkah", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_PlansForHanukkah", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_HowIsPassover", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_LikesPassover", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_LooksForwardToPassover", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_PlansForPassover", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_HowIsNewYears", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_LikesNewYears", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_LooksForwardToNewYears", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_PlansForNewYears", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_HowIsValentinesDay", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_LikesValentinesDay", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_LooksForwardToValentinesDay", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_PlansForValentinesDay", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_HowIsKwanzaa", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_LikesKwanzaa", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_LooksForwardToKwanzaa", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_PlansForKwanzaa", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_HowIsEaster", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_LikesEaster", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_LooksForwardToEaster", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_PlansForEaster", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_HowIsOrthodoxEaster", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_LikesOrthodoxEaster", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_LooksForwardToOrthodoxEaster", StringComparison.OrdinalIgnoreCase) ||
fileName.StartsWith("RI_JBO_PlansForOrthodoxEaster", StringComparison.OrdinalIgnoreCase);
}
private enum LegacyMimBucket
@@ -529,6 +535,7 @@ public static class LegacyMimCatalogImporter
private sealed class LegacyMimCatalogBuilder
{
private readonly List<string> _birthdayCelebrationReplies = [];
private readonly List<string> _calendarNothingReplies = [];
private readonly List<string> _calendarNothingTodayReplies = [];
private readonly List<string> _calendarOutroReplies = [];
@@ -537,28 +544,27 @@ public static class LegacyMimCatalogImporter
private readonly List<string> _commuteConfirmSpeakerReplies = [];
private readonly List<string> _commuteDepartTimeNormalReplies = [];
private readonly List<string> _commuteDepartTimeNotNormalReplies = [];
private readonly List<string> _commuteNowReplies = [];
private readonly List<string> _commuteMinutesLeftReplies = [];
private readonly List<string> _commuteDriveNormalReplies = [];
private readonly List<string> _commuteDriveLateReplies = [];
private readonly List<string> _commuteDriveHurryReplies = [];
private readonly List<string> _commuteDriveLateReplies = [];
private readonly List<string> _commuteDriveNormalReplies = [];
private readonly List<string> _commuteDrivePoorReplies = [];
private readonly List<string> _commuteDriveTerribleReplies = [];
private readonly List<string> _commuteTransportNormalReplies = [];
private readonly List<string> _commuteTransportLateReplies = [];
private readonly List<string> _commuteTransportHurryReplies = [];
private readonly List<string> _commuteMinutesLeftReplies = [];
private readonly List<string> _commuteNowReplies = [];
private readonly List<string> _commuteServiceDownReplies = [];
private readonly List<string> _birthdayCelebrationReplies = [];
private readonly List<string> _commuteTransportHurryReplies = [];
private readonly List<string> _commuteTransportLateReplies = [];
private readonly List<string> _commuteTransportNormalReplies = [];
private readonly List<JiboConditionedReply> _emotionReplies = [];
private readonly List<string> _fallbacks = [];
private readonly List<string> _funFacts = [];
private readonly List<string> _favoriteAnimalReplies = [];
private readonly List<string> _funFacts = [];
private readonly List<string> _greetings = [];
private readonly List<string> _holidayGiftReplies = [];
private readonly List<string> _holidayGreetingReplies = [];
private readonly List<string> _holidayReplies = [];
private readonly List<string> _holidaySeasonReplies = [];
private readonly List<string> _holidayTrackerReplies = [];
private readonly List<string> _greetings = [];
private readonly List<string> _howAreYous = [];
private readonly List<string> _humanFacts = [];
private readonly List<string> _jokes = [];
@@ -868,4 +874,4 @@ public static class LegacyMimCatalogImporter
[JsonPropertyName("weight")] public double? Weight { get; init; }
}
}
}

View File

@@ -130,4 +130,4 @@ public static class ServiceCollectionExtensions
? backendKind
: PersistenceBackendKind.File;
}
}
}

View File

@@ -3,4 +3,4 @@ namespace Jibo.Cloud.Infrastructure.Holidays;
public sealed class HolidayCalendarOptions
{
public string CountryCode { get; set; } = "US";
}
}

View File

@@ -1,4 +1,5 @@
using System.Collections.Concurrent;
using System.Text;
using System.Text.Json;
using Jibo.Cloud.Application.Abstractions;
using Jibo.Cloud.Domain.Models;
@@ -9,6 +10,7 @@ public sealed class NagerDateHolidayCalendarProvider : IHolidayCalendarProvider
{
private static readonly HttpClient HttpClient = new();
private static readonly ConcurrentDictionary<string, HolidayRecord[]> Cache = new(StringComparer.OrdinalIgnoreCase);
private static readonly JsonSerializerOptions JsonOptions = new(JsonSerializerDefaults.Web)
{
PropertyNameCaseInsensitive = true
@@ -168,13 +170,13 @@ public sealed class NagerDateHolidayCalendarProvider : IHolidayCalendarProvider
var l = (32 + 2 * e + 2 * i - h - k) % 7;
var m = (a + 11 * h + 22 * l) / 451;
var month = (h + l - 7 * m + 114) / 31;
var day = ((h + l - 7 * m + 114) % 31) + 1;
var day = (h + l - 7 * m + 114) % 31 + 1;
return new DateOnly(year, month, day);
}
private static string Slugify(string value)
{
var builder = new System.Text.StringBuilder(value.Length);
var builder = new StringBuilder(value.Length);
var lastWasDash = false;
foreach (var ch in value.ToLowerInvariant())
{
@@ -205,4 +207,4 @@ public sealed class NagerDateHolidayCalendarProvider : IHolidayCalendarProvider
public string[]? Counties { get; init; }
public string[]? Types { get; init; }
}
}
}

View File

@@ -539,4 +539,4 @@ public sealed class NewsApiBriefingProvider(
private sealed record ApiError(string? Code, string? Message);
private sealed record CacheEntry<T>(T Value, DateTimeOffset ExpiresUtc);
}
}

View File

@@ -18,22 +18,23 @@ public sealed class InMemoryCloudStateStore : ICloudStateStore
};
private readonly List<BackupRecord> _backups = [];
private readonly List<CommuteProfileRecord> _commuteProfiles = [];
private readonly List<CalendarEventRecord> _calendarEvents = [];
private readonly List<CommuteProfileRecord> _commuteProfiles = [];
private readonly ConcurrentDictionary<string, DeviceRegistration> _devices = new(StringComparer.OrdinalIgnoreCase);
private readonly IHolidayCalendarProvider _holidayCalendarProvider;
private readonly List<HolidayRecord> _holidayOverrides = [];
private readonly ConcurrentDictionary<string, KeyRequestRecord>
_keyRequests = new(StringComparer.OrdinalIgnoreCase);
private readonly List<LoopRecord> _loops;
private readonly List<HolidayRecord> _holidayOverrides = [];
private readonly List<MediaRecord> _media = [];
private readonly List<PersonRecord> _people;
private readonly ConcurrentDictionary<string, CloudSession>
_sessionsByToken = new(StringComparer.OrdinalIgnoreCase);
private readonly IHolidayCalendarProvider _holidayCalendarProvider;
private readonly ISnapshotStore _snapshotStore;
private readonly ConcurrentDictionary<string, string> _symmetricKeys = new(StringComparer.OrdinalIgnoreCase);
private readonly Lock _syncRoot = new();
@@ -515,7 +516,8 @@ public sealed class InMemoryCloudStateStore : ICloudStateStore
{
Id = normalizedId,
LoopId = resolvedLoopId,
Summary = string.IsNullOrWhiteSpace(calendarEvent.Summary) ? "Calendar event" : calendarEvent.Summary.Trim(),
Summary =
string.IsNullOrWhiteSpace(calendarEvent.Summary) ? "Calendar event" : calendarEvent.Summary.Trim(),
TimeLabel = string.IsNullOrWhiteSpace(calendarEvent.TimeLabel) ? null : calendarEvent.TimeLabel.Trim(),
Date = calendarEvent.Date,
EndDate = calendarEvent.EndDate,
@@ -757,14 +759,12 @@ public sealed class InMemoryCloudStateStore : ICloudStateStore
private void EnsureDefaultTopology()
{
if (_loops.Count == 0)
{
_loops.Add(new LoopRecord
{
OwnerAccountId = _account.AccountId,
RobotId = _robot.RobotId,
RobotFriendlyId = _robot.DeviceId
});
}
if (_people.Count != 0)
{
@@ -952,4 +952,4 @@ public sealed class InMemoryCloudStateStore : ICloudStateStore
};
}
}
}
}

View File

@@ -560,4 +560,4 @@ public sealed class LegacyMimCatalogImporterTests
return rootDirectory;
}
}
}

View File

@@ -156,12 +156,12 @@ public sealed class PersistenceStoreTests
try
{
File.WriteAllText(persistencePath, """
{
"SchemaVersion": "1",
"Revision": 7,
"Loops": []
}
""");
{
"SchemaVersion": "1",
"Revision": 7,
"Loops": []
}
""");
var store = new InMemoryCloudStateStore(persistencePath);
@@ -189,4 +189,4 @@ public sealed class PersistenceStoreTests
Saves.Add(snapshot);
}
}
}
}

View File

@@ -497,4 +497,4 @@ public sealed class ProviderCachingTests
return Task.FromResult(responseFactory(request));
}
}
}
}

View File

@@ -88,13 +88,13 @@ public sealed class JiboCloudProtocolServiceTests
try
{
await File.WriteAllTextAsync(persistencePath, """
{
"SchemaVersion": "1",
"Revision": 0,
"Loops": [],
"Holidays": []
}
""");
{
"SchemaVersion": "1",
"Revision": 0,
"Loops": [],
"Holidays": []
}
""");
var service = new JiboCloudProtocolService(new InMemoryCloudStateStore(persistencePath));
var result = await service.DispatchAsync(new ProtocolEnvelope
@@ -124,27 +124,27 @@ public sealed class JiboCloudProtocolServiceTests
try
{
await File.WriteAllTextAsync(persistencePath, """
{
"SchemaVersion": "1",
"Revision": 0,
"Loops": [],
"Holidays": [
{
"Id": "birthday-1",
"EventId": "birthday-1",
"Name": "Jake's Birthday",
"Category": "birthday",
"LoopId": "loop-123",
"MemberId": "person-123",
"IsEnabled": true,
"Date": "2026-05-19",
"Source": "manual",
"CountryCode": "US",
"Created": "2026-05-19T00:00:00Z"
}
]
}
""");
{
"SchemaVersion": "1",
"Revision": 0,
"Loops": [],
"Holidays": [
{
"Id": "birthday-1",
"EventId": "birthday-1",
"Name": "Jake's Birthday",
"Category": "birthday",
"LoopId": "loop-123",
"MemberId": "person-123",
"IsEnabled": true,
"Date": "2026-05-19",
"Source": "manual",
"CountryCode": "US",
"Created": "2026-05-19T00:00:00Z"
}
]
}
""");
var service = new JiboCloudProtocolService(new InMemoryCloudStateStore(persistencePath));
var result = await service.DispatchAsync(new ProtocolEnvelope
@@ -468,4 +468,4 @@ public sealed class JiboCloudProtocolServiceTests
Assert.Contains(people,
person => string.Equals(person.LoopId, store.GetLoops()[0].LoopId, StringComparison.OrdinalIgnoreCase));
}
}
}

View File

@@ -4289,5 +4289,4 @@ public sealed class JiboInteractionServiceTests
return Task.FromResult(Snapshot);
}
}
}
}

View File

@@ -5212,4 +5212,4 @@ public sealed class JiboWebSocketServiceTests
return items[^1];
}
}
}
}

View File

@@ -275,4 +275,4 @@ public sealed class LocalWhisperCppBufferedAudioSttStrategyTests
return Task.FromResult(new ExternalProcessResult(0, string.Empty, string.Empty));
}
}
}
}