# Assistant Mode vNext Spec ## 1. Цель Перевести Assistant Mode из planner/debug shell в рабочий factual-режим: - принять вопрос пользователя; - нормализовать и декомпозировать; - выбрать маршрут выполнения; - выполнить route-specific retrieval; - нормализовать retrieval results в единый контракт; - собрать один человекочитаемый ответ на русском; - отдать debug отдельно, через раскрываемый слой. ## 2. Реализованный контур Текущий контур в backend: `User message -> NormalizerService -> Route plan -> AssistantDataLayer (route executor) -> normalizeRetrievalResult -> composeAssistantAnswer -> Assistant API response` Ключевые файлы: - `backend/src/services/assistantService.ts` - `backend/src/services/assistantDataLayer.ts` - `backend/src/services/retrievalResultNormalizer.ts` - `backend/src/services/answerComposer.ts` - `backend/src/routes/assistant.ts` ## 3. API контракты Endpoint: `POST /api/assistant/message` Request (поддерживаются оба поля `user_message` и `message`): ```json { "session_id": "asst-...", "mode": "assistant", "message": "Покажи риски по НДС за июнь 2020", "user_message": "Покажи риски по НДС за июнь 2020", "promptVersion": "normalizer_v2_0_2", "context": { "period_hint": "2020-06", "business_context": "buh_test" }, "useMock": true } ``` Response: ```json { "ok": true, "session_id": "asst-...", "assistant_reply": "Проверка выполнена...", "reply_type": "factual", "conversation_item": {}, "debug": { "trace_id": "...", "fragments": [], "routes": [], "retrieval_status": [], "retrieval_results": [] }, "conversation": [] } ``` ## 4. Reply policy Реализованы user-facing типы: - `factual` - `empty` - `partial` - `clarification` - `out_of_scope` - `error` Технические маркеры (`fallback_type`, route names, trace details) остаются в debug payload и не выводятся как основной ответ. ## 5. Debug payload Debug отделён от user reply и содержит: - `trace_id` - `route_summary` - `fragments` - `routes` - `retrieval_status` - `retrieval_results` - `normalized` ## 6. UI поведение Frontend Assistant panel: - показывает нормальный текст ответа; - показывает техразбор только внутри `details`-блока `Показать технический разбор`; - использует русские loading-состояния: - `Разбираю запрос` - `Ищу данные` - `Собираю ответ` Ключевые файлы: - `frontend/src/components/AssistantPanel.tsx` - `frontend/src/App.tsx` - `frontend/src/state/types.ts` ## 7. Логирование В `assistant_loop` логируются: - `session_id`, `message_id`, `user_message` - `normalizer_output` - `execution_plan` - `retrieval_calls` - `retrieval_results_raw` - `retrieval_results_normalized` - `assistant_reply` - `reply_type` - `trace_id` Дополнительно введён session-level лог (один файл на `session_id`): - каталог: `data/assistant_sessions` - формат: `assistant_session_log_v1` - модель записи: один JSON-файл `.json`, который обновляется при каждом сообщении в рамках этой сессии. - внутри `turns[]` каждый закрытый контур хранит человекочитаемый блок: - `Вопрос` - `Понято как` - `Декомпозиция` - `Ответ` - ниже в `technical_json` остаётся полный технический JSON по этому же контуру. ## 8. Минимальная приёмка этапа Этап считается выполненным: 1. Assistant возвращает русскоязычный пользовательский ответ, не route plan. 2. Debug остаётся доступным отдельно. 3. Работает factual retrieval loop через route executors. 4. Отображаются `out_of_scope / clarification / partial / empty / error`. 5. Decomposition-режим не сломан.