Files
JiboExperiments/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Application/Services/ProtocolToTurnContextMapper.cs

160 lines
5.6 KiB
C#
Raw Normal View History

using System.Text.Json;
using Jibo.Cloud.Domain.Models;
using Jibo.Runtime.Abstractions;
namespace Jibo.Cloud.Application.Services;
public sealed class ProtocolToTurnContextMapper
{
2026-04-18 00:54:56 -05:00
public static TurnContext MapListenMessage(WebSocketMessageEnvelope envelope, CloudSession session, string messageType)
{
2026-04-12 08:31:33 -05:00
var turnState = session.TurnState;
2026-04-11 21:50:26 -05:00
var protocolOperation = messageType.ToLowerInvariant();
var attributes = new Dictionary<string, object?>(StringComparer.OrdinalIgnoreCase)
{
["messageType"] = messageType
};
var text = ExtractTranscript(envelope.Text, attributes);
2026-04-11 21:50:26 -05:00
2026-04-12 08:31:33 -05:00
if (!string.IsNullOrWhiteSpace(turnState.TransId))
2026-04-11 21:50:26 -05:00
{
2026-04-12 08:31:33 -05:00
attributes["transID"] = turnState.TransId;
2026-04-11 21:50:26 -05:00
}
if (!string.IsNullOrWhiteSpace(session.AccountId))
{
attributes["accountId"] = session.AccountId;
}
if (!string.IsNullOrWhiteSpace(session.DeviceId))
{
attributes["deviceId"] = session.DeviceId;
}
if (session.Metadata.TryGetValue("loopId", out var loopId) &&
loopId is string loopIdText &&
!string.IsNullOrWhiteSpace(loopIdText))
{
attributes["loopId"] = loopIdText;
}
2026-04-12 08:31:33 -05:00
if (!string.IsNullOrWhiteSpace(turnState.ContextPayload))
2026-04-11 21:50:26 -05:00
{
2026-04-12 08:31:33 -05:00
attributes["context"] = turnState.ContextPayload;
2026-04-11 21:50:26 -05:00
}
2026-04-24 06:55:15 -05:00
if (session.Metadata.TryGetValue("lastClockDomain", out var lastClockDomain) &&
lastClockDomain is string lastClockDomainText &&
!string.IsNullOrWhiteSpace(lastClockDomainText))
{
attributes["lastClockDomain"] = lastClockDomainText;
}
attributes["listenHotphrase"] = turnState.ListenHotphrase;
2026-04-12 08:31:33 -05:00
if (turnState.ListenRules.Count > 0)
2026-04-11 21:50:26 -05:00
{
2026-04-12 08:31:33 -05:00
attributes["listenRules"] = turnState.ListenRules;
2026-04-11 21:50:26 -05:00
}
2026-04-18 17:15:49 -05:00
if (turnState.ListenAsrHints.Count > 0)
{
attributes["listenAsrHints"] = turnState.ListenAsrHints;
}
2026-04-12 08:31:33 -05:00
if (turnState.BufferedAudioBytes > 0)
2026-04-11 22:11:08 -05:00
{
2026-04-12 08:31:33 -05:00
attributes["bufferedAudioBytes"] = turnState.BufferedAudioBytes;
attributes["bufferedAudioChunks"] = turnState.BufferedAudioChunkCount;
attributes["bufferedAudioFrames"] = turnState.BufferedAudioFrames.Select(frame => frame.ToArray()).ToArray();
2026-04-11 22:11:08 -05:00
}
2026-04-12 08:31:33 -05:00
if (!string.IsNullOrWhiteSpace(turnState.AudioTranscriptHint))
2026-04-11 22:11:08 -05:00
{
2026-04-12 08:31:33 -05:00
attributes["audioTranscriptHint"] = turnState.AudioTranscriptHint;
}
if (turnState.FinalizeAttemptCount > 0)
{
attributes["finalizeAttemptCount"] = turnState.FinalizeAttemptCount;
2026-04-11 22:11:08 -05:00
}
return new TurnContext
{
SessionId = session.SessionId,
2026-04-11 21:50:26 -05:00
InputMode = session.FollowUpOpen ? TurnInputMode.FollowUp : TurnInputMode.DirectText,
SourceKind = TurnSourceKind.Api,
RawTranscript = text,
NormalizedTranscript = text?.Trim(),
DeviceId = session.DeviceId,
HostName = envelope.HostName,
RequestId = envelope.ConnectionId,
ProtocolService = "neo-hub",
2026-04-11 21:50:26 -05:00
ProtocolOperation = protocolOperation,
FirmwareVersion = session.Metadata.TryGetValue("firmwareVersion", out var firmwareVersion) ? firmwareVersion as string : null,
ApplicationVersion = session.Metadata.TryGetValue("applicationVersion", out var applicationVersion) ? applicationVersion as string : null,
2026-04-11 21:50:26 -05:00
IsFollowUpEligible = true,
Attributes = attributes
};
}
private static string? ExtractTranscript(string? text, IDictionary<string, object?> attributes)
{
if (string.IsNullOrWhiteSpace(text))
{
return null;
}
try
{
using var document = JsonDocument.Parse(text);
var root = document.RootElement;
2026-04-26 20:57:08 -05:00
if (!root.TryGetProperty("data", out var data)) return null;
if (data.TryGetProperty("text", out var transcript) && transcript.ValueKind == JsonValueKind.String)
{
2026-04-26 20:57:08 -05:00
return transcript.GetString();
}
2026-04-11 22:11:08 -05:00
2026-04-26 20:57:08 -05:00
if (data.TryGetProperty("asr", out var asr) &&
asr.ValueKind == JsonValueKind.Object &&
asr.TryGetProperty("text", out var asrText) &&
asrText.ValueKind == JsonValueKind.String)
{
return asrText.GetString();
}
if (data.TryGetProperty("transcriptHint", out var transcriptHint) && transcriptHint.ValueKind == JsonValueKind.String)
{
return transcriptHint.GetString();
}
if (data.TryGetProperty("intent", out var intent) && intent.ValueKind == JsonValueKind.String)
{
attributes["clientIntent"] = intent.GetString();
}
if (data.TryGetProperty("rules", out var rules) && rules.ValueKind == JsonValueKind.Array)
{
attributes["clientRules"] = rules.EnumerateArray()
.Where(item => item.ValueKind == JsonValueKind.String)
.Select(item => item.GetString() ?? string.Empty)
.Where(rule => !string.IsNullOrWhiteSpace(rule))
.ToArray();
}
if (data.TryGetProperty("entities", out var entities) && entities.ValueKind == JsonValueKind.Object)
{
attributes["clientEntities"] = entities.Clone();
}
return intent.ValueKind == JsonValueKind.String ? intent.GetString() : null;
}
catch
{
return text;
}
}
}