refactor
This commit is contained in:
@@ -44,4 +44,4 @@ public interface ICloudStateStore
|
||||
IReadOnlyList<KeyRequestRecord> GetBinaryRequests();
|
||||
IReadOnlyList<object> GetHolidays();
|
||||
void UpdateRobot(DeviceRegistration registration);
|
||||
}
|
||||
}
|
||||
@@ -12,4 +12,4 @@ public sealed record CommuteReportSnapshot(
|
||||
string Summary,
|
||||
int DurationMinutes,
|
||||
string? Mode = null,
|
||||
bool EventIsEarly = false);
|
||||
bool EventIsEarly = false);
|
||||
@@ -50,4 +50,4 @@ public sealed class JiboExperienceCatalog
|
||||
public IReadOnlyList<string> GenericFallbackReplies { get; init; } = [];
|
||||
public IReadOnlyList<string> DanceReplies { get; init; } = [];
|
||||
public IReadOnlyList<string> DanceQuestionReplies { get; init; } = [];
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,7 @@ public sealed record MediaContentSnapshot
|
||||
{
|
||||
public string ContentType { get; init; } = "application/octet-stream";
|
||||
public byte[] Content { get; init; } = [];
|
||||
|
||||
public IReadOnlyDictionary<string, object?> Meta { get; init; } =
|
||||
new Dictionary<string, object?>(StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
}
|
||||
@@ -620,4 +620,4 @@ internal static class ChitchatStateMachine
|
||||
mappings.Sort(static (left, right) => right.Phrase.Length.CompareTo(left.Phrase.Length));
|
||||
return [.. mappings];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using Jibo.Cloud.Application.Abstractions;
|
||||
using Jibo.Cloud.Domain.Models;
|
||||
@@ -6,7 +7,6 @@ namespace Jibo.Cloud.Application.Services;
|
||||
|
||||
public sealed class JiboCloudProtocolService(ICloudStateStore stateStore, IMediaContentStore? mediaContentStore = null)
|
||||
{
|
||||
private readonly IMediaContentStore _mediaContentStore = mediaContentStore ?? new NullMediaContentStore();
|
||||
private static readonly string[] AcceptedHosts =
|
||||
[
|
||||
"api.jibo.com",
|
||||
@@ -15,6 +15,8 @@ public sealed class JiboCloudProtocolService(ICloudStateStore stateStore, IMedia
|
||||
"localhost"
|
||||
];
|
||||
|
||||
private readonly IMediaContentStore _mediaContentStore = mediaContentStore ?? new NullMediaContentStore();
|
||||
|
||||
public Task<ProtocolDispatchResult> DispatchAsync(ProtocolEnvelope envelope,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
@@ -344,7 +346,7 @@ public sealed class JiboCloudProtocolService(ICloudStateStore stateStore, IMedia
|
||||
if (!string.IsNullOrWhiteSpace(envelope.BodyText)) meta["bodyText"] = envelope.BodyText;
|
||||
|
||||
_mediaContentStore.StoreAsync(path, contentType,
|
||||
string.IsNullOrWhiteSpace(envelope.BodyText) ? [] : System.Text.Encoding.UTF8.GetBytes(envelope.BodyText),
|
||||
string.IsNullOrWhiteSpace(envelope.BodyText) ? [] : Encoding.UTF8.GetBytes(envelope.BodyText),
|
||||
meta as IReadOnlyDictionary<string, object?>, CancellationToken.None).GetAwaiter().GetResult();
|
||||
|
||||
return ProtocolDispatchResult.Ok(
|
||||
@@ -367,7 +369,8 @@ public sealed class JiboCloudProtocolService(ICloudStateStore stateStore, IMedia
|
||||
{
|
||||
var body = envelope.TryParseBody();
|
||||
var requestedName = ReadString(body, "name") ?? ReadString(body, "backupName");
|
||||
return ProtocolDispatchResult.Ok(stateStore.CreateBackup(requestedName ?? $"backup-{DateTimeOffset.UtcNow:yyyyMMddHHmmss}"));
|
||||
return ProtocolDispatchResult.Ok(
|
||||
stateStore.CreateBackup(requestedName ?? $"backup-{DateTimeOffset.UtcNow:yyyyMMddHHmmss}"));
|
||||
}
|
||||
|
||||
return ProtocolDispatchResult.Ok(Array.Empty<object>());
|
||||
@@ -512,27 +515,13 @@ public sealed class JiboCloudProtocolService(ICloudStateStore stateStore, IMedia
|
||||
|
||||
var storedContent = _mediaContentStore.LoadAsync(media.Path, CancellationToken.None).GetAwaiter().GetResult();
|
||||
var contentType = storedContent?.ContentType ?? TryReadMetaString(media.Meta, "contentType") ??
|
||||
"application/octet-stream";
|
||||
"application/octet-stream";
|
||||
var bodyText = storedContent is not null
|
||||
? System.Text.Encoding.UTF8.GetString(storedContent.Content)
|
||||
? Encoding.UTF8.GetString(storedContent.Content)
|
||||
: TryReadMetaString(media.Meta, "bodyText") ?? string.Empty;
|
||||
return ProtocolDispatchResult.Raw(200, bodyText, contentType);
|
||||
}
|
||||
|
||||
private sealed class NullMediaContentStore : IMediaContentStore
|
||||
{
|
||||
public Task StoreAsync(string path, string contentType, byte[] content,
|
||||
IReadOnlyDictionary<string, object?>? meta, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public Task<MediaContentSnapshot?> LoadAsync(string path, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return Task.FromResult<MediaContentSnapshot?>(null);
|
||||
}
|
||||
}
|
||||
|
||||
private ProtocolDispatchResult HandleGetUpdateFrom(string? subsystem, string? fromVersion, string? filter)
|
||||
{
|
||||
var update = stateStore.GetUpdateFrom(subsystem, fromVersion, filter);
|
||||
@@ -662,4 +651,18 @@ public sealed class JiboCloudProtocolService(ICloudStateStore stateStore, IMedia
|
||||
bool.TryParse(value, out var parsed) &&
|
||||
parsed;
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class NullMediaContentStore : IMediaContentStore
|
||||
{
|
||||
public Task StoreAsync(string path, string contentType, byte[] content,
|
||||
IReadOnlyDictionary<string, object?>? meta, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public Task<MediaContentSnapshot?> LoadAsync(string path, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return Task.FromResult<MediaContentSnapshot?>(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1524,10 +1524,10 @@ public sealed class JiboInteractionService(
|
||||
{
|
||||
"walking" => lowered.Contains("walk", StringComparison.OrdinalIgnoreCase),
|
||||
"transit" => lowered.Contains("public transportation", StringComparison.OrdinalIgnoreCase) ||
|
||||
lowered.Contains("transit", StringComparison.OrdinalIgnoreCase) ||
|
||||
lowered.Contains("transportation", StringComparison.OrdinalIgnoreCase),
|
||||
lowered.Contains("transit", StringComparison.OrdinalIgnoreCase) ||
|
||||
lowered.Contains("transportation", StringComparison.OrdinalIgnoreCase),
|
||||
"bicycling" => lowered.Contains("bike", StringComparison.OrdinalIgnoreCase) ||
|
||||
lowered.Contains("ride", StringComparison.OrdinalIgnoreCase),
|
||||
lowered.Contains("ride", StringComparison.OrdinalIgnoreCase),
|
||||
_ => lowered.Contains("drive", StringComparison.OrdinalIgnoreCase) ||
|
||||
lowered.Contains("commute", StringComparison.OrdinalIgnoreCase)
|
||||
};
|
||||
@@ -4617,13 +4617,13 @@ public sealed class JiboInteractionService(
|
||||
{
|
||||
var normalized = NormalizeCommandPhrase(loweredTranscript);
|
||||
return normalized.StartsWith("what is my favorite", StringComparison.Ordinal) ||
|
||||
normalized.StartsWith("what s my favorite", StringComparison.Ordinal) ||
|
||||
normalized.StartsWith("what's my favorite", StringComparison.Ordinal) ||
|
||||
normalized.StartsWith("what is my favourite", StringComparison.Ordinal) ||
|
||||
normalized.StartsWith("what s my favourite", StringComparison.Ordinal) ||
|
||||
normalized.StartsWith("what's my favourite", StringComparison.Ordinal) ||
|
||||
normalized.StartsWith("do you remember my favorite", StringComparison.Ordinal) ||
|
||||
normalized.StartsWith("do you remember my favourite", StringComparison.Ordinal);
|
||||
normalized.StartsWith("what s my favorite", StringComparison.Ordinal) ||
|
||||
normalized.StartsWith("what's my favorite", StringComparison.Ordinal) ||
|
||||
normalized.StartsWith("what is my favourite", StringComparison.Ordinal) ||
|
||||
normalized.StartsWith("what s my favourite", StringComparison.Ordinal) ||
|
||||
normalized.StartsWith("what's my favourite", StringComparison.Ordinal) ||
|
||||
normalized.StartsWith("do you remember my favorite", StringComparison.Ordinal) ||
|
||||
normalized.StartsWith("do you remember my favourite", StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
private static string? TryExtractPreferenceLookupCategory(string transcript)
|
||||
@@ -5410,4 +5410,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);
|
||||
@@ -676,7 +676,8 @@ internal static class PersonalReportOrchestrator
|
||||
var selected = ChooseShortestTemplate(briefings);
|
||||
if (string.IsNullOrWhiteSpace(selected)) return string.Empty;
|
||||
|
||||
var firstSentence = selected.Split(['.', '!', '?'], 2, StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries)
|
||||
var firstSentence = selected.Split(['.', '!', '?'], 2,
|
||||
StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries)
|
||||
.FirstOrDefault();
|
||||
return string.IsNullOrWhiteSpace(firstSentence) ? selected : firstSentence;
|
||||
}
|
||||
@@ -705,4 +706,4 @@ internal static class PersonalReportOrchestrator
|
||||
bool CalendarEnabled,
|
||||
bool CommuteEnabled,
|
||||
bool NewsEnabled);
|
||||
}
|
||||
}
|
||||
@@ -1459,4 +1459,4 @@ public sealed class ResponsePlanToSocketMessagesMapper
|
||||
string? SpokenLine);
|
||||
|
||||
public sealed record SocketReplyPlan(string Text, int DelayMs = 0);
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
using System.Text.RegularExpressions;
|
||||
using Jibo.Runtime.Abstractions;
|
||||
|
||||
namespace Jibo.Cloud.Application.Services;
|
||||
@@ -57,10 +58,10 @@ public sealed class SyntheticBufferedAudioSttStrategy : ISttStrategy
|
||||
if (string.IsNullOrWhiteSpace(value)) return string.Empty;
|
||||
|
||||
var lowered = value.Trim().ToLowerInvariant();
|
||||
lowered = System.Text.RegularExpressions.Regex.Replace(lowered, @"[^\p{L}\p{N}\s']+", " ",
|
||||
System.Text.RegularExpressions.RegexOptions.CultureInvariant | System.Text.RegularExpressions.RegexOptions.Compiled);
|
||||
lowered = System.Text.RegularExpressions.Regex.Replace(lowered, @"\s+"," ",
|
||||
System.Text.RegularExpressions.RegexOptions.CultureInvariant | System.Text.RegularExpressions.RegexOptions.Compiled);
|
||||
lowered = Regex.Replace(lowered, @"[^\p{L}\p{N}\s']+", " ",
|
||||
RegexOptions.CultureInvariant | RegexOptions.Compiled);
|
||||
lowered = Regex.Replace(lowered, @"\s+", " ",
|
||||
RegexOptions.CultureInvariant | RegexOptions.Compiled);
|
||||
return lowered.Trim();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@ using System.Text.RegularExpressions;
|
||||
|
||||
namespace Jibo.Cloud.Application.Services;
|
||||
|
||||
internal static partial class TranscriptTextNormalizer
|
||||
internal static class TranscriptTextNormalizer
|
||||
{
|
||||
private static readonly Regex PunctuationToSpaceRegex = new(
|
||||
@"[^\p{L}\p{N}\s']+",
|
||||
@@ -55,4 +55,4 @@ internal static partial class TranscriptTextNormalizer
|
||||
trimmed = normalizedValue;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,11 @@
|
||||
using System.Text.Json;
|
||||
using System.Text.RegularExpressions;
|
||||
using Jibo.Cloud.Application.Abstractions;
|
||||
using Jibo.Cloud.Domain.Models;
|
||||
using Jibo.Runtime.Abstractions;
|
||||
|
||||
namespace Jibo.Cloud.Application.Services;
|
||||
|
||||
public sealed partial class WebSocketTurnFinalizationService(
|
||||
public sealed class WebSocketTurnFinalizationService(
|
||||
IConversationBroker conversationBroker,
|
||||
ISttStrategySelector sttStrategySelector,
|
||||
ITurnTelemetrySink sink
|
||||
@@ -1943,4 +1942,4 @@ public sealed partial class WebSocketTurnFinalizationService(
|
||||
Affirmative = 1,
|
||||
Negative = 2
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,4 +21,4 @@ internal static class AudioTranscriptNormalizer
|
||||
" ")
|
||||
.Trim();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -155,4 +155,4 @@ public sealed class LocalWhisperCppBufferedAudioSttStrategy(
|
||||
|
||||
return !checkFileExists || File.Exists(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,4 +11,4 @@ public sealed class UnavailableCommuteReportProvider : ICommuteReportProvider
|
||||
{
|
||||
return Task.FromResult<CommuteReportSnapshot?>(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -246,4 +246,4 @@ public sealed class InMemoryJiboExperienceContentRepository : IJiboExperienceCon
|
||||
|
||||
return candidates.Where(Directory.Exists).ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -371,18 +371,17 @@ public static class LegacyMimCatalogImporter
|
||||
{
|
||||
private readonly List<string> _calendarNothingReplies = [];
|
||||
private readonly List<string> _calendarNothingTodayReplies = [];
|
||||
private readonly List<string> _calendarServiceDownReplies = [];
|
||||
private readonly List<string> _calendarOutroReplies = [];
|
||||
private readonly List<string> _calendarServiceDownReplies = [];
|
||||
private readonly List<string> _commuteNowReplies = [];
|
||||
private readonly List<string> _commuteServiceDownReplies = [];
|
||||
private readonly List<JiboConditionedReply> _emotionReplies = [];
|
||||
private readonly List<string> _fallbacks = [];
|
||||
private readonly List<string> _greetings = [];
|
||||
private readonly List<string> _jokes = [];
|
||||
private readonly List<string> _robotFacts = [];
|
||||
private readonly List<string> _humanFacts = [];
|
||||
private readonly List<string> _howAreYous = [];
|
||||
private readonly List<string> _funFacts = [];
|
||||
private readonly List<string> _greetings = [];
|
||||
private readonly List<string> _howAreYous = [];
|
||||
private readonly List<string> _humanFacts = [];
|
||||
private readonly List<string> _jokes = [];
|
||||
private readonly List<string> _newsCategoryIntroReplies = [];
|
||||
private readonly List<string> _newsIntroReplies = [];
|
||||
private readonly List<string> _newsOutroReplies = [];
|
||||
@@ -390,6 +389,7 @@ public static class LegacyMimCatalogImporter
|
||||
private readonly List<string> _personalReportKickOffReplies = [];
|
||||
private readonly List<string> _personalReportOutroReplies = [];
|
||||
private readonly List<string> _reportSkillTemplates = [];
|
||||
private readonly List<string> _robotFacts = [];
|
||||
private readonly List<string> _weatherIntroReplies = [];
|
||||
private readonly List<string> _weatherServiceDownReplies = [];
|
||||
private readonly List<string> _weatherTodayHighLowReplies = [];
|
||||
@@ -564,7 +564,8 @@ public static class LegacyMimCatalogImporter
|
||||
private LegacyMimBucket ResolveFunFactTarget(string prompt)
|
||||
{
|
||||
var lowered = NormalizePrompt(prompt, false).ToLowerInvariant();
|
||||
if (ContainsAny(lowered, "robot", "humanoid", "machine", "about me", "my cameras", "turing", "deep blue", "rossum"))
|
||||
if (ContainsAny(lowered, "robot", "humanoid", "machine", "about me", "my cameras", "turing", "deep blue",
|
||||
"rossum"))
|
||||
return LegacyMimBucket.RobotFacts;
|
||||
|
||||
if (ContainsAny(lowered, "human", "people", "grown ups", "human being", "humans"))
|
||||
@@ -607,4 +608,4 @@ public static class LegacyMimCatalogImporter
|
||||
|
||||
[JsonPropertyName("weight")] public double? Weight { get; init; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -67,7 +67,8 @@ public static class ServiceCollectionExtensions
|
||||
configuration.GetSection("OpenJibo:Media").Bind(mediaOptions);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(mediaOptions.ConnectionString))
|
||||
mediaOptions.ConnectionString = Environment.GetEnvironmentVariable("OPENJIBO_MEDIA_STORAGE_CONNECTION_STRING");
|
||||
mediaOptions.ConnectionString =
|
||||
Environment.GetEnvironmentVariable("OPENJIBO_MEDIA_STORAGE_CONNECTION_STRING");
|
||||
|
||||
services.AddSingleton<IPersistenceSnapshotStoreFactory, PersistenceSnapshotStoreFactory>();
|
||||
services.AddSingleton<IMediaContentStoreFactory, MediaContentStoreFactory>();
|
||||
@@ -116,4 +117,4 @@ public static class ServiceCollectionExtensions
|
||||
? backendKind
|
||||
: PersistenceBackendKind.File;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -30,14 +30,14 @@ internal sealed class AzureBlobMediaContentStore : IMediaContentStore
|
||||
var contentBlob = _containerClient.GetBlobClient($"{relative}.bin");
|
||||
var metaBlob = _containerClient.GetBlobClient($"{relative}.json");
|
||||
await _containerClient.CreateIfNotExistsAsync(cancellationToken: cancellationToken);
|
||||
await contentBlob.UploadAsync(new MemoryStream(content), overwrite: true, cancellationToken);
|
||||
await contentBlob.UploadAsync(new MemoryStream(content), true, cancellationToken);
|
||||
var payload = JsonSerializer.Serialize(new
|
||||
{
|
||||
path,
|
||||
contentType,
|
||||
meta
|
||||
}, JsonOptions);
|
||||
await metaBlob.UploadAsync(BinaryData.FromString(payload), overwrite: true, cancellationToken);
|
||||
await metaBlob.UploadAsync(BinaryData.FromString(payload), true, cancellationToken);
|
||||
}
|
||||
|
||||
public async Task<MediaContentSnapshot?> LoadAsync(string path, CancellationToken cancellationToken = default)
|
||||
@@ -52,7 +52,6 @@ internal sealed class AzureBlobMediaContentStore : IMediaContentStore
|
||||
var metaBlob = _containerClient.GetBlobClient($"{relative}.json");
|
||||
|
||||
if (await metaBlob.ExistsAsync(cancellationToken))
|
||||
{
|
||||
try
|
||||
{
|
||||
var json = (await metaBlob.DownloadContentAsync(cancellationToken)).Value.Content.ToString();
|
||||
@@ -70,7 +69,6 @@ internal sealed class AzureBlobMediaContentStore : IMediaContentStore
|
||||
{
|
||||
// Keep the raw binary available even if metadata parsing fails.
|
||||
}
|
||||
}
|
||||
|
||||
return new MediaContentSnapshot
|
||||
{
|
||||
@@ -79,4 +77,4 @@ internal sealed class AzureBlobMediaContentStore : IMediaContentStore
|
||||
Meta = meta as IReadOnlyDictionary<string, object?> ?? new Dictionary<string, object?>(meta)
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -53,7 +53,6 @@ internal sealed class FileMediaContentStore : IMediaContentStore
|
||||
IDictionary<string, object?> meta = new Dictionary<string, object?>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
if (File.Exists(metaPath))
|
||||
{
|
||||
try
|
||||
{
|
||||
using var document = JsonDocument.Parse(await File.ReadAllTextAsync(metaPath, cancellationToken));
|
||||
@@ -72,7 +71,6 @@ internal sealed class FileMediaContentStore : IMediaContentStore
|
||||
{
|
||||
// Keep binary content available even if the manifest is malformed.
|
||||
}
|
||||
}
|
||||
|
||||
return new MediaContentSnapshot
|
||||
{
|
||||
@@ -81,4 +79,4 @@ internal sealed class FileMediaContentStore : IMediaContentStore
|
||||
Meta = meta as IReadOnlyDictionary<string, object?> ?? new Dictionary<string, object?>(meta)
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,4 +6,4 @@ internal interface IMediaContentStoreFactory
|
||||
{
|
||||
IMediaContentStore Create(string? directoryPath, MediaContentStoreKind backendKind, string containerName,
|
||||
string? connectionString);
|
||||
}
|
||||
}
|
||||
@@ -13,4 +13,4 @@ internal sealed class MediaContentStoreFactory : IMediaContentStoreFactory
|
||||
_ => new FileMediaContentStore(directoryPath)
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,4 +4,4 @@ public enum MediaContentStoreKind
|
||||
{
|
||||
File,
|
||||
AzureBlob
|
||||
}
|
||||
}
|
||||
@@ -6,4 +6,4 @@ public sealed class MediaContentStoreOptions
|
||||
public string? DirectoryPath { get; set; }
|
||||
public string? ConnectionString { get; set; }
|
||||
public string ContainerName { get; set; } = "openjibo-media";
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,8 @@ internal static class MediaPathHelper
|
||||
public static string GetRelativeStoragePath(string path)
|
||||
{
|
||||
var trimmed = path.Trim().TrimStart('/', '\\');
|
||||
var segments = trimmed.Split(['/', '\\'], StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries)
|
||||
var segments = trimmed
|
||||
.Split(['/', '\\'], StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries)
|
||||
.Select(SanitizeSegment)
|
||||
.Where(segment => !string.IsNullOrWhiteSpace(segment))
|
||||
.ToArray();
|
||||
@@ -20,4 +21,4 @@ internal static class MediaPathHelper
|
||||
.ToArray();
|
||||
return string.Join(string.Empty, chars);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -673,4 +673,4 @@ public sealed class InMemoryCloudStateStore : ICloudStateStore
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,8 @@ internal static class CaptureIndexWriter
|
||||
WriteIndented = false
|
||||
};
|
||||
|
||||
private static readonly ConcurrentDictionary<string, SemaphoreSlim> DirectoryLocks = new(StringComparer.OrdinalIgnoreCase);
|
||||
private static readonly ConcurrentDictionary<string, SemaphoreSlim> DirectoryLocks =
|
||||
new(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
public static async Task AppendAsync(
|
||||
string directoryPath,
|
||||
@@ -45,4 +46,4 @@ internal static class CaptureIndexWriter
|
||||
gate.Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -89,4 +89,4 @@ public sealed class FileProtocolTelemetrySink(
|
||||
$"{envelope.ServicePrefix}.{envelope.Operation}".Trim('.'),
|
||||
result.StatusCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -79,4 +79,4 @@ public sealed class FileTurnTelemetrySink(
|
||||
Directory.GetCurrentDirectory(),
|
||||
AppContext.BaseDirectory);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -291,4 +291,4 @@ public sealed class FileWebSocketTelemetrySink(
|
||||
public CapturedWebSocketFixtureSession Session { get; init; } = new();
|
||||
public List<CapturedWebSocketFixtureStep> Steps { get; } = [];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -218,7 +218,8 @@ public sealed class OpenWeatherReportProvider(
|
||||
var summary = TryReadWeatherSummary(root);
|
||||
var condition = TryReadWeatherCondition(root);
|
||||
var temperature = TryReadInt(main, "temp");
|
||||
var currentDayHighLow = await TryResolveCurrentDayHighLowFromForecastAsync(location, useCelsius, cancellationToken);
|
||||
var currentDayHighLow =
|
||||
await TryResolveCurrentDayHighLowFromForecastAsync(location, useCelsius, cancellationToken);
|
||||
var high = currentDayHighLow?.High ?? TryReadInt(main, "temp_max");
|
||||
var low = currentDayHighLow?.Low ?? TryReadInt(main, "temp_min");
|
||||
|
||||
@@ -509,4 +510,4 @@ public sealed class OpenWeatherReportProvider(
|
||||
int? LowTemperature,
|
||||
string? Summary,
|
||||
string? Condition);
|
||||
}
|
||||
}
|
||||
@@ -92,7 +92,8 @@ public sealed class LegacyMimCatalogImporterTests
|
||||
|
||||
Assert.Contains("I like all the colors of the rainbow. But blue is my favorite.",
|
||||
catalog.PersonalityReplies);
|
||||
Assert.Contains("I never eat, so I don't have a favorite food by taste. But my favorite food by shape, is macaroni.",
|
||||
Assert.Contains(
|
||||
"I never eat, so I don't have a favorite food by taste. But my favorite food by shape, is macaroni.",
|
||||
catalog.PersonalityReplies);
|
||||
Assert.Contains("I mostly like fun music I can dance to.", catalog.PersonalityReplies);
|
||||
Assert.Contains("The only thing I consume is electricity.", catalog.PersonalityReplies);
|
||||
@@ -199,7 +200,8 @@ public sealed class LegacyMimCatalogImporterTests
|
||||
|
||||
var catalog = LegacyMimCatalogImporter.ImportCatalog(rootDirectory);
|
||||
|
||||
Assert.Contains("I love jokes. Did you hear about the theater actor who fell through the floorboards? He was just going through a stage.",
|
||||
Assert.Contains(
|
||||
"I love jokes. Did you hear about the theater actor who fell through the floorboards? He was just going through a stage.",
|
||||
catalog.Jokes);
|
||||
Assert.Contains("Sure I got one. What did the zero say to the eight. Nice belt.", catalog.Jokes);
|
||||
Assert.Contains(catalog.RobotFacts, reply =>
|
||||
@@ -211,7 +213,8 @@ public sealed class LegacyMimCatalogImporterTests
|
||||
Assert.Contains(catalog.RobotFacts, reply =>
|
||||
reply.Contains("two cameras but they're different focal lengths", StringComparison.OrdinalIgnoreCase));
|
||||
Assert.Contains("A random fact for you. A shrimp's heart is in its head.", catalog.FunFacts);
|
||||
Assert.Contains("An amazing but true fact for you. Dogs and elephants are the only animals that understand pointing.",
|
||||
Assert.Contains(
|
||||
"An amazing but true fact for you. Dogs and elephants are the only animals that understand pointing.",
|
||||
catalog.FunFacts);
|
||||
}
|
||||
|
||||
@@ -505,4 +508,4 @@ public sealed class LegacyMimCatalogImporterTests
|
||||
|
||||
return rootDirectory;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -426,7 +426,8 @@ public sealed class ProviderCachingTests
|
||||
entries.Select(entry =>
|
||||
$$"""{"dt":{{entry.Timestamp.ToUnixTimeSeconds()}},"main":{"temp":{{entry.Temp}},"temp_min":{{entry.Low}},"temp_max":{{entry.High}}},"weather":[{"main":"{{entry.Main}}","description":"{{entry.Description}}"}]}"""));
|
||||
|
||||
return $$"""{"city":{"name":"{{cityName}}","country":"{{country}}","timezone":{{timezoneSeconds}}},"list":[{{list}}]}""";
|
||||
return
|
||||
$$"""{"city":{"name":"{{cityName}}","country":"{{country}}","timezone":{{timezoneSeconds}}},"list":[{{list}}]}""";
|
||||
}
|
||||
|
||||
private sealed class CountingHttpMessageHandler(Func<HttpRequestMessage, HttpResponseMessage> responseFactory)
|
||||
@@ -456,4 +457,4 @@ public sealed class ProviderCachingTests
|
||||
return Task.FromResult(responseFactory(request));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -60,8 +60,9 @@ public sealed class FileProtocolTelemetrySinkTests : IDisposable
|
||||
|
||||
Assert.Contains("Notification_20150505", contents);
|
||||
Assert.DoesNotContain(Path.Combine("bin", "Debug"), captureFile, StringComparison.OrdinalIgnoreCase);
|
||||
Assert.Contains(indexLines, line => line.Contains("\"eventType\":\"protocol_record\"", StringComparison.Ordinal));
|
||||
Assert.Contains(indexLines,
|
||||
line => line.Contains("\"eventType\":\"protocol_record\"", StringComparison.Ordinal));
|
||||
Assert.Contains(indexLines, line => line.Contains("\"servicePrefix\":\"Notification_20150505\"",
|
||||
StringComparison.Ordinal));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -163,7 +163,8 @@ public sealed class JiboCloudProtocolServiceTests
|
||||
Method = "POST",
|
||||
ServicePrefix = "Update_20160715",
|
||||
Operation = "CreateUpdate",
|
||||
BodyText = """{"fromVersion":"1.0.0","toVersion":"1.0.1","changes":"Restore proof","subsystem":"robot"}"""
|
||||
BodyText =
|
||||
"""{"fromVersion":"1.0.0","toVersion":"1.0.1","changes":"Restore proof","subsystem":"robot"}"""
|
||||
});
|
||||
|
||||
await firstService.DispatchAsync(new ProtocolEnvelope
|
||||
@@ -209,16 +210,15 @@ public sealed class JiboCloudProtocolServiceTests
|
||||
Assert.NotNull(secondInfo.LastLoadedUtc);
|
||||
Assert.NotNull(secondInfo.LastSavedUtc);
|
||||
Assert.NotEmpty(updatesPayload.RootElement.EnumerateArray());
|
||||
Assert.Contains(updatesPayload.RootElement.EnumerateArray(), item => item.GetProperty("changes").GetString() == "Restore proof");
|
||||
Assert.Contains(updatesPayload.RootElement.EnumerateArray(),
|
||||
item => item.GetProperty("changes").GetString() == "Restore proof");
|
||||
Assert.NotEmpty(backupsPayload.RootElement.EnumerateArray());
|
||||
Assert.Contains(backupsPayload.RootElement.EnumerateArray(), item => item.TryGetProperty("Name", out var name) && name.GetString() == "manual-backup");
|
||||
Assert.Contains(backupsPayload.RootElement.EnumerateArray(),
|
||||
item => item.TryGetProperty("Name", out var name) && name.GetString() == "manual-backup");
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (File.Exists(persistencePath))
|
||||
{
|
||||
File.Delete(persistencePath);
|
||||
}
|
||||
if (File.Exists(persistencePath)) File.Delete(persistencePath);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -345,4 +345,4 @@ public sealed class JiboCloudProtocolServiceTests
|
||||
Assert.Contains(people,
|
||||
person => string.Equals(person.LoopId, store.GetLoops()[0].LoopId, StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -62,9 +62,11 @@ public sealed class FileTurnTelemetrySinkTests
|
||||
var indexPath = Path.Combine(directoryPath, "capture-index.ndjson");
|
||||
var lines = await File.ReadAllLinesAsync(indexPath);
|
||||
|
||||
Assert.Contains(lines, line => line.Contains("\"eventType\":\"yes_no_turn_received\"", StringComparison.Ordinal));
|
||||
Assert.Contains(lines,
|
||||
line => line.Contains("\"eventType\":\"yes_no_turn_received\"", StringComparison.Ordinal));
|
||||
Assert.Contains(lines, line => line.Contains("\"eventType\":\"transcript_error\"", StringComparison.Ordinal));
|
||||
Assert.Contains(lines, line => line.Contains("\"message\":\"Turn telemetry diagnostic\"", StringComparison.Ordinal));
|
||||
Assert.Contains(lines,
|
||||
line => line.Contains("\"message\":\"Turn telemetry diagnostic\"", StringComparison.Ordinal));
|
||||
Assert.Contains(lines, line => line.Contains("\"message\":\"Turn telemetry error\"", StringComparison.Ordinal));
|
||||
}
|
||||
|
||||
@@ -177,4 +179,4 @@ public sealed class FileTurnTelemetrySinkTests
|
||||
It.IsAny<CancellationToken>()),
|
||||
Times.AtLeastOnce());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -146,4 +146,4 @@ public sealed class FileWebSocketTelemetrySinkTests : IDisposable
|
||||
|
||||
return entries;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
using System.Text.Json;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using Jibo.Cloud.Application.Abstractions;
|
||||
using Jibo.Cloud.Application.Services;
|
||||
using Jibo.Cloud.Infrastructure.Content;
|
||||
@@ -3108,7 +3108,8 @@ public sealed class JiboInteractionServiceTests
|
||||
});
|
||||
|
||||
Assert.Equal("robot_can_sleep", decision.IntentName);
|
||||
Assert.Contains("I do. I usually fall asleep at night.", decision.ReplyText, StringComparison.OrdinalIgnoreCase);
|
||||
Assert.Contains("I do. I usually fall asleep at night.", decision.ReplyText,
|
||||
StringComparison.OrdinalIgnoreCase);
|
||||
Assert.Equal("ScriptedResponse", decision.ContextUpdates![ChitchatRouteKey]);
|
||||
}
|
||||
|
||||
@@ -4090,4 +4091,4 @@ public sealed class JiboInteractionServiceTests
|
||||
return Task.FromResult(Snapshot);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
using System.Text.Json;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using Jibo.Cloud.Application.Abstractions;
|
||||
using Jibo.Cloud.Application.Services;
|
||||
using Jibo.Cloud.Domain.Models;
|
||||
@@ -21,7 +21,7 @@ public sealed class JiboWebSocketServiceTests
|
||||
var contentRepository = new InMemoryJiboExperienceContentRepository();
|
||||
var contentCache = new JiboExperienceContentCache(contentRepository);
|
||||
var conversationBroker = new DemoConversationBroker(new JiboInteractionService(contentCache,
|
||||
new LastItemRandomizer(), new InMemoryPersonalMemoryStore(), null, null, null));
|
||||
new LastItemRandomizer(), new InMemoryPersonalMemoryStore()));
|
||||
var sttSelector = new DefaultSttStrategySelector(
|
||||
[
|
||||
new SyntheticBufferedAudioSttStrategy()
|
||||
@@ -2727,7 +2727,8 @@ public sealed class JiboWebSocketServiceTests
|
||||
Path = "/listen",
|
||||
Kind = "neo-hub-listen",
|
||||
Token = "hub-radio-noise-token",
|
||||
Text = """{"type":"CLIENT_ASR","transID":"trans-radio-noise","data":{"text":"Hey Jibo - so open the radio"}}"""
|
||||
Text =
|
||||
"""{"type":"CLIENT_ASR","transID":"trans-radio-noise","data":{"text":"Hey Jibo - so open the radio"}}"""
|
||||
});
|
||||
|
||||
Assert.Equal(4, replies.Count);
|
||||
@@ -4749,7 +4750,8 @@ public sealed class JiboWebSocketServiceTests
|
||||
Path = "/listen",
|
||||
Kind = "neo-hub-listen",
|
||||
Token = token,
|
||||
Text = """{"type":"LISTEN","transID":"trans-smoke-greeting","data":{"text":"hello jibo","rules":["wake-word"]}}"""
|
||||
Text =
|
||||
"""{"type":"LISTEN","transID":"trans-smoke-greeting","data":{"text":"hello jibo","rules":["wake-word"]}}"""
|
||||
});
|
||||
|
||||
Assert.Equal(3, greetingReplies.Count);
|
||||
@@ -4794,7 +4796,8 @@ public sealed class JiboWebSocketServiceTests
|
||||
Path = "/listen",
|
||||
Kind = "neo-hub-listen",
|
||||
Token = token,
|
||||
Text = """{"type":"CLIENT_ASR","transID":"trans-smoke-color","data":{"text":"what is your favorite color"}}"""
|
||||
Text =
|
||||
"""{"type":"CLIENT_ASR","transID":"trans-smoke-color","data":{"text":"what is your favorite color"}}"""
|
||||
});
|
||||
|
||||
Assert.Equal(3, personalityReplies.Count);
|
||||
@@ -5206,4 +5209,4 @@ public sealed class JiboWebSocketServiceTests
|
||||
return items[^1];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -190,7 +190,8 @@ public sealed class LocalWhisperCppBufferedAudioSttStrategyTests
|
||||
return page;
|
||||
}
|
||||
|
||||
private sealed class FakeExternalProcessRunner(string whisperStdOut = "[00:00:00.000 --> 00:00:01.000] tell me a joke")
|
||||
private sealed class FakeExternalProcessRunner(
|
||||
string whisperStdOut = "[00:00:00.000 --> 00:00:01.000] tell me a joke")
|
||||
: IExternalProcessRunner
|
||||
{
|
||||
public List<(string FileName, IReadOnlyList<string> Arguments)> Calls { get; } = [];
|
||||
@@ -208,4 +209,4 @@ public sealed class LocalWhisperCppBufferedAudioSttStrategyTests
|
||||
return Task.FromResult(new ExternalProcessResult(0, string.Empty, string.Empty));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,4 +22,4 @@ public sealed class SyntheticBufferedAudioSttStrategyTests
|
||||
Assert.Equal("synthetic-buffered-audio", result.Provider);
|
||||
Assert.Equal(0.75f, result.Confidence);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user