a little code cleanup

This commit is contained in:
Jacob Dubin
2026-04-18 00:54:56 -05:00
parent bd394ecbcd
commit e4f8d6940d
17 changed files with 95 additions and 121 deletions

View File

@@ -35,7 +35,7 @@ app.Use(async (context, next) =>
return; return;
} }
if ((kind is "neo-hub-listen" or "neo-hub-proactive") && string.IsNullOrWhiteSpace(token)) if (kind is "neo-hub-listen" or "neo-hub-proactive" && string.IsNullOrWhiteSpace(token))
{ {
context.Response.StatusCode = StatusCodes.Status401Unauthorized; context.Response.StatusCode = StatusCodes.Status401Unauthorized;
return; return;

View File

@@ -9,11 +9,8 @@ public sealed class DefaultSttStrategySelector(IEnumerable<ISttStrategy> strateg
public Task<ISttStrategy> SelectAsync(TurnContext turn, CancellationToken cancellationToken = default) public Task<ISttStrategy> SelectAsync(TurnContext turn, CancellationToken cancellationToken = default)
{ {
var strategy = _strategies.FirstOrDefault(candidate => candidate.CanHandle(turn)); var strategy = _strategies.FirstOrDefault(candidate => candidate.CanHandle(turn));
if (strategy is null) return strategy is null
{ ? throw new InvalidOperationException("No STT strategy can handle the current turn.")
throw new InvalidOperationException("No STT strategy can handle the current turn."); : Task.FromResult(strategy);
}
return Task.FromResult(strategy);
} }
} }

View File

@@ -9,11 +9,8 @@ public sealed class DefaultJiboRandomizer : IJiboRandomizer
{ {
public T Choose<T>(IReadOnlyList<T> items) public T Choose<T>(IReadOnlyList<T> items)
{ {
if (items.Count == 0) return items.Count == 0
{ ? throw new InvalidOperationException("Cannot choose from an empty list.")
throw new InvalidOperationException("Cannot choose from an empty list."); : items[Random.Shared.Next(items.Count)];
}
return items[Random.Shared.Next(items.Count)];
} }
} }

View File

@@ -317,7 +317,7 @@ public sealed class JiboCloudProtocolService(ICloudStateStore stateStore)
}).ToArray()); }).ToArray());
} }
private ProtocolDispatchResult HandleLog(string operation, ProtocolEnvelope envelope) private static ProtocolDispatchResult HandleLog(string operation, ProtocolEnvelope envelope)
{ {
return operation switch return operation switch
{ {
@@ -393,22 +393,16 @@ public sealed class JiboCloudProtocolService(ICloudStateStore stateStore)
private ProtocolDispatchResult HandlePerson(string operation) private ProtocolDispatchResult HandlePerson(string operation)
{ {
if (operation.Equals("ListHolidays", StringComparison.OrdinalIgnoreCase)) return ProtocolDispatchResult.Ok(operation.Equals("ListHolidays", StringComparison.OrdinalIgnoreCase)
{ ? stateStore.GetHolidays()
return ProtocolDispatchResult.Ok(stateStore.GetHolidays()); : []);
}
return ProtocolDispatchResult.Ok(Array.Empty<object>());
} }
private ProtocolDispatchResult HandleBackup(string operation) private ProtocolDispatchResult HandleBackup(string operation)
{ {
if (operation.Equals("List", StringComparison.OrdinalIgnoreCase)) return operation.Equals("List", StringComparison.OrdinalIgnoreCase)
{ ? ProtocolDispatchResult.Ok(stateStore.GetBackups())
return ProtocolDispatchResult.Ok(stateStore.GetBackups()); : ProtocolDispatchResult.Ok(Array.Empty<object>());
}
return ProtocolDispatchResult.Ok(Array.Empty<object>());
} }
private ProtocolDispatchResult HandleKey(string operation, ProtocolEnvelope envelope) private ProtocolDispatchResult HandleKey(string operation, ProtocolEnvelope envelope)

View File

@@ -80,12 +80,10 @@ public sealed class JiboInteractionService(
return "Good afternoon. I am happy to be here."; return "Good afternoon. I am happy to be here.";
} }
if (lowered.Contains("good night", StringComparison.Ordinal)) return lowered.Contains("good night", StringComparison.Ordinal)
{ ? "Good night. Sleep tight."
return "Good night. Sleep tight."; : randomizer.Choose(catalog.GenericFallbackReplies)
} .Replace("{transcript}", transcript, StringComparison.Ordinal);
return randomizer.Choose(catalog.GenericFallbackReplies).Replace("{transcript}", transcript, StringComparison.Ordinal);
} }
private static string ResolveSemanticIntent(string loweredTranscript, string? clientIntent) private static string ResolveSemanticIntent(string loweredTranscript, string? clientIntent)

View File

@@ -1,7 +1,6 @@
using System.Text.Json; using System.Text.Json;
using Jibo.Cloud.Application.Abstractions; using Jibo.Cloud.Application.Abstractions;
using Jibo.Cloud.Domain.Models; using Jibo.Cloud.Domain.Models;
using Jibo.Runtime.Abstractions;
namespace Jibo.Cloud.Application.Services; namespace Jibo.Cloud.Application.Services;

View File

@@ -6,7 +6,7 @@ namespace Jibo.Cloud.Application.Services;
public sealed class ProtocolToTurnContextMapper public sealed class ProtocolToTurnContextMapper
{ {
public TurnContext MapListenMessage(WebSocketMessageEnvelope envelope, CloudSession session, string messageType) public static TurnContext MapListenMessage(WebSocketMessageEnvelope envelope, CloudSession session, string messageType)
{ {
var turnState = session.TurnState; var turnState = session.TurnState;
var protocolOperation = messageType.ToLowerInvariant(); var protocolOperation = messageType.ToLowerInvariant();

View File

@@ -6,7 +6,7 @@ namespace Jibo.Cloud.Application.Services;
public sealed class ResponsePlanToSocketMessagesMapper public sealed class ResponsePlanToSocketMessagesMapper
{ {
public IReadOnlyList<SocketReplyPlan> Map(ResponsePlan plan, TurnContext turn, CloudSession session, bool emitSkillActions) public static IReadOnlyList<SocketReplyPlan> Map(ResponsePlan plan, TurnContext turn, CloudSession session, bool emitSkillActions)
{ {
var speak = plan.Actions.OfType<SpeakAction>().FirstOrDefault(); var speak = plan.Actions.OfType<SpeakAction>().FirstOrDefault();
var skill = plan.Actions.OfType<InvokeNativeSkillAction>().FirstOrDefault(); var skill = plan.Actions.OfType<InvokeNativeSkillAction>().FirstOrDefault();
@@ -18,50 +18,50 @@ public sealed class ResponsePlanToSocketMessagesMapper
var clientIntent = ReadAttribute(turn, "clientIntent"); var clientIntent = ReadAttribute(turn, "clientIntent");
var rules = ReadRules(turn, messageType); var rules = ReadRules(turn, messageType);
var outboundIntent = string.Equals(messageType, "CLIENT_NLU", StringComparison.OrdinalIgnoreCase) && !string.IsNullOrWhiteSpace(clientIntent) var outboundIntent = string.Equals(messageType, "CLIENT_NLU", StringComparison.OrdinalIgnoreCase) && !string.IsNullOrWhiteSpace(clientIntent)
? clientIntent! ? clientIntent
: plan.IntentName ?? "unknown"; : plan.IntentName ?? "unknown";
var outboundAsrText = string.Equals(messageType, "CLIENT_NLU", StringComparison.OrdinalIgnoreCase) && !string.IsNullOrWhiteSpace(clientIntent) var outboundAsrText = string.Equals(messageType, "CLIENT_NLU", StringComparison.OrdinalIgnoreCase) && !string.IsNullOrWhiteSpace(clientIntent)
? clientIntent! ? clientIntent
: transcript; : transcript;
var entities = ReadEntities(turn, messageType); var entities = ReadEntities(turn, messageType);
var messages = new List<SocketReplyPlan>(); var messages = new List<SocketReplyPlan>
messages.Add(new SocketReplyPlan(JsonSerializer.Serialize(new
{ {
type = "LISTEN", new(JsonSerializer.Serialize(new
transID = transId,
data = new
{ {
asr = new type = "LISTEN",
transID = transId,
data = new
{ {
confidence = 0.95, asr = new
final = true, {
text = outboundAsrText confidence = 0.95,
}, final = true,
nlu = new text = outboundAsrText
{ },
confidence = 0.95, nlu = new
intent = outboundIntent, {
rules, confidence = 0.95,
entities intent = outboundIntent,
}, rules,
match = new entities
{ },
intent = outboundIntent, match = new
rule = rules.FirstOrDefault() ?? string.Empty, {
score = 0.95 intent = outboundIntent,
rule = rules.FirstOrDefault() ?? string.Empty,
score = 0.95
}
} }
} })),
}))); new(JsonSerializer.Serialize(new
{
messages.Add(new SocketReplyPlan(JsonSerializer.Serialize(new type = "EOS",
{ ts = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
type = "EOS", msgID = CreateHubMessageId(),
ts = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(), transID = transId,
msgID = CreateHubMessageId(), data = new { }
transID = transId, }))
data = new { } };
})));
if (emitSkillActions && speak is not null) if (emitSkillActions && speak is not null)
{ {
@@ -73,7 +73,7 @@ public sealed class ResponsePlanToSocketMessagesMapper
return messages; return messages;
} }
public IReadOnlyList<SocketReplyPlan> MapFallback(CloudSession session, string transId, IReadOnlyList<string> rules) public static IReadOnlyList<SocketReplyPlan> MapFallback(CloudSession session, string transId, IReadOnlyList<string> rules)
{ {
return return
[ [
@@ -149,7 +149,7 @@ public sealed class ResponsePlanToSocketMessagesMapper
return value switch return value switch
{ {
JsonElement jsonElement when jsonElement.ValueKind == JsonValueKind.Object => jsonElement, JsonElement { ValueKind: JsonValueKind.Object } jsonElement => jsonElement,
IDictionary<string, object?> dictionary => dictionary, IDictionary<string, object?> dictionary => dictionary,
_ => new Dictionary<string, object?>() _ => new Dictionary<string, object?>()
}; };

View File

@@ -260,7 +260,7 @@ public sealed class WebSocketTurnFinalizationService(
bool allowFallbackOnMissingTranscript, bool allowFallbackOnMissingTranscript,
CancellationToken cancellationToken) CancellationToken cancellationToken)
{ {
var turn = turnContextMapper.MapListenMessage(envelope, session, messageType); var turn = ProtocolToTurnContextMapper.MapListenMessage(envelope, session, messageType);
var finalizedTurn = await ResolveTranscriptAsync(turn, session, cancellationToken); var finalizedTurn = await ResolveTranscriptAsync(turn, session, cancellationToken);
var turnState = session.TurnState; var turnState = session.TurnState;
if (string.IsNullOrWhiteSpace(finalizedTurn.NormalizedTranscript) && if (string.IsNullOrWhiteSpace(finalizedTurn.NormalizedTranscript) &&
@@ -278,7 +278,7 @@ public sealed class WebSocketTurnFinalizationService(
session.LastTranscript = string.Empty; session.LastTranscript = string.Empty;
session.LastIntent = "heyJibo"; session.LastIntent = "heyJibo";
session.LastListenType = "fallback"; session.LastListenType = "fallback";
var fallbackReplies = replyMapper.MapFallback(session, turnState.TransId ?? session.LastTransId ?? string.Empty, turnState.ListenRules) var fallbackReplies = ResponsePlanToSocketMessagesMapper.MapFallback(session, turnState.TransId ?? session.LastTransId ?? string.Empty, turnState.ListenRules)
.Select(map => new WebSocketReply { Text = map.Text, DelayMs = map.DelayMs }) .Select(map => new WebSocketReply { Text = map.Text, DelayMs = map.DelayMs })
.ToArray(); .ToArray();
ResetBufferedAudio(session); ResetBufferedAudio(session);
@@ -318,7 +318,7 @@ public sealed class WebSocketTurnFinalizationService(
turnState.AwaitingTurnCompletion = false; turnState.AwaitingTurnCompletion = false;
var emitSkillActions = messageType != "CLIENT_NLU"; var emitSkillActions = messageType != "CLIENT_NLU";
var replies = replyMapper.Map(plan, finalizedTurn, session, emitSkillActions).Select(map => new WebSocketReply var replies = ResponsePlanToSocketMessagesMapper.Map(plan, finalizedTurn, session, emitSkillActions).Select(map => new WebSocketReply
{ {
Text = map.Text, Text = map.Text,
DelayMs = map.DelayMs DelayMs = map.DelayMs
@@ -332,10 +332,11 @@ public sealed class WebSocketTurnFinalizationService(
{ {
var turnState = session.TurnState; var turnState = session.TurnState;
return turnState.AwaitingTurnCompletion && return turnState.AwaitingTurnCompletion &&
turnState.SawListen && turnState is
turnState.SawContext && {
turnState.BufferedAudioChunkCount >= AutoFinalizeMinBufferedAudioChunks && SawListen: true, SawContext: true, BufferedAudioChunkCount: >= AutoFinalizeMinBufferedAudioChunks,
turnState.BufferedAudioBytes >= AutoFinalizeMinBufferedAudioBytes; BufferedAudioBytes: >= AutoFinalizeMinBufferedAudioBytes
};
} }
private static string? ExtractDataPayload(string? text) private static string? ExtractDataPayload(string? text)

View File

@@ -32,11 +32,9 @@ public sealed class ExternalProcessRunner : IExternalProcessRunner
var stdOut = await stdOutTask; var stdOut = await stdOutTask;
var stdErr = await stdErrTask; var stdErr = await stdErrTask;
if (process.ExitCode != 0) return process.ExitCode != 0
{ ? throw new InvalidOperationException(
throw new InvalidOperationException($"External process '{fileName}' failed with exit code {process.ExitCode}: {stdErr}"); $"External process '{fileName}' failed with exit code {process.ExitCode}: {stdErr}")
} : new ExternalProcessResult(process.ExitCode, stdOut, stdErr);
return new ExternalProcessResult(process.ExitCode, stdOut, stdErr);
} }
} }

View File

@@ -92,7 +92,7 @@ public sealed class LocalWhisperCppBufferedAudioSttStrategy(
byte[][] jagged => jagged, byte[][] jagged => jagged,
IReadOnlyList<byte[]> typed => typed, IReadOnlyList<byte[]> typed => typed,
IEnumerable<byte[]> enumerable => enumerable.ToArray(), IEnumerable<byte[]> enumerable => enumerable.ToArray(),
JsonElement jsonElement when jsonElement.ValueKind == JsonValueKind.Array => jsonElement.EnumerateArray() JsonElement { ValueKind: JsonValueKind.Array } jsonElement => jsonElement.EnumerateArray()
.Where(static item => item.ValueKind == JsonValueKind.Array) .Where(static item => item.ValueKind == JsonValueKind.Array)
.Select(static item => item.EnumerateArray().Select(static b => (byte)b.GetInt32()).ToArray()) .Select(static item => item.EnumerateArray().Select(static b => (byte)b.GetInt32()).ToArray())
.ToArray(), .ToArray(),
@@ -128,12 +128,7 @@ public sealed class LocalWhisperCppBufferedAudioSttStrategy(
.Where(static line => !string.IsNullOrWhiteSpace(line)) .Where(static line => !string.IsNullOrWhiteSpace(line))
.ToArray(); .ToArray();
if (timecoded.Length > 0) return timecoded.Length > 0 ? string.Join(" ", timecoded).Trim() : string.Join(" ", lines).Trim();
{
return string.Join(" ", timecoded).Trim();
}
return string.Join(" ", lines).Trim();
} }
private static void TryDelete(string path) private static void TryDelete(string path)

View File

@@ -72,12 +72,9 @@ internal static class OggOpusAudioNormalizer
} }
var expectedLength = 27 + pageSegments + payloadLength; var expectedLength = 27 + pageSegments + payloadLength;
if (buffer.Length < expectedLength) return buffer.Length < expectedLength
{ ? throw new InvalidOperationException("Buffered Ogg page payload was truncated.")
throw new InvalidOperationException("Buffered Ogg page payload was truncated."); : new ParsedOggPage(BinaryPrimitives.ReadUInt64LittleEndian(buffer.AsSpan(6, 8)));
}
return new ParsedOggPage(BinaryPrimitives.ReadUInt64LittleEndian(buffer.AsSpan(6, 8)));
} }
private static uint ComputeCrc(byte[] buffer) private static uint ComputeCrc(byte[] buffer)

View File

@@ -22,7 +22,7 @@ internal static class CapturePathResolver
} }
var directory = new DirectoryInfo(Path.GetFullPath(startPath)); var directory = new DirectoryInfo(Path.GetFullPath(startPath));
if (!directory.Exists && directory.Parent is not null) if (directory is { Exists: false, Parent: not null })
{ {
directory = directory.Parent; directory = directory.Parent;
} }

View File

@@ -42,22 +42,18 @@ public sealed class FileWebSocketTelemetrySink(
public Task RecordInboundAsync(WebSocketMessageEnvelope envelope, CloudSession session, string? messageType, CancellationToken cancellationToken = default) public Task RecordInboundAsync(WebSocketMessageEnvelope envelope, CloudSession session, string? messageType, CancellationToken cancellationToken = default)
{ {
if (!options.Value.Enabled) return !options.Value.Enabled
{ ? Task.CompletedTask
return Task.CompletedTask; : WriteRecordAsync(BuildRecord("message_in", envelope, session, messageType, "in", null, null),
} cancellationToken);
return WriteRecordAsync(BuildRecord("message_in", envelope, session, messageType, "in", null, null), cancellationToken);
} }
public Task RecordTurnEventAsync(WebSocketMessageEnvelope envelope, CloudSession session, string eventType, IReadOnlyDictionary<string, object?> details, CancellationToken cancellationToken = default) public Task RecordTurnEventAsync(WebSocketMessageEnvelope envelope, CloudSession session, string eventType, IReadOnlyDictionary<string, object?> details, CancellationToken cancellationToken = default)
{ {
if (!options.Value.Enabled) return !options.Value.Enabled
{ ? Task.CompletedTask
return Task.CompletedTask; : WriteRecordAsync(BuildRecord(eventType, envelope, session, null, "internal", null, details),
} cancellationToken);
return WriteRecordAsync(BuildRecord(eventType, envelope, session, null, "internal", null, details), cancellationToken);
} }
public async Task RecordOutboundAsync(WebSocketMessageEnvelope envelope, CloudSession session, IReadOnlyList<WebSocketReply> replies, CancellationToken cancellationToken = default) public async Task RecordOutboundAsync(WebSocketMessageEnvelope envelope, CloudSession session, IReadOnlyList<WebSocketReply> replies, CancellationToken cancellationToken = default)

View File

@@ -177,6 +177,8 @@ while (!cts.IsCancellationRequested)
} }
} }
return;
static string PickBestUtterance(List<AsrUtterance>? utterances) static string PickBestUtterance(List<AsrUtterance>? utterances)
{ {
if (utterances == null || utterances.Count == 0) if (utterances == null || utterances.Count == 0)
@@ -201,7 +203,7 @@ static string NormalizeUtterance(string? text)
// Very light cleanup for occasional weird leading duplication like "wWhat" // Very light cleanup for occasional weird leading duplication like "wWhat"
if (s.Length >= 2 && char.ToLowerInvariant(s[0]) == char.ToLowerInvariant(s[1])) if (s.Length >= 2 && char.ToLowerInvariant(s[0]) == char.ToLowerInvariant(s[1]))
s = s.Substring(1); s = s[1..];
return s; return s;
} }
@@ -216,10 +218,7 @@ static string BuildReply(string heard)
if (text.Contains("hello") || text.Contains("hi")) if (text.Contains("hello") || text.Contains("hi"))
return "Hello! I heard you loud and clear."; return "Hello! I heard you loud and clear.";
if (text.Contains("your name")) return text.Contains("your name") ? "I am Jibo, running with a local demo bridge." : $"You said: {heard}";
return "I am Jibo, running with a local demo bridge.";
return $"You said: {heard}";
} }
public sealed class AsrEvent public sealed class AsrEvent

View File

@@ -98,9 +98,12 @@ public sealed class FileWebSocketTelemetrySinkTests : IDisposable
{ {
Token = "token-relative", Token = "token-relative",
HostName = "neo-hub.jibo.com", HostName = "neo-hub.jibo.com",
Path = "/listen" Path = "/listen",
TurnState =
{
TransId = "trans-relative"
}
}; };
session.TurnState.TransId = "trans-relative";
await sink.RecordConnectionOpenedAsync(envelope, session); await sink.RecordConnectionOpenedAsync(envelope, session);
await sink.RecordOutboundAsync(envelope, session, [new WebSocketReply { Text = """{"type":"LISTEN"}""" }]); await sink.RecordOutboundAsync(envelope, session, [new WebSocketReply { Text = """{"type":"LISTEN"}""" }]);

View File

@@ -105,8 +105,8 @@ public sealed class LocalWhisperCppBufferedAudioSttStrategyTests
if (string.Equals(fileName, "ffmpeg", StringComparison.OrdinalIgnoreCase)) if (string.Equals(fileName, "ffmpeg", StringComparison.OrdinalIgnoreCase))
{ {
var outputPath = arguments.Last(); var outputPath = arguments[^1];
File.WriteAllBytes(outputPath, [0x52, 0x49, 0x46, 0x46]); File.WriteAllBytes(outputPath, "RIFF"u8);
return Task.FromResult(new ExternalProcessResult(0, string.Empty, string.Empty)); return Task.FromResult(new ExternalProcessResult(0, string.Empty, string.Empty));
} }