fixes for hey jibo
This commit is contained in:
@@ -260,6 +260,7 @@ public sealed class WebSocketTurnFinalizationService(
|
|||||||
(hotphrase.ValueKind == JsonValueKind.True || hotphrase.ValueKind == JsonValueKind.False))
|
(hotphrase.ValueKind == JsonValueKind.True || hotphrase.ValueKind == JsonValueKind.False))
|
||||||
{
|
{
|
||||||
turnState.ListenHotphrase = hotphrase.GetBoolean();
|
turnState.ListenHotphrase = hotphrase.GetBoolean();
|
||||||
|
turnState.HotphraseEmptyTurnCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.TryGetProperty("intent", out var intent) && intent.ValueKind == JsonValueKind.String)
|
if (data.TryGetProperty("intent", out var intent) && intent.ValueKind == JsonValueKind.String)
|
||||||
@@ -310,6 +311,7 @@ public sealed class WebSocketTurnFinalizationService(
|
|||||||
turnState.SawListen = false;
|
turnState.SawListen = false;
|
||||||
turnState.SawContext = false;
|
turnState.SawContext = false;
|
||||||
turnState.ListenHotphrase = false;
|
turnState.ListenHotphrase = false;
|
||||||
|
turnState.HotphraseEmptyTurnCount = 0;
|
||||||
turnState.ListenRules = [];
|
turnState.ListenRules = [];
|
||||||
turnState.ListenAsrHints = [];
|
turnState.ListenAsrHints = [];
|
||||||
}
|
}
|
||||||
@@ -364,6 +366,32 @@ public sealed class WebSocketTurnFinalizationService(
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ShouldIgnoreInitialEmptyHotphraseTurn(finalizedTurn, turnState))
|
||||||
|
{
|
||||||
|
turnState.HotphraseEmptyTurnCount += 1;
|
||||||
|
turnState.AwaitingTurnCompletion = true;
|
||||||
|
return
|
||||||
|
[
|
||||||
|
new WebSocketReply
|
||||||
|
{
|
||||||
|
Text = JsonSerializer.Serialize(new
|
||||||
|
{
|
||||||
|
type = "OPENJIBO_TURN_PENDING",
|
||||||
|
data = new
|
||||||
|
{
|
||||||
|
sessionId = session.SessionId,
|
||||||
|
transID = session.LastTransId,
|
||||||
|
bufferedAudioBytes = turnState.BufferedAudioBytes,
|
||||||
|
bufferedAudioChunks = turnState.BufferedAudioChunkCount,
|
||||||
|
awaitingAudio = turnState.BufferedAudioBytes == 0,
|
||||||
|
awaitingTranscriptHint = turnState.BufferedAudioBytes > 0 && string.IsNullOrWhiteSpace(turnState.AudioTranscriptHint),
|
||||||
|
finalizeAttempts = turnState.FinalizeAttemptCount
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
if (ShouldTreatEmptyHotphraseTurnAsGreeting(finalizedTurn))
|
if (ShouldTreatEmptyHotphraseTurnAsGreeting(finalizedTurn))
|
||||||
{
|
{
|
||||||
finalizedTurn = WithSyntheticTranscript(finalizedTurn, "hello");
|
finalizedTurn = WithSyntheticTranscript(finalizedTurn, "hello");
|
||||||
@@ -689,6 +717,33 @@ public sealed class WebSocketTurnFinalizationService(
|
|||||||
.Any(static rule => string.Equals(rule, "launch", StringComparison.OrdinalIgnoreCase));
|
.Any(static rule => string.Equals(rule, "launch", StringComparison.OrdinalIgnoreCase));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static bool ShouldIgnoreInitialEmptyHotphraseTurn(TurnContext turn, WebSocketTurnState turnState)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrWhiteSpace(turn.NormalizedTranscript) || !string.IsNullOrWhiteSpace(turn.RawTranscript))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var messageType = ReadMessageType(turn);
|
||||||
|
if (messageType is not ("CLIENT_ASR" or "CLIENT_NLU"))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ReadBoolAttribute(turn, "listenHotphrase"))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (turnState.HotphraseEmptyTurnCount > 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ReadRules(turn, "listenRules")
|
||||||
|
.Any(static rule => string.Equals(rule, "launch", StringComparison.OrdinalIgnoreCase));
|
||||||
|
}
|
||||||
|
|
||||||
private static TurnContext WithSyntheticTranscript(TurnContext turn, string transcript)
|
private static TurnContext WithSyntheticTranscript(TurnContext turn, string transcript)
|
||||||
{
|
{
|
||||||
var attributes = new Dictionary<string, object?>(turn.Attributes, StringComparer.OrdinalIgnoreCase)
|
var attributes = new Dictionary<string, object?>(turn.Attributes, StringComparer.OrdinalIgnoreCase)
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ public sealed class WebSocketTurnState
|
|||||||
public string? TransId { get; set; }
|
public string? TransId { get; set; }
|
||||||
public string? ContextPayload { get; set; }
|
public string? ContextPayload { get; set; }
|
||||||
public bool ListenHotphrase { get; set; }
|
public bool ListenHotphrase { get; set; }
|
||||||
|
public int HotphraseEmptyTurnCount { get; set; }
|
||||||
public string? AudioTranscriptHint { get; set; }
|
public string? AudioTranscriptHint { get; set; }
|
||||||
public string? LastSttError { get; set; }
|
public string? LastSttError { get; set; }
|
||||||
public DateTimeOffset? LastSttErrorUtc { get; set; }
|
public DateTimeOffset? LastSttErrorUtc { get; set; }
|
||||||
|
|||||||
@@ -573,7 +573,7 @@ public sealed class JiboWebSocketServiceTests
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task EmptyHotphraseTurn_BecomesGreetingAndKeepsFollowUpOpen()
|
public async Task SecondEmptyHotphraseTurn_BecomesGreetingAndKeepsFollowUpOpen()
|
||||||
{
|
{
|
||||||
await _service.HandleMessageAsync(new WebSocketMessageEnvelope
|
await _service.HandleMessageAsync(new WebSocketMessageEnvelope
|
||||||
{
|
{
|
||||||
@@ -584,6 +584,18 @@ public sealed class JiboWebSocketServiceTests
|
|||||||
Text = """{"type":"LISTEN","transID":"trans-empty-hotphrase","data":{"hotphrase":true,"rules":["launch","globals/global_commands_launch"]}}"""
|
Text = """{"type":"LISTEN","transID":"trans-empty-hotphrase","data":{"hotphrase":true,"rules":["launch","globals/global_commands_launch"]}}"""
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var firstReplies = await _service.HandleMessageAsync(new WebSocketMessageEnvelope
|
||||||
|
{
|
||||||
|
HostName = "neo-hub.jibo.com",
|
||||||
|
Path = "/listen",
|
||||||
|
Kind = "neo-hub-listen",
|
||||||
|
Token = "hub-empty-hotphrase-token",
|
||||||
|
Text = """{"type":"CLIENT_ASR","transID":"trans-empty-hotphrase","data":{}}"""
|
||||||
|
});
|
||||||
|
|
||||||
|
Assert.Single(firstReplies);
|
||||||
|
Assert.Equal("OPENJIBO_TURN_PENDING", ReadReplyType(firstReplies[0]));
|
||||||
|
|
||||||
var replies = await _service.HandleMessageAsync(new WebSocketMessageEnvelope
|
var replies = await _service.HandleMessageAsync(new WebSocketMessageEnvelope
|
||||||
{
|
{
|
||||||
HostName = "neo-hub.jibo.com",
|
HostName = "neo-hub.jibo.com",
|
||||||
|
|||||||
Reference in New Issue
Block a user