Files
LazyBearWorks/LazyBear.MCP/Services/GitLab/GitLabToolsBase.cs

169 lines
5.5 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System.Collections.Generic;
using System.Text.Json;
using LazyBear.MCP.Services.ToolRegistry;
using RestSharp;
namespace LazyBear.MCP.Services.GitLab;
/// <summary>
/// Базовый класс для всех инструментов GitLab
/// </summary>
public sealed class GitLabToolsBase
{
protected readonly GitLabApiClient _client;
protected readonly string _baseUrl;
protected readonly int _perPageDefault;
private readonly string _token;
private readonly string _baseUrlConfig;
private readonly ToolRegistryService _registry;
/// <summary>
/// Ошибка инициализации клиента (если возникла)
/// </summary>
protected string? ClientInitializationError { get; }
/// <summary>
/// Конструктор
/// </summary>
/// <param name="baseUrlConfig">Конфигурация URL</param>
/// <param name="token">API токен</param>
/// <param name="registry">Регистратор инструментов</param>
public GitLabToolsBase(
string baseUrlConfig,
string token,
ToolRegistryService registry)
{
_token = token;
_baseUrlConfig = baseUrlConfig;
_registry = registry;
// Инициализация клиента
_baseUrl = baseUrlConfig;
_client = new GitLabApiClient(baseUrlConfig);
}
/// <summary>
/// Проверка, активирован ли инструмент в TUI
/// </summary>
protected bool TryCheckEnabled(string toolName, out string error)
{
if (!_registry.IsToolEnabled("GitLab", toolName))
{
error = $"Инструмент '{toolName}' модуля GitLab отключён в TUI.";
return false;
}
error = string.Empty;
return true;
}
/// <summary>
/// Получение клиента RestSharp
/// </summary>
protected bool TryGetClient(out GitLabApiClient client, out string error)
{
client = _client;
error = ClientInitializationError is null
? string.Empty
: $"GitLab клиент не инициализирован. Проверьте GitLab:Url. Детали: {ClientInitializationError}";
return ClientInitializationError is null;
}
/// <summary>
/// Создание запроса к GitLab API
/// </summary>
protected RestRequest CreateRequest(string resource, RestSharp.Method method = RestSharp.Method.Get)
{
var request = _client.GetRequest(resource);
return request;
}
/// <summary>
/// Форматирование ошибки ответа от GitLab API
/// </summary>
protected string FormatResponseError(string toolName, RestResponse response, string? resource = null)
{
var resourcePart = string.IsNullOrWhiteSpace(resource)
? string.Empty
: $", resource='{resource}'";
var body = string.IsNullOrWhiteSpace(response.Content)
? "-"
: response.Content;
return $"Ошибка GitLab в tool '{toolName}'{resourcePart}: status={(int)response.StatusCode}, details={body}";
}
/// <summary>
/// Форматирование исключения
/// </summary>
protected string FormatException(string toolName, Exception exception, string? resource = null)
{
var resourcePart = string.IsNullOrWhiteSpace(resource)
? string.Empty
: $", resource='{resource}'";
return $"Ошибка GitLab в tool '{toolName}'{resourcePart}: {exception.GetType().Name}: {exception.Message}";
}
/// <summary>
/// Получение вложенного строки из Json
/// </summary>
protected static string? GetNestedString(JsonElement element, params string[] path)
{
var current = element;
foreach (var segment in path)
{
if (!current.TryGetProperty(segment, out current))
{
return null;
}
}
return current.ValueKind == JsonValueKind.String
? current.GetString()
: current.ToString();
}
/// <summary>
/// Экстракция текста из комментариев GitLab
/// </summary>
protected static string ExtractCommentText(JsonElement body)
{
var chunks = new List<string>();
CollectText(body, chunks);
return chunks.Count == 0 ? "-" : string.Join(" ", chunks);
}
/// <summary>
/// Рекурсивный сбор текста из JSON
/// </summary>
protected static void CollectText(JsonElement element, List<string> chunks)
{
if (element.ValueKind == JsonValueKind.Object)
{
// Ищем текстовый узел в структуре комментария GitLab
if (element.TryGetProperty("body", out var bodyElement) &&
bodyElement.TryGetProperty("text", out var textElement))
{
if (textElement.ValueKind == JsonValueKind.String)
{
chunks.Add(textElement.GetString() ?? string.Empty);
}
}
foreach (var property in element.EnumerateObject())
{
CollectText(property.Value, chunks);
}
return;
}
if (element.ValueKind == JsonValueKind.Array)
{
foreach (var item in element.EnumerateArray())
{
CollectText(item, chunks);
}
}
}
}