RealtimeSession: persist user/assistant transcripts; emit assistant_done
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
using System.Text.Json.Nodes;
|
||||
using backend.Conversations;
|
||||
using backend.Data;
|
||||
using backend.Realtime;
|
||||
using backend.Tools;
|
||||
using FluentAssertions;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Xunit;
|
||||
|
||||
namespace backend.tests;
|
||||
|
||||
public class RealtimeSessionTranscriptTests(ApiFactory factory) : IClassFixture<ApiFactory>
|
||||
{
|
||||
private readonly ApiFactory _factory = factory;
|
||||
|
||||
[Fact]
|
||||
public async Task User_and_assistant_transcripts_are_persisted_and_response_done_emits_assistant_done()
|
||||
{
|
||||
using var scope = _factory.Services.CreateScope();
|
||||
var db = scope.ServiceProvider.GetRequiredService<AppDbContext>();
|
||||
var log = scope.ServiceProvider.GetRequiredService<ConversationLog>();
|
||||
var reg = new ToolRegistry(Array.Empty<ITool>());
|
||||
var upstream = new ScriptedRealtimeUpstream();
|
||||
var sink = new RecordingSink();
|
||||
var cfg = new RealtimeSettings("m", "v", "p", 30, new HashSet<string>());
|
||||
var session = new RealtimeSession(Guid.NewGuid(), upstream, sink, log, reg, cfg,
|
||||
new FakeDeviceChannel(), NullLogger.Instance);
|
||||
|
||||
upstream.Push(new JsonObject { ["type"] = "session.updated" });
|
||||
var cts = new CancellationTokenSource();
|
||||
var run = session.RunAsync(cts.Token);
|
||||
await sink.WaitForAsync("session_started", TimeSpan.FromSeconds(2));
|
||||
|
||||
upstream.Push(new JsonObject
|
||||
{
|
||||
["type"] = "conversation.item.input_audio_transcription.completed",
|
||||
["transcript"] = "hello",
|
||||
});
|
||||
upstream.Push(new JsonObject
|
||||
{
|
||||
["type"] = "response.audio_transcript.done",
|
||||
["transcript"] = "hi there",
|
||||
});
|
||||
upstream.Push(new JsonObject { ["type"] = "response.done" });
|
||||
|
||||
await sink.WaitForAsync("assistant_done", TimeSpan.FromSeconds(2));
|
||||
|
||||
var convoId = session.ConversationId!.Value;
|
||||
var turns = await db.Turns
|
||||
.Where(t => t.ConversationId == convoId)
|
||||
.OrderBy(t => t.Index).ToListAsync();
|
||||
turns.Select(t => t.Role).Should().Equal(TurnRole.User, TurnRole.Assistant);
|
||||
turns[0].Text.Should().Be("hello");
|
||||
turns[1].Text.Should().Be("hi there");
|
||||
|
||||
cts.Cancel();
|
||||
await run;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user