144 lines
5.2 KiB
C#
144 lines
5.2 KiB
C#
using OpenAI.Chat;
|
|
using OpenAI.Models;
|
|
using PerfReviewSummarizer.Api.Models;
|
|
|
|
namespace PerfReviewSummarizer.Api.Services;
|
|
|
|
public class OpenAiService : IOpenAiService, IAiService
|
|
{
|
|
private readonly IConfiguration _configuration;
|
|
private readonly HttpClient _httpClient;
|
|
private bool _initialized = false;
|
|
|
|
public OpenAiService(IConfiguration configuration, HttpClient httpClient)
|
|
{
|
|
_configuration = configuration;
|
|
_httpClient = httpClient;
|
|
}
|
|
|
|
private void EnsureInitialized()
|
|
{
|
|
if (_initialized) return;
|
|
|
|
var apiKey = _configuration["OpenAI:ApiKey"];
|
|
|
|
if (string.IsNullOrEmpty(apiKey))
|
|
{
|
|
throw new InvalidOperationException("OpenAI API ключ не найден в конфигурации. Добавьте 'OpenAI:ApiKey' в appsettings.json");
|
|
}
|
|
|
|
_httpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", apiKey);
|
|
_initialized = true;
|
|
}
|
|
|
|
public async Task<string> GenerateSummaryFromCommitsAsync(List<CommitInfo> commits)
|
|
{
|
|
var commitMessages = commits.Select(c => c.Message).ToList();
|
|
return await GenerateSummaryFromCommitMessagesAsync(commitMessages);
|
|
}
|
|
|
|
public async Task<string> GenerateSummaryFromCommitMessagesAsync(List<string> commitMessages)
|
|
{
|
|
EnsureInitialized();
|
|
|
|
if (!commitMessages.Any())
|
|
{
|
|
return "Нет коммитов для анализа";
|
|
}
|
|
|
|
var commitListText = string.Join("\n", commitMessages.Select((msg, idx) => $"{idx + 1}. {msg}"));
|
|
|
|
var prompt = $@"Проанализируй следующие сообщения коммитов из Git репозитория и создай краткое, информативное резюме (summary).
|
|
|
|
Сообщения коммитов:
|
|
{commitListText}
|
|
|
|
Требования:
|
|
1. Резюме должно быть на русском языке
|
|
2. Будь лаконичен, но информативен (2-4 абзаца)
|
|
3. Выделите основные темы изменений (новые функции, исправления, рефакторинг и т.д.)
|
|
4. Укажите общую направленность разработки
|
|
5. Отметьте любые важные или критичные изменения
|
|
|
|
Формат ответа - просто текст резюме без дополнительных комментариев.";
|
|
|
|
try
|
|
{
|
|
var request = new ChatCompletionRequest
|
|
{
|
|
Model = "gpt-3.5-turbo",
|
|
Messages = new List<ChatMessage>
|
|
{
|
|
new ChatMessage
|
|
{
|
|
Role = ChatMessageRole.User,
|
|
Content = prompt
|
|
}
|
|
},
|
|
Temperature = 0.7,
|
|
MaxTokens = 1000
|
|
};
|
|
|
|
var json = System.Text.Json.JsonSerializer.Serialize(request);
|
|
var content = new StringContent(json, System.Text.Encoding.UTF8, "application/json");
|
|
|
|
var response = await _httpClient.PostAsync("https://api.openai.com/v1/chat/completions", content);
|
|
|
|
if (!response.IsSuccessStatusCode)
|
|
{
|
|
var errorContent = await response.Content.ReadAsStringAsync();
|
|
Console.WriteLine($"OpenAI Error ({response.StatusCode}): {errorContent}");
|
|
throw new InvalidOperationException($"Ошибка OpenAI API: {response.StatusCode} - {errorContent}");
|
|
}
|
|
|
|
var responseContent = await response.Content.ReadAsStringAsync();
|
|
var result = System.Text.Json.JsonDocument.Parse(responseContent);
|
|
|
|
var message = result.RootElement
|
|
.GetProperty("choices")[0]
|
|
.GetProperty("message")
|
|
.GetProperty("content")
|
|
.GetString();
|
|
|
|
return message ?? "Ошибка при генерировании резюме";
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
throw new InvalidOperationException($"Ошибка при обращении к OpenAI API: {ex.Message}", ex);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Вспомогательные классы для сериализации
|
|
public class ChatCompletionRequest
|
|
{
|
|
[System.Text.Json.Serialization.JsonPropertyName("model")]
|
|
public string Model { get; set; } = "gpt-3.5-turbo";
|
|
|
|
[System.Text.Json.Serialization.JsonPropertyName("messages")]
|
|
public List<ChatMessage> Messages { get; set; } = new();
|
|
|
|
[System.Text.Json.Serialization.JsonPropertyName("temperature")]
|
|
public double Temperature { get; set; } = 0.7;
|
|
|
|
[System.Text.Json.Serialization.JsonPropertyName("max_tokens")]
|
|
public int MaxTokens { get; set; } = 1000;
|
|
}
|
|
|
|
public class ChatMessage
|
|
{
|
|
[System.Text.Json.Serialization.JsonPropertyName("role")]
|
|
public string Role { get; set; } = "user";
|
|
|
|
[System.Text.Json.Serialization.JsonPropertyName("content")]
|
|
public string Content { get; set; } = string.Empty;
|
|
}
|
|
|
|
public static class ChatMessageRole
|
|
{
|
|
public const string User = "user";
|
|
public const string Assistant = "assistant";
|
|
public const string System = "system";
|
|
}
|
|
|