# MVP: процесс v1

## 1. Общее описание

Запрос пользователя обрабатывается цепочкой API → рантайм агента → зарегистрированный процесс версии `v1` → один workflow из трёх последовательных шагов. Процесс **не** обращается к RAG и **не** маршрутизирует интенты: текст сообщения передаётся в LLM по фиксированному промпту. Ответ агента — результат генерации с лёгкой постобработкой (trim).

```mermaid
flowchart LR
  subgraph api [API]
    RS[RequestService]
  end
  subgraph runtime [Agent runtime]
    AR[AgentRuntime]
    PR[ProcessRunner]
  end
  subgraph v1 [Процесс v1]
    P1[V1Process]
    WG[V1FlowMainGraph]
  end
  subgraph wf [Workflow v1.flow_main]
    S1[PrepareUserMessageStep]
    S2[GenerateAnswerStep]
    S3[FinalizeAnswerStep]
  end
  LLM[AgentLlmService]
  RS --> AR
  AR --> PR
  PR --> P1
  P1 --> WG
  WG --> S1 --> S2 --> S3
  S2 --> LLM
```

Клиент создаёт запрос с `process_version: v1`. `AgentRuntime` поднимает `RuntimeExecutionContext` (запрос, сессия, publisher, trace), выбирает `V1Process` из реестра и вызывает `run`. `V1Process` собирает `V1FlowContext` и прогоняет линейный граф: подготовка текста, один вызов LLM, финализация строки ответа. Итог попадает в `ProcessResult.answer` и дальше в ответ пользователю.

---

## 2. Шаги и контракты

### 2.1. Вход в процесс: `V1Process.run`

| | |
|--|--|
| **Название** | Запуск процесса v1 |
| **Задача** | Собрать контекст workflow и выполнить граф до готового ответа. |
| **Вход** | `RuntimeExecutionContext`: `request` (в т.ч. `message`), `session`, `publisher`, `trace`. |
| **Выход** | `ProcessResult` с полем `answer: str`. |
| **Как работает** | Создаётся `V1FlowContext` с `prompt_name` по умолчанию `v1_flow_main.answer`. Вызывается `V1FlowMainGraph.run`. Возвращается ответ из контекста workflow. |

Код: `src/app/core/agent/processes/v1/process.py`.

---

### 2.2. Шаг workflow: `PrepareUserMessageStep`

| | |
|--|--|
| **Название** | Подготовка сообщения пользователя |
| **Задача** | Сформировать строку, которая уйдёт в LLM как пользовательский ввод. |
| **Вход** | `V1FlowContext` с заполненным `runtime` и `prompt_name`. |
| **Выход** | Тот же контекст с `prepared_message: str`. |
| **Как работает** | Берётся `context.runtime.request.message` и обрезаются пробелы по краям (`strip`). Результат пишется в `prepared_message`. Других преобразований нет. |

Код: `src/app/core/agent/processes/v1/workflow/flow_main/steps/prepare_user_message_step.py`.

---

### 2.3. Шаг workflow: `GenerateAnswerStep`

| | |
|--|--|
| **Название** | Вызов LLM |
| **Задача** | Сгенерировать ответ по выбранному промпту и подготовленному сообщению. |
| **Вход** | `V1FlowContext` с `prepared_message`, `prompt_name`, `runtime.trace` для модуля LLM. |
| **Выход** | Контекст с `answer: str` (сырой ответ модели). |
| **Как работает** | Асинхронно в пуле потоков вызывается `AgentLlmService.generate(prompt_name, prepared_message, ...)`. В trace подключается модуль `workflow.v1.llm`. Идентификатор запроса передаётся в `log_context` для логов. |

Код: `src/app/core/agent/processes/v1/workflow/flow_main/steps/generate_answer_step.py`.

---

### 2.4. Шаг workflow: `FinalizeAnswerStep`

| | |
|--|--|
| **Название** | Финализация ответа |
| **Задача** | Нормализовать строку ответа перед выдачей пользователю. |
| **Вход** | `V1FlowContext` с заполненным `answer` после LLM. |
| **Выход** | Контекст с обновлённым `answer`. |
| **Как работает** | К ответу применяется `strip()` по краям. Другой логики нет. |

Код: `src/app/core/agent/processes/v1/workflow/flow_main/steps/finalize_answer_step.py`.

---

### 2.5. Транспорт: `WorkflowGraph` (v1)

Граф для v1 использует стандартный `WorkflowGraph`: на каждом шаге пишутся события `workflow_started`, `step_started`, `step_completed`, `workflow_completed` в `runtime_traces` через `context.runtime.trace`.

Код: `src/app/core/agent/utils/workflow/graph.py`, обёртка `V1FlowMainGraph` в `src/app/core/agent/processes/v1/workflow/flow_main/graph.py`.
