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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user