Update implementation details

This commit is contained in:
Jacob Dubin
2026-05-06 20:10:31 -05:00
parent a5de0fdbdd
commit ec14e61a81
2 changed files with 73 additions and 4 deletions

View File

@@ -37,12 +37,24 @@ public sealed class JiboWebSocketService(
!containsInlineTurnPayload &&
WebSocketTurnFinalizationService.ShouldIgnoreLateListenSetup(session, envelope.Text))
{
var (lateTransId, lateRules) = ResolveLateListenNoInputPayload(session, envelope.Text);
var replies = ResponsePlanToSocketMessagesMapper
.MapNoInputAndRedirectToSkill(lateTransId, lateRules, "@be/idle")
.Select(map => new WebSocketReply
{
Text = map.Text,
DelayMs = map.DelayMs
})
.ToArray();
await telemetrySink.RecordTurnEventAsync(envelope, session, "late_listen_ignored", new Dictionary<string, object?>
{
["messageType"] = parsedType,
["activeTransID"] = session.TurnState.TransId
["activeTransID"] = session.TurnState.TransId,
["ignoredTransID"] = lateTransId,
["replyCount"] = replies.Length
}, cancellationToken);
return [];
return replies;
}
WebSocketTurnFinalizationService.ObserveIncomingMessage(session, envelope.Text);
@@ -145,4 +157,53 @@ public sealed class JiboWebSocketService(
return false;
}
}
private static (string TransId, IReadOnlyList<string> Rules) ResolveLateListenNoInputPayload(
CloudSession session,
string? text)
{
var transId = session.TurnState.TransId ?? session.LastTransId ?? string.Empty;
var rules = session.TurnState.ListenRules;
if (string.IsNullOrWhiteSpace(text))
{
return (transId, rules);
}
try
{
using var document = JsonDocument.Parse(text);
var root = document.RootElement;
if (root.TryGetProperty("transID", out var transIdValue) &&
transIdValue.ValueKind == JsonValueKind.String &&
!string.IsNullOrWhiteSpace(transIdValue.GetString()))
{
transId = transIdValue.GetString()!;
}
if (root.TryGetProperty("data", out var data) &&
data.ValueKind == JsonValueKind.Object &&
data.TryGetProperty("rules", out var ruleValues) &&
ruleValues.ValueKind == JsonValueKind.Array)
{
var parsedRules = ruleValues.EnumerateArray()
.Where(static item => item.ValueKind == JsonValueKind.String)
.Select(static item => item.GetString() ?? string.Empty)
.Where(static rule => !string.IsNullOrWhiteSpace(rule))
.ToArray();
if (parsedRules.Length > 0)
{
rules = parsedRules;
}
}
}
catch
{
// Best effort parsing for late-listen cleanup.
}
return (transId, rules);
}
}

View File

@@ -77,7 +77,7 @@ public sealed class JiboWebSocketServiceTests
}
[Fact]
public async Task Listen_CloudVersion_DoesNotOpenFollowUpAndIgnoresSpeechTailListen()
public async Task Listen_CloudVersion_DoesNotOpenFollowUpAndClosesLateTailListen()
{
var replies = await _service.HandleMessageAsync(new WebSocketMessageEnvelope
{
@@ -127,7 +127,15 @@ public sealed class JiboWebSocketServiceTests
Text = """{"type":"LISTEN","transID":"trans-cloud-version-tail","data":{"hotphrase":true,"rules":["launch","globals/global_commands_launch"]}}"""
});
Assert.Empty(tailListenReplies);
Assert.Equal(3, tailListenReplies.Count);
Assert.Equal("LISTEN", ReadReplyType(tailListenReplies[0]));
Assert.Equal("EOS", ReadReplyType(tailListenReplies[1]));
Assert.Equal("SKILL_REDIRECT", ReadReplyType(tailListenReplies[2]));
using (var lateListenPayload = JsonDocument.Parse(tailListenReplies[0].Text!))
{
Assert.Equal("trans-cloud-version-tail", lateListenPayload.RootElement.GetProperty("transID").GetString());
Assert.Equal("launch", lateListenPayload.RootElement.GetProperty("data").GetProperty("nlu").GetProperty("rules")[0].GetString());
}
Assert.Equal("trans-cloud-version", session.TurnState.TransId);
Assert.False(session.TurnState.AwaitingTurnCompletion);
Assert.False(session.TurnState.SawListen);