# 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`.