Forge
csharpdeeb25a2
1#nullable enable
2using System.Text;
3using CascadeIDE.Models.AgentChat;
4
5namespace CascadeIDE.Features.Chat;
6
7/// <summary>Секция Decisions в chat_export_readable (ADR 0173).</summary>
8internal static class ChatSedmReadableExport
9{
10 public static string? BuildDecisionsSection(IReadOnlyList<ChatHistoryEvent> events)
11 {
12 var projection = SedmEventProjector.Project(events, Guid.Empty, openWorklineCount: 1);
13 if (projection.ByWorkline.Count == 0)
14 return null;
15
16 var sb = new StringBuilder();
17 sb.AppendLine("## Decisions (SEDM)");
18 var any = false;
19
20 foreach (var pair in projection.ByWorkline.OrderBy(static kv => kv.Key, StringComparer.Ordinal))
21 {
22 var wl = pair.Value;
23 if (wl.IntentCard is null && wl.DecisionHistory.Count == 0)
24 continue;
25
26 any = true;
27 sb.AppendLine();
28 sb.AppendLine($"### Workline {pair.Key}");
29
30 if (wl.IntentCard is not null)
31 {
32 sb.AppendLine("- **Intent (operator)**");
33 AppendCard(sb, wl.IntentCard.Card, wl.IntentCard.Considered);
34 }
35
36 foreach (var decision in wl.DecisionHistory)
37 {
38 sb.AppendLine($"- **Decision ({decision.Status})**");
39 AppendCard(sb, decision.Payload.Card, decision.Payload.Considered);
40 if (decision.Payload.Findings is { Count: > 0 })
41 {
42 sb.AppendLine(" - Findings:");
43 foreach (var finding in decision.Payload.Findings)
44 sb.AppendLine($" - [{finding.Kind}] {finding.Ref}: {finding.Summary}");
45 }
46 }
47 }
48
49 return any ? sb.ToString().TrimEnd() : null;
50 }
51
52 private static void AppendCard(
53 StringBuilder sb,
54 SedmIntentCardBodyPayload card,
55 IReadOnlyList<SedmIntentConsideredOptionPayload>? considered)
56 {
57 if (!string.IsNullOrWhiteSpace(card.Outcome))
58 sb.AppendLine($" - Outcome: {card.Outcome.Trim()}");
59 if (!string.IsNullOrWhiteSpace(card.ChosenApproach))
60 sb.AppendLine($" - Chosen: {card.ChosenApproach.Trim()}");
61 if (!string.IsNullOrWhiteSpace(card.SelectionRationale))
62 sb.AppendLine($" - Rationale: {card.SelectionRationale.Trim()}");
63 if (considered is { Count: > 0 })
64 {
65 sb.AppendLine(" - Rejected:");
66 foreach (var option in considered)
67 sb.AppendLine($" - {option.Approach}: {option.RejectedBecause}");
68 }
69 }
70}
71
View only · write via MCP/CIDE