Forge
csharp4405de34
1using System.Text.Json;
2using Microsoft.CodeAnalysis;
3
4namespace CascadeIDE.Services;
5
6/// <summary>Минимизация контекста для чата: только диагностики и сигнатуры (встроенный Roslyn).</summary>
7public sealed class ContextMinimizer
8{
9 private readonly CSharpLanguageService _languageService;
10
11 public ContextMinimizer(CSharpLanguageService languageService)
12 {
13 _languageService = languageService;
14 }
15
16 /// <summary>Возвращает компактный текст: блок Diagnostics (file:line:severity: id: message) и блок Signatures.</summary>
17 /// <param name="filePath">Путь к файлу (для .cs используется анализ).</param>
18 /// <param name="sourceText">Исходный код файла.</param>
19 /// <param name="ct">Отмена.</param>
20 /// <returns>Строка для подмешивания в системное/первое сообщение; пустая, если не C# или при ошибке.</returns>
21 public string Minimize(string filePath, string sourceText, CancellationToken ct = default)
22 {
23 if (string.IsNullOrEmpty(filePath) || !filePath.EndsWith(".cs", StringComparison.OrdinalIgnoreCase))
24 return string.Empty;
25
26 var diagnostics = _languageService.GetDiagnosticsForFile(filePath, sourceText, ct);
27 var signatures = _languageService.GetSignatureStringsForFile(filePath, sourceText, ct);
28 if (diagnostics.Count == 0 && signatures.Count == 0)
29 return string.Empty;
30
31 var sb = new System.Text.StringBuilder();
32 if (diagnostics.Count > 0)
33 {
34 sb.Append("## Diagnostics\n");
35 var fileName = System.IO.Path.GetFileName(filePath);
36 foreach (var d in diagnostics)
37 {
38 var (line, col) = RoslynLinePositionMapper.ToEditorLineColumn(d.Location.GetLineSpan().StartLinePosition);
39 sb.Append(fileName).Append('(').Append(line.Value).Append(',').Append(col.Value).Append("): ")
40 .Append(d.Severity == DiagnosticSeverity.Error ? "error" : "warning")
41 .Append(' ').Append(d.Id).Append(": ").Append(d.GetMessage()).Append('\n');
42 }
43 }
44 if (signatures.Count > 0)
45 {
46 sb.Append("## Signatures\n");
47 foreach (var sig in signatures)
48 sb.Append(sig).Append('\n');
49 }
50 return sb.ToString();
51 }
52
53 /// <summary>Диагностики по файлу в виде JSON для MCP (ide_get_current_file_diagnostics): массив { id, message, severity, line, column } (line/column 1-based). Только .cs.</summary>
54 public string GetDiagnosticsJson(string filePath, string sourceText, CancellationToken ct = default)
55 {
56 if (string.IsNullOrEmpty(filePath) || !filePath.EndsWith(".cs", StringComparison.OrdinalIgnoreCase))
57 return "[]";
58 var diagnostics = _languageService.GetDiagnosticsForFile(filePath, sourceText, ct);
59 var list = diagnostics.Select(d =>
60 {
61 var (line, col) = RoslynLinePositionMapper.ToEditorLineColumn(d.Location.GetLineSpan().StartLinePosition);
62 return new { id = d.Id, message = d.GetMessage(), severity = d.Severity == DiagnosticSeverity.Error ? "error" : "warning", line = line.Value, column = col.Value };
63 }).ToList();
64 return JsonSerializer.Serialize(list);
65 }
66}
67
View only · write via MCP/CIDE