# 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-файл `<session_id>.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-режим не сломан.
