| | | 1 | | using System.Text; |
| | | 2 | | using OzonDomains.Models; |
| | | 3 | | using Services.ApiServices.OpenRouterApi.Models; |
| | | 4 | | |
| | | 5 | | namespace Services.AiAssistant; |
| | | 6 | | |
| | | 7 | | /// <summary>Структурированный контекст для LLM при write-транзакциях и редактировании.</summary> |
| | | 8 | | public static class AiWriteContextFormatter |
| | | 9 | | { |
| | | 10 | | public static string FormatTransactionProposal(AiActionProposalDto proposal, OrderSummaryDto? order) |
| | | 11 | | { |
| | 10 | 12 | | var sb = new StringBuilder(); |
| | 10 | 13 | | sb.AppendLine("=== Проверка транзакции (факты из БД, не выдумывать) ==="); |
| | 10 | 14 | | sb.AppendLine($"Отправление: {proposal.ShipmentNumber}"); |
| | 10 | 15 | | sb.AppendLine($"ID заказа: {proposal.OrderId}"); |
| | 10 | 16 | | sb.AppendLine($"Текущий AppStatus: «{proposal.CurrentStatus ?? "Не указан"}»"); |
| | | 17 | | |
| | 10 | 18 | | if (order != null) |
| | | 19 | | { |
| | 2 | 20 | | sb.AppendLine($"ClientStatus Ozon: «{order.ClientStatus ?? "Не указан"}»"); |
| | 2 | 21 | | sb.AppendLine($"Товар: {order.ProductName}"); |
| | 2 | 22 | | sb.AppendLine($"Поставщик в заказе: «{order.Supplier ?? "Не указан"}»"); |
| | 2 | 23 | | sb.AppendLine($"Склад отгрузки: «{order.ShipmentWarehouseName ?? "Не указан"}»"); |
| | | 24 | | } |
| | | 25 | | |
| | 10 | 26 | | var txLabel = proposal.TransactionDto?.TransactionLabel ?? "—"; |
| | 10 | 27 | | sb.AppendLine($"Запрошенная транзакция: «{txLabel}»"); |
| | | 28 | | |
| | 10 | 29 | | if (proposal.MissingFields is { Count: > 0 }) |
| | | 30 | | { |
| | 2 | 31 | | sb.AppendLine("Нужно уточнить (missingFields):"); |
| | 12 | 32 | | foreach (var field in proposal.MissingFields) |
| | 4 | 33 | | sb.AppendLine($" • {field}"); |
| | 2 | 34 | | sb.AppendLine( |
| | 2 | 35 | | "ВАЖНО: не называй другой AppStatus и не пиши «Отменен»/«Новый», если выше указан иной статус. " + |
| | 2 | 36 | | "Не перечисляй альтернативные транзакции — только missingFields."); |
| | | 37 | | } |
| | | 38 | | else |
| | 8 | 39 | | sb.AppendLine("Проверки пройдены. Карточка подтверждения показана пользователю."); |
| | | 40 | | |
| | 10 | 41 | | return sb.ToString().TrimEnd(); |
| | | 42 | | } |
| | | 43 | | |
| | | 44 | | public static string FormatOrderFactsHeader(Order order) |
| | | 45 | | { |
| | 10 | 46 | | var sb = new StringBuilder(); |
| | 10 | 47 | | sb.AppendLine("=== ФАКТЫ ЗАКАЗА (только эти данные; игнорируй историю чата) ==="); |
| | 10 | 48 | | sb.AppendLine($"Отправление: {order.ShipmentNumber}"); |
| | 10 | 49 | | sb.AppendLine($"ID: {order.Id}"); |
| | 10 | 50 | | sb.AppendLine($"Товар: {order.ProductName}"); |
| | 10 | 51 | | sb.AppendLine($"Артикул: {order.Article ?? "—"}"); |
| | 10 | 52 | | sb.AppendLine($"Количество: {order.TrueQuantity} шт."); |
| | 10 | 53 | | sb.AppendLine($"AppStatus: «{order.AppStatus?.Name ?? "Не указан"}»" + |
| | 10 | 54 | | (order.AppStatus?.IsFinal == true ? " (финальный)" : "")); |
| | 10 | 55 | | sb.AppendLine($"ClientStatus Ozon: «{order.ClientStatus?.Name ?? "Не указан"}»"); |
| | 10 | 56 | | sb.AppendLine($"Поставщик: «{order.Supplier?.Name ?? "Не указан"}»"); |
| | 10 | 57 | | sb.AppendLine($"Склад отгрузки: «{order.ShipmentWarehouse?.Name ?? "Не указан"}»"); |
| | 10 | 58 | | sb.AppendLine($"Ozon-клиент: «{order.OzonClient?.Name ?? "Не указан"}»"); |
| | 10 | 59 | | return sb.ToString().TrimEnd(); |
| | | 60 | | } |
| | | 61 | | } |