feat: add standards workbench and portable rules profiles

This commit is contained in:
codex
2026-07-30 13:18:59 +03:00
parent 958bad6823
commit 86fb8c89d2
5 changed files with 165 additions and 0 deletions
@@ -0,0 +1,17 @@
using System.Net.Http.Json;
using System.Text.Json;
using StandardsWorkbench.Core;
namespace StandardsWorkbench.Ollama;
public sealed class OllamaClient : IOllamaService
{
private readonly HttpClient _http;
public OllamaClient(HttpClient? httpClient = null) { _http = httpClient ?? new HttpClient(); _http.BaseAddress = new Uri("http://192.168.200.112:11434"); _http.Timeout = TimeSpan.FromSeconds(120); }
public async Task<IReadOnlyList<string>> GetModelsAsync(CancellationToken cancellationToken)
{ using var response = await _http.GetAsync("/api/tags", cancellationToken); response.EnsureSuccessStatusCode(); using var json = await response.Content.ReadFromJsonAsync<JsonDocument>(cancellationToken: cancellationToken); return json?.RootElement.GetProperty("models").EnumerateArray().Select(x => x.GetProperty("name").GetString() ?? "").Where(x => x.Length > 0).ToArray() ?? []; }
public async Task<CandidateRule?> SuggestCandidateAsync(StandardClause clause, string model, CancellationToken cancellationToken)
{
if (string.IsNullOrWhiteSpace(model)) throw new ArgumentException("Модель Ollama не выбрана.", nameof(model)); var prompt = $"Return JSON only. Extract one candidate DOCX rule from clause {clause.ClauseId}. Never invent source references. Text: {clause.Text}"; using var response = await _http.PostAsJsonAsync("/api/generate", new { model, prompt, stream = false, format = "json" }, cancellationToken); response.EnsureSuccessStatusCode(); using var json = await response.Content.ReadFromJsonAsync<JsonDocument>(cancellationToken: cancellationToken); var raw = json?.RootElement.GetProperty("response").GetString(); if (string.IsNullOrWhiteSpace(raw)) return null; try { return JsonSerializer.Deserialize<CandidateRule>(raw); } catch (JsonException) { return null; }
}
}