Files
Deal/src/core/Deal.Contracts/Integrations/IAiTools.cs
T
Rustam Khalimov 492950bdd0 Отформатировать списки параметров по код-стайлу
Больше двух параметров — каждый на отдельной строке (закрывающая
скобка в конце последнего); два и меньше — в одну строку. Правило
добавлено в docs/spec/Код-стайл-Дейл.md; применено к 628 сигнатурам
в 253 файлах.
2026-09-11 13:22:56 +03:00

51 lines
3.8 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 Deal.Contracts.Integrations.Models;
namespace Deal.Contracts.Integrations;
/// <summary>
/// Порт ИИ-инструментов Discovery и генерации ключевых слов (Ruling 9, план Task 15/18/19).
/// </summary>
/// <remarks>
/// Порт объявлен в Contracts, потому что контракт потребляет модуль Discovery (воркер/эндпоинты) на этапе 6;
/// реализация — gRPC-адаптер ai-service <c>GrpcAiTools</c>, регистрируемый при <c>Services:Ai:UseLocal=false</c>
/// (Ruling 6). Локальная реализация <c>LocalAiTools</c> (UseLocal=true) методы не поддерживает: Discovery-воркер
/// при aiEnabled=false/сбое сам выбирает эвристику (python discovery_eval L186194), generate-keywords-эндпоинт
/// (Task 19) отдаёт мягкую ошибку {keywords: [], error}. Методы повторяют прототип 1:1:
/// <c>backend/app/routers/discovery_routes.py</c> L189211 (generate-keywords) и
/// <c>backend/app/services/discovery_eval.py</c> L5054/L153194 (оценка fit). Выключатели aiEnabled/aiFilterEnabled
/// порт не читает — ветки выключателей отрабатывает вызывающий (воркер Discovery, Ruling 10).
/// </remarks>
public interface IAiTools
{
/// <summary>
/// Генерация поисковых ключевых слов discovery-задачи по описанию ниши (discovery_routes L3647).
/// </summary>
/// <remarks>
/// Очистку (<c>_clean_keywords</c>: ≤30, ≤60 символов, дедуп) и мягкую ошибку {keywords: [], error} для UI
/// делает вызывающий (эндпоинт Task 19, Ruling 11); адаптер возвращает сырые ключи модели и ok=false при
/// недоступности сервиса/провайдера (без исключений наружу — мягкая форма Ruling 11).
/// </remarks>
/// <param name="description">Описание ниши/задачи (вызывающий режет до 4000, как discovery_routes L29).</param>
/// <param name="ct">Токен отмены.</param>
/// <returns>Результат: ok + ключевые слова (пусто — модель не выделила ключей или сервис недоступен) + текст ошибки.</returns>
public Task<AiGenerateKeywordsResultDto> GenerateKeywordsAsync(string description, CancellationToken ct);
/// <summary>
/// Оценка соответствия сообщения задаче поиска (промпт discovery_eval L5054; Ruling 5/10).
/// </summary>
/// <remarks>
/// Вызывающий (воркер Discovery, Task 18) зовёт только при aiEnabled и при сбое/исключении сам падает в
/// эвристику по ключам (python evaluate_message L186194) — порт ошибки пробрасывает наружу.
/// </remarks>
/// <param name="text">Текст сообщения кандидата (вызывающий режет до 4000).</param>
/// <param name="description">Описание задачи поиска (discovery_eval L51).</param>
/// <param name="keywords">Ключи задачи (discovery_eval L52).</param>
/// <param name="ct">Токен отмены.</param>
/// <returns>Решение fit + краткая причина (потолок причины 200, как _AI_REASON_LIMIT L43).</returns>
public Task<AiEvaluateFitResultDto> EvaluateFitAsync(
string text,
string description,
IReadOnlyCollection<string> keywords,
CancellationToken ct);
}