From bd394ecbcdef5e6570299751308c8777f94acaf8 Mon Sep 17 00:00:00 2001 From: Jacob Dubin Date: Fri, 17 Apr 2026 23:57:52 -0500 Subject: [PATCH] added some logging to see why processing audio is not working --- .../src/Jibo.Cloud.Api/Jibo.Cloud.Api.csproj | 20 +++---- .../dotnet/src/Jibo.Cloud.Api/Program.cs | 27 +++++++-- .../src/Jibo.Cloud.Api/appsettings.json | 4 ++ .../Abstractions/ITurnTelemetrySink.cs | 6 ++ .../Abstractions/IWebSocketTelemetrySink.cs | 2 +- .../Jibo.Cloud.Application.csproj | 18 +++--- .../Services/NullTurnTelemetrySink.cs | 8 +++ .../Services/NullWebSocketTelemetrySink.cs | 2 +- .../WebSocketTurnFinalizationService.cs | 8 ++- .../Jibo.Cloud.Domain.csproj | 10 ++-- .../ServiceCollectionExtensions.cs | 2 + .../Jibo.Cloud.Infrastructure.csproj | 20 +++---- .../Telemetry/FileTurnTelemetrySink.cs | 55 +++++++++++++++++++ .../Telemetry/TurnTelemetryOptions.cs | 7 +++ .../Telemetry/WebSocketTelemetryOptions.cs | 2 +- .../Jibo.Runtime.Abstractions.csproj | 10 ++-- OpenJibo/src/Playground/Playground.csproj | 12 ++-- .../Jibo.Cloud.Tests/Jibo.Cloud.Tests.csproj | 53 +++++++++--------- .../Turn/FileTurnTelemetrySinkTests.cs | 32 +++++++++++ .../FileWebSocketTelemetrySinkTests.cs | 11 ++-- .../WebSockets/JiboWebSocketServiceTests.cs | 17 +++--- 21 files changed, 232 insertions(+), 94 deletions(-) create mode 100644 OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Application/Abstractions/ITurnTelemetrySink.cs create mode 100644 OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Application/Services/NullTurnTelemetrySink.cs create mode 100644 OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Infrastructure/Telemetry/FileTurnTelemetrySink.cs create mode 100644 OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Infrastructure/Telemetry/TurnTelemetryOptions.cs create mode 100644 OpenJibo/tests/Jibo.Cloud.Tests/Turn/FileTurnTelemetrySinkTests.cs diff --git a/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Api/Jibo.Cloud.Api.csproj b/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Api/Jibo.Cloud.Api.csproj index f639144..2818739 100644 --- a/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Api/Jibo.Cloud.Api.csproj +++ b/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Api/Jibo.Cloud.Api.csproj @@ -1,15 +1,15 @@ - - - - - + + + + + - - net10.0 - enable - enable - + + net10.0 + enable + enable + diff --git a/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Api/Program.cs b/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Api/Program.cs index e2194ff..8be0c51 100644 --- a/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Api/Program.cs +++ b/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Api/Program.cs @@ -43,6 +43,7 @@ app.Use(async (context, next) => var webSocketService = context.RequestServices.GetRequiredService(); var telemetrySink = context.RequestServices.GetRequiredService(); + using var socket = await context.WebSockets.AcceptWebSocketAsync(); var openEnvelope = new WebSocketMessageEnvelope @@ -56,15 +57,29 @@ app.Use(async (context, next) => var openSession = ResolveSession(webSocketService, openEnvelope); await telemetrySink.RecordConnectionOpenedAsync(openEnvelope, openSession, context.RequestAborted); + var isPrematureClose = false; + while (socket.State == WebSocketState.Open) { - var received = await ReceiveAsync(socket, context.RequestAborted); - if (received.MessageType == WebSocketMessageType.Close) + ReceivedSocketMessage received = null!; + try { - await socket.CloseAsync(WebSocketCloseStatus.NormalClosure, "bye", context.RequestAborted); - break; + received = await ReceiveAsync(socket, context.RequestAborted); + if (received.MessageType == WebSocketMessageType.Close) + { + await socket.CloseAsync(WebSocketCloseStatus.NormalClosure, "bye", context.RequestAborted); + break; + } } - + catch (WebSocketException exception) + { + if (exception.WebSocketErrorCode == WebSocketError.ConnectionClosedPrematurely) + { + isPrematureClose = true; + break; + } + } + var envelope = new WebSocketMessageEnvelope { ConnectionId = Guid.NewGuid().ToString("N"), @@ -107,7 +122,7 @@ app.Use(async (context, next) => Token = token }; var closeSession = ResolveSession(webSocketService, closeEnvelope); - await telemetrySink.RecordConnectionClosedAsync(closeEnvelope, closeSession, "socket-loop-ended", context.RequestAborted); + await telemetrySink.RecordConnectionClosedAsync(closeEnvelope, closeSession, $"socket-loop-ended{(isPrematureClose ? "-prematurely" : string.Empty)}", context.RequestAborted); }); app.MapGet("/health", () => Results.Json(new { ok = true, service = "OpenJibo Cloud Api" })); diff --git a/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Api/appsettings.json b/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Api/appsettings.json index cb14b27..4bb4436 100644 --- a/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Api/appsettings.json +++ b/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Api/appsettings.json @@ -9,6 +9,10 @@ "Enabled": true, "DirectoryPath": "captures/http" }, + "TurnTelemetry": { + "Enabled": true, + "DirectoryPath": "captures/turn" + }, "Stt": { "EnableLocalWhisperCpp": true, "FfmpegPath": "/usr/bin/ffmpeg", diff --git a/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Application/Abstractions/ITurnTelemetrySink.cs b/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Application/Abstractions/ITurnTelemetrySink.cs new file mode 100644 index 0000000..ed9d5ca --- /dev/null +++ b/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Application/Abstractions/ITurnTelemetrySink.cs @@ -0,0 +1,6 @@ +namespace Jibo.Cloud.Application.Abstractions; + +public interface ITurnTelemetrySink +{ + Task RecordTranscriptError(Exception ex, string message, CancellationToken cancellationToken = default); +} \ No newline at end of file diff --git a/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Application/Abstractions/IWebSocketTelemetrySink.cs b/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Application/Abstractions/IWebSocketTelemetrySink.cs index 495a99a..c954fa6 100644 --- a/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Application/Abstractions/IWebSocketTelemetrySink.cs +++ b/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Application/Abstractions/IWebSocketTelemetrySink.cs @@ -9,4 +9,4 @@ public interface IWebSocketTelemetrySink Task RecordTurnEventAsync(WebSocketMessageEnvelope envelope, CloudSession session, string eventType, IReadOnlyDictionary details, CancellationToken cancellationToken = default); Task RecordOutboundAsync(WebSocketMessageEnvelope envelope, CloudSession session, IReadOnlyList replies, CancellationToken cancellationToken = default); Task RecordConnectionClosedAsync(WebSocketMessageEnvelope envelope, CloudSession session, string reason, CancellationToken cancellationToken = default); -} +} \ No newline at end of file diff --git a/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Application/Jibo.Cloud.Application.csproj b/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Application/Jibo.Cloud.Application.csproj index f8de323..1737e88 100644 --- a/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Application/Jibo.Cloud.Application.csproj +++ b/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Application/Jibo.Cloud.Application.csproj @@ -1,14 +1,14 @@ - - - - + + + + - - net10.0 - enable - enable - + + net10.0 + enable + enable + diff --git a/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Application/Services/NullTurnTelemetrySink.cs b/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Application/Services/NullTurnTelemetrySink.cs new file mode 100644 index 0000000..d31da42 --- /dev/null +++ b/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Application/Services/NullTurnTelemetrySink.cs @@ -0,0 +1,8 @@ +using Jibo.Cloud.Application.Abstractions; + +namespace Jibo.Cloud.Application.Services; + +public sealed class NullTurnTelemetrySink : ITurnTelemetrySink +{ + public Task RecordTranscriptError(Exception ex, string message, CancellationToken cancellationToken = default) => Task.CompletedTask; +} \ No newline at end of file diff --git a/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Application/Services/NullWebSocketTelemetrySink.cs b/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Application/Services/NullWebSocketTelemetrySink.cs index ebd237e..beac1d3 100644 --- a/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Application/Services/NullWebSocketTelemetrySink.cs +++ b/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Application/Services/NullWebSocketTelemetrySink.cs @@ -10,4 +10,4 @@ public sealed class NullWebSocketTelemetrySink : IWebSocketTelemetrySink public Task RecordTurnEventAsync(WebSocketMessageEnvelope envelope, CloudSession session, string eventType, IReadOnlyDictionary details, CancellationToken cancellationToken = default) => Task.CompletedTask; public Task RecordOutboundAsync(WebSocketMessageEnvelope envelope, CloudSession session, IReadOnlyList replies, CancellationToken cancellationToken = default) => Task.CompletedTask; public Task RecordConnectionClosedAsync(WebSocketMessageEnvelope envelope, CloudSession session, string reason, CancellationToken cancellationToken = default) => Task.CompletedTask; -} +} \ No newline at end of file diff --git a/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Application/Services/WebSocketTurnFinalizationService.cs b/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Application/Services/WebSocketTurnFinalizationService.cs index 3b27bd4..166d651 100644 --- a/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Application/Services/WebSocketTurnFinalizationService.cs +++ b/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Application/Services/WebSocketTurnFinalizationService.cs @@ -1,4 +1,5 @@ using System.Text.Json; +using Jibo.Cloud.Application.Abstractions; using Jibo.Cloud.Domain.Models; using Jibo.Runtime.Abstractions; @@ -8,7 +9,9 @@ public sealed class WebSocketTurnFinalizationService( ProtocolToTurnContextMapper turnContextMapper, IConversationBroker conversationBroker, ResponsePlanToSocketMessagesMapper replyMapper, - ISttStrategySelector sttStrategySelector) + ISttStrategySelector sttStrategySelector, + ITurnTelemetrySink sink +) { private const int AutoFinalizeMinBufferedAudioBytes = 12000; private const int AutoFinalizeMinBufferedAudioChunks = 5; @@ -155,8 +158,9 @@ public sealed class WebSocketTurnFinalizationService( Attributes = attributes }; } - catch + catch (Exception ex) { + await sink.RecordTranscriptError(ex, "Error during STT processing", cancellationToken); return turn; } } diff --git a/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Domain/Jibo.Cloud.Domain.csproj b/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Domain/Jibo.Cloud.Domain.csproj index 9ed914b..d75cc3e 100644 --- a/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Domain/Jibo.Cloud.Domain.csproj +++ b/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Domain/Jibo.Cloud.Domain.csproj @@ -1,9 +1,9 @@ - - net10.0 - enable - enable - + + net10.0 + enable + enable + diff --git a/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Infrastructure/DependencyInjection/ServiceCollectionExtensions.cs b/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Infrastructure/DependencyInjection/ServiceCollectionExtensions.cs index 038415b..f87d4ea 100644 --- a/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Infrastructure/DependencyInjection/ServiceCollectionExtensions.cs +++ b/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Infrastructure/DependencyInjection/ServiceCollectionExtensions.cs @@ -19,6 +19,7 @@ public static class ServiceCollectionExtensions { services.Configure(configuration.GetSection("OpenJibo:Telemetry")); services.Configure(configuration.GetSection("OpenJibo:ProtocolTelemetry")); + services.Configure(configuration.GetSection("OpenJibo:TurnTelemetry")); configuration.GetSection("OpenJibo:Stt").Bind(sttOptions); } @@ -35,6 +36,7 @@ public static class ServiceCollectionExtensions services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); + services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); diff --git a/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Infrastructure/Jibo.Cloud.Infrastructure.csproj b/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Infrastructure/Jibo.Cloud.Infrastructure.csproj index 94672ab..d5c18bc 100644 --- a/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Infrastructure/Jibo.Cloud.Infrastructure.csproj +++ b/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Infrastructure/Jibo.Cloud.Infrastructure.csproj @@ -1,15 +1,15 @@ - - - - - + + + + + - - net10.0 - enable - enable - + + net10.0 + enable + enable + diff --git a/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Infrastructure/Telemetry/FileTurnTelemetrySink.cs b/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Infrastructure/Telemetry/FileTurnTelemetrySink.cs new file mode 100644 index 0000000..f3ec998 --- /dev/null +++ b/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Infrastructure/Telemetry/FileTurnTelemetrySink.cs @@ -0,0 +1,55 @@ +using System.Text.Json; +using Jibo.Cloud.Application.Abstractions; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; + +namespace Jibo.Cloud.Infrastructure.Telemetry; + +public sealed class FileTurnTelemetrySink(ILogger logger, + IOptions options) : ITurnTelemetrySink +{ + private static readonly JsonSerializerOptions JsonOptions = new(JsonSerializerDefaults.Web) + { + WriteIndented = true + }; + + private readonly SemaphoreSlim _writeLock = new(1, 1); + + public async Task RecordTranscriptError(Exception ex, string message, CancellationToken cancellationToken = default) + { + if (!options.Value.Enabled) + { + return; + } + + await WriteErrorAsync(ex, message, cancellationToken); + } + + private async Task WriteErrorAsync(Exception ex, string message, CancellationToken cancellationToken) + { + var directory = GetBaseDirectory(); + Directory.CreateDirectory(directory); + var filePath = Path.Combine(directory, $"{DateTimeOffset.UtcNow:yyyyMMdd}.events.ndjson"); + var line = JsonSerializer.Serialize(new { Exception = ex.ToString(), Message = message }, JsonOptions) + Environment.NewLine; + + await _writeLock.WaitAsync(cancellationToken); + try + { + await File.AppendAllTextAsync(filePath, line, cancellationToken); + } + finally + { + _writeLock.Release(); + } + + logger.LogError("Turn telemetry Message={Message} Exception={Exception}", message, ex); + } + + private string GetBaseDirectory() + { + return CapturePathResolver.Resolve( + options.Value.DirectoryPath, + Directory.GetCurrentDirectory(), + AppContext.BaseDirectory); + } +} \ No newline at end of file diff --git a/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Infrastructure/Telemetry/TurnTelemetryOptions.cs b/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Infrastructure/Telemetry/TurnTelemetryOptions.cs new file mode 100644 index 0000000..7966da8 --- /dev/null +++ b/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Infrastructure/Telemetry/TurnTelemetryOptions.cs @@ -0,0 +1,7 @@ +namespace Jibo.Cloud.Infrastructure.Telemetry; + +public sealed class TurnTelemetryOptions +{ + public bool Enabled { get; set; } = true; + public string DirectoryPath { get; set; } = "captures/turn"; +} \ No newline at end of file diff --git a/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Infrastructure/Telemetry/WebSocketTelemetryOptions.cs b/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Infrastructure/Telemetry/WebSocketTelemetryOptions.cs index 5f03e30..b9d87de 100644 --- a/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Infrastructure/Telemetry/WebSocketTelemetryOptions.cs +++ b/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Infrastructure/Telemetry/WebSocketTelemetryOptions.cs @@ -5,4 +5,4 @@ public sealed class WebSocketTelemetryOptions public bool Enabled { get; set; } = true; public bool ExportFixtures { get; set; } = true; public string DirectoryPath { get; set; } = "captures/websocket"; -} +} \ No newline at end of file diff --git a/OpenJibo/src/Jibo.Runtime.Abstractions/Jibo.Runtime.Abstractions.csproj b/OpenJibo/src/Jibo.Runtime.Abstractions/Jibo.Runtime.Abstractions.csproj index b760144..23df897 100644 --- a/OpenJibo/src/Jibo.Runtime.Abstractions/Jibo.Runtime.Abstractions.csproj +++ b/OpenJibo/src/Jibo.Runtime.Abstractions/Jibo.Runtime.Abstractions.csproj @@ -1,9 +1,9 @@  - - net10.0 - enable - enable - + + net10.0 + enable + enable + diff --git a/OpenJibo/src/Playground/Playground.csproj b/OpenJibo/src/Playground/Playground.csproj index ed9781c..917de9f 100644 --- a/OpenJibo/src/Playground/Playground.csproj +++ b/OpenJibo/src/Playground/Playground.csproj @@ -1,10 +1,10 @@  - - Exe - net10.0 - enable - enable - + + Exe + net10.0 + enable + enable + diff --git a/OpenJibo/tests/Jibo.Cloud.Tests/Jibo.Cloud.Tests.csproj b/OpenJibo/tests/Jibo.Cloud.Tests/Jibo.Cloud.Tests.csproj index c95f3c2..5974d0b 100644 --- a/OpenJibo/tests/Jibo.Cloud.Tests/Jibo.Cloud.Tests.csproj +++ b/OpenJibo/tests/Jibo.Cloud.Tests/Jibo.Cloud.Tests.csproj @@ -1,33 +1,34 @@ - - net10.0 - enable - enable - false - + + net10.0 + enable + enable + false + - - - - - + + + + + + - - - - - + + + + + - - - fixtures\%(Filename)%(Extension) - PreserveNewest - - - fixtures\%(Filename)%(Extension) - PreserveNewest - - + + + fixtures\%(Filename)%(Extension) + PreserveNewest + + + fixtures\%(Filename)%(Extension) + PreserveNewest + + diff --git a/OpenJibo/tests/Jibo.Cloud.Tests/Turn/FileTurnTelemetrySinkTests.cs b/OpenJibo/tests/Jibo.Cloud.Tests/Turn/FileTurnTelemetrySinkTests.cs new file mode 100644 index 0000000..ab686c1 --- /dev/null +++ b/OpenJibo/tests/Jibo.Cloud.Tests/Turn/FileTurnTelemetrySinkTests.cs @@ -0,0 +1,32 @@ +using Jibo.Cloud.Application.Abstractions; +using Jibo.Cloud.Application.Services; +using Jibo.Cloud.Domain.Models; +using Jibo.Runtime.Abstractions; +using Moq; + +namespace Jibo.Cloud.Tests.Turn; + +public sealed class FileTurnTelemetrySinkTests +{ + [Fact] + public async Task RecordsTranscriptErrorOnTurnError() + { + var sink = new Mock(); + var sttStrategySelector = new Mock(); + sttStrategySelector.Setup(s => s.SelectAsync(It.IsAny(), It.IsAny())) + .ThrowsAsync(new Exception("dummy")); + + var turnService = new WebSocketTurnFinalizationService( + new ProtocolToTurnContextMapper(), + Mock.Of(), + new ResponsePlanToSocketMessagesMapper(), + sttStrategySelector.Object, + sink.Object + ); + + await turnService.HandleTurnAsync(new CloudSession() { TurnState = { BufferedAudioBytes = 100 }}, new WebSocketMessageEnvelope(), "dummy", + CancellationToken.None); + + sink.Verify(s => s.RecordTranscriptError(It.IsAny(), It.IsAny(), It.IsAny()), Times.Once()); + } +} \ No newline at end of file diff --git a/OpenJibo/tests/Jibo.Cloud.Tests/WebSockets/FileWebSocketTelemetrySinkTests.cs b/OpenJibo/tests/Jibo.Cloud.Tests/WebSockets/FileWebSocketTelemetrySinkTests.cs index 9905402..34ed462 100644 --- a/OpenJibo/tests/Jibo.Cloud.Tests/WebSockets/FileWebSocketTelemetrySinkTests.cs +++ b/OpenJibo/tests/Jibo.Cloud.Tests/WebSockets/FileWebSocketTelemetrySinkTests.cs @@ -36,9 +36,12 @@ public sealed class FileWebSocketTelemetrySinkTests : IDisposable { Token = "token-1", HostName = "neo-hub.jibo.com", - Path = "/listen" + Path = "/listen", + TurnState = + { + TransId = "trans-1" + } }; - session.TurnState.TransId = "trans-1"; await sink.RecordConnectionOpenedAsync(envelope, session); await sink.RecordInboundAsync(envelope, session, "LISTEN"); @@ -70,7 +73,7 @@ public sealed class FileWebSocketTelemetrySinkTests : IDisposable { Directory.CreateDirectory(_repoRoot); Directory.CreateDirectory(_appBaseDirectory); - File.WriteAllText(Path.Combine(_repoRoot, "OpenJibo.slnx"), string.Empty); + await File.WriteAllTextAsync(Path.Combine(_repoRoot, "OpenJibo.slnx"), string.Empty); var captureDirectory = CapturePathResolver.Resolve("captures/websocket", _repoRoot, _appBaseDirectory); var sink = new FileWebSocketTelemetrySink( @@ -118,4 +121,4 @@ public sealed class FileWebSocketTelemetrySinkTests : IDisposable DirectoryPath = _directoryPath })); } -} +} \ No newline at end of file diff --git a/OpenJibo/tests/Jibo.Cloud.Tests/WebSockets/JiboWebSocketServiceTests.cs b/OpenJibo/tests/Jibo.Cloud.Tests/WebSockets/JiboWebSocketServiceTests.cs index 2beb93d..2a42198 100644 --- a/OpenJibo/tests/Jibo.Cloud.Tests/WebSockets/JiboWebSocketServiceTests.cs +++ b/OpenJibo/tests/Jibo.Cloud.Tests/WebSockets/JiboWebSocketServiceTests.cs @@ -1,5 +1,4 @@ using System.Text.Json; -using Jibo.Cloud.Application.Abstractions; using Jibo.Cloud.Application.Services; using Jibo.Cloud.Domain.Models; using Jibo.Cloud.Infrastructure.Content; @@ -25,6 +24,7 @@ public sealed class JiboWebSocketServiceTests [ new SyntheticBufferedAudioSttStrategy() ]); + var sink = new NullTurnTelemetrySink(); _service = new JiboWebSocketService( _store, @@ -33,7 +33,8 @@ public sealed class JiboWebSocketServiceTests turnContextMapper, conversationBroker, replyMapper, - sttSelector)); + sttSelector, + sink)); } [Fact] @@ -118,7 +119,7 @@ public sealed class JiboWebSocketServiceTests Text = """{"type":"CONTEXT","transID":"trans-auto","data":{"audioTranscriptHint":"tell me a joke"}}""" }); - IReadOnlyList replies = []; + IReadOnlyList replies; for (var index = 0; index < 4; index += 1) { replies = await _service.HandleMessageAsync(new WebSocketMessageEnvelope @@ -175,7 +176,7 @@ public sealed class JiboWebSocketServiceTests Text = """{"type":"CONTEXT","transID":"trans-auto-fallback","data":{"topic":"conversation"}}""" }); - IReadOnlyList replies = []; + IReadOnlyList replies; for (var index = 0; index < 4; index += 1) { replies = await _service.HandleMessageAsync(new WebSocketMessageEnvelope @@ -249,7 +250,7 @@ public sealed class JiboWebSocketServiceTests var session = _store.FindSessionByToken("hub-multichunk-token"); Assert.NotNull(session); - Assert.Equal(7, session!.TurnState.BufferedAudioBytes); + Assert.Equal(7, session.TurnState.BufferedAudioBytes); Assert.Equal(2, session.TurnState.BufferedAudioChunkCount); } @@ -292,7 +293,7 @@ public sealed class JiboWebSocketServiceTests var session = _store.FindSessionByToken("hub-follow-up-token"); Assert.NotNull(session); - Assert.True(session!.FollowUpOpen); + Assert.True(session.FollowUpOpen); Assert.Equal("joke", session.LastIntent); Assert.Equal("trans-follow-up", session.LastTransId); } @@ -393,7 +394,7 @@ public sealed class JiboWebSocketServiceTests var session = _store.FindSessionByToken("hub-audio-token"); Assert.NotNull(session); - Assert.Equal(0, session!.TurnState.BufferedAudioBytes); + Assert.Equal(0, session.TurnState.BufferedAudioBytes); Assert.Equal(0, session.TurnState.BufferedAudioChunkCount); Assert.False(session.Metadata.ContainsKey("audioTranscriptHint")); } @@ -632,7 +633,7 @@ public sealed class JiboWebSocketServiceTests var session = _store.FindSessionByToken("hub-followup-audio-token"); Assert.NotNull(session); - Assert.Equal("trans-second", session!.TurnState.TransId); + Assert.Equal("trans-second", session.TurnState.TransId); Assert.Equal(0, session.TurnState.BufferedAudioBytes); Assert.Equal(0, session.TurnState.BufferedAudioChunkCount); }