Forge
csharp4405de34
1#nullable enable
2
3using CascadeIDE.Models.AgentChat;
4using CascadeIDE.Models.Intercom;
5
6namespace CascadeIDE.Services.Intercom;
7
8/// <summary>Contiguous и disjoint ordinal segments для <see cref="ChatHistoryEventKind.MessageRangeRelated"/>.</summary>
9public static class IntercomMessageRangeRelatedSupport
10{
11 public static IReadOnlyList<ChatHistoryMessageOrdinalSegment> ResolveSegments(
12 ChatHistoryMessageRangeRelatedPayload payload)
13 {
14 if (payload.OrdinalSegments is { Count: > 0 } segments)
15 return segments;
16
17 return
18 [
19 new ChatHistoryMessageOrdinalSegment(payload.StartOrdinal, payload.EndOrdinal),
20 ];
21 }
22
23 public static bool IsDisjoint(ChatHistoryMessageRangeRelatedPayload payload) =>
24 ResolveSegments(payload).Count > 1;
25
26 public static ChatHistoryMessageRangeRelatedPayload CreatePayload(
27 string threadId,
28 IReadOnlyList<ChatHistoryMessageOrdinalSegment> segments,
29 AttachmentAnchor codeRef,
30 string source)
31 {
32 if (segments.Count == 0)
33 throw new ArgumentException("At least one ordinal segment is required.", nameof(segments));
34
35 var min = segments.Min(s => s.StartOrdinal);
36 var max = segments.Max(s => s.EndOrdinal);
37
38 return new ChatHistoryMessageRangeRelatedPayload(
39 threadId,
40 min,
41 max,
42 codeRef,
43 source,
44 segments.Count > 1 ? segments : null);
45 }
46
47 public static string FormatOrdinalSummary(IReadOnlyList<ChatHistoryMessageOrdinalSegment> segments)
48 {
49 if (segments.Count == 0)
50 return "";
51
52 if (segments.Count == 1)
53 {
54 var s = segments[0];
55 return s.StartOrdinal == s.EndOrdinal
56 ? $"#{s.StartOrdinal}"
57 : $"#{s.StartOrdinal}–#{s.EndOrdinal}";
58 }
59
60 return string.Join(", ", segments.Select(s =>
61 s.StartOrdinal == s.EndOrdinal
62 ? $"#{s.StartOrdinal}"
63 : $"#{s.StartOrdinal}–#{s.EndOrdinal}"));
64 }
65
66 public static bool TryValidateSegmentsInLane(
67 IReadOnlyList<ChatHistoryMessageOrdinalSegment> segments,
68 int laneMessageCount,
69 out string error)
70 {
71 error = "";
72 foreach (var segment in segments)
73 {
74 if (segment.StartOrdinal < 1 || segment.EndOrdinal < 1)
75 {
76 error = "Номера сообщений должны быть ≥ 1.";
77 return false;
78 }
79
80 if (segment.EndOrdinal < segment.StartOrdinal)
81 {
82 error = "Конец диапазона не может быть меньше начала.";
83 return false;
84 }
85
86 if (segment.StartOrdinal > laneMessageCount)
87 {
88 error = $"Нет сообщения #{segment.StartOrdinal} (в ветке {laneMessageCount}).";
89 return false;
90 }
91
92 if (segment.EndOrdinal > laneMessageCount)
93 {
94 error = $"Нет сообщения #{segment.EndOrdinal} (в ветке {laneMessageCount}).";
95 return false;
96 }
97 }
98
99 return true;
100 }
101}
102
View only · write via MCP/CIDE