using backend.Data; using Microsoft.EntityFrameworkCore; namespace backend.Conversations; public class ConversationLog(AppDbContext db) { public async Task StartAsync(Guid deviceId, CancellationToken ct) { var c = new Conversation { DeviceId = deviceId, StartedAt = DateTimeOffset.UtcNow, }; db.Conversations.Add(c); await db.SaveChangesAsync(ct); return c; } public Task AppendUserAsync(Guid conversationId, string text, CancellationToken ct) => AppendAsync(conversationId, TurnRole.User, text: text, ct: ct); public Task AppendAssistantAsync(Guid conversationId, string text, CancellationToken ct) => AppendAsync(conversationId, TurnRole.Assistant, text: text, ct: ct); public Task AppendToolAsync( Guid conversationId, string toolName, string argsJson, string resultJson, CancellationToken ct) => AppendAsync(conversationId, TurnRole.Tool, toolName: toolName, argsJson: argsJson, resultJson: resultJson, ct: ct); public async Task EndAsync(Guid conversationId, EndReason reason, CancellationToken ct) { var row = await db.Conversations.FirstAsync(c => c.Id == conversationId, ct); row.EndedAt = DateTimeOffset.UtcNow; row.EndReason = reason; await db.SaveChangesAsync(ct); } private async Task AppendAsync( Guid conversationId, TurnRole role, string? text = null, string? toolName = null, string? argsJson = null, string? resultJson = null, CancellationToken ct = default) { var next = await db.Turns .Where(t => t.ConversationId == conversationId) .Select(t => (int?)t.Index) .MaxAsync(ct) ?? -1; db.Turns.Add(new Turn { ConversationId = conversationId, Index = next + 1, Role = role, Text = text, ToolName = toolName, ToolArgsJson = argsJson, ToolResultJson = resultJson, CreatedAt = DateTimeOffset.UtcNow, }); await db.SaveChangesAsync(ct); } }