sequenceDiagram
autonumber
participant Orch as 🧠 Orchestrator
participant Stoch as 🎲 Stochastic Engine
participant Sim as 🚀 Action Simulator
participant API as ⚡ FastAPI Backend
Orch->>Stoch: Вычисление интента (Такт t)
alt Интент == INVENTORY
Stoch-->>Sim: Триггер: execute_get_fridge_stock()
Sim->>API: HTTP GET /api/v1/inventory/stock
API-->>Sim: JSON Response (Stock Data)
else Интент == SUPPLY / PREPARING
Stoch-->>Sim: Триггер: execute_add_product_via_text()
Sim->>API: HTTP POST /api/v1/inventory/add-by-text
API-->>Sim: JSON Response (Status OK)
end
Sim-->>Orch: Возврат DTO результата шага
User Action Simulator (Эмулятор действий пользователя)
Прикладной домен: Централизованная программная обёртка симулятора над API реальных приложений
1. Системное назначение сервиса
User Action Simulator является единым исполнительным интерфейсом симуляционного движка, изолирующим In-Memory ядро от сетевого взаимодействия. Этот сервис представляет собой высокоуровневую программную обёртку (HTTP-клиент), которая принимает абстрактные интенты от математического процессора и транслирует их в реальные вызовы эндпоинтов приложений.
2. Architecture и маппинг методов
Сервис содержит внутри себя пул асинхронных методов, каждый из которых жестко привязан к конкретному HTTP-контракту реального FastAPI бэкенда.
2.1. Метод-клиент execute_get_fridge_stock
- Интент-триггер ядра:
INVENTORY - Целевой эндпоинт приложения:
GET /api/v1/inventory/stock - Логика обёртки: Извлекает из RAM-реестра сохраненный для
user_idтокен авторизации, формирует заголовокAuthorization: Bearerи выполняет асинхронный вызов. При эскалации тревожности (\(H_{\text{anxiety}} > 4.0\)) переводит вызов в режим высокочастотного DoS-тестирования.
2.2. Метод-клиент execute_add_product_via_text
- Интент-триггер ядра:
SUPPLY/PREPARING - Целевой эндпоинт приложения:
POST /api/v1/inventory/add-by-text - Логика обёртки: На основе матрицы аффинити и параметров стресса генерирует стохастический текст (используя логнормальное масштабирование объемов закупки), упаковывает строку в JSON
{"raw_text_input": ...}и пушит в приложение.
3. Сквозной рантайм-контур взаимодействия
4. Программный каркас обёртки (Python + httpx)
import httpx
import numpy as np
from uuid import UUID
class UserActionSimulator:
def __init__(self, app_base_url: str):
self.app_url = app_base_url
self.client = httpx.AsyncClient()
async def execute_get_fridge_stock(self, token: str, twin_metrics: dict) -> dict:
"""Обёртка над GET /inventory/stock с симуляцией компульсивного DoS"""
headers = {"Authorization": f"Bearer {token}"}
if twin_metrics["h_anxiety"] > 4.0:
# Аномальный высокочастотный цикл вызовов
for _ in range(3):
await self.client.get(f"{self.app_url}/api/v1/inventory/stock", headers=headers)
response = await self.client.get(f"{self.app_url}/api/v1/inventory/stock", headers=headers)
return response.json()
async def execute_add_product_via_text(self, token: str, user_id: UUID, twin_metrics: dict, target_sku: str) -> dict:
"""Обёртка над POST /inventory/add-by-text со стохастическим расчетом объемов"""
headers = {"Authorization": f"Bearer {token}"}
# Расчет объема на основе логнормального распределения и уровня тревожности
base_qty = np.random.exponential(scale=1.0)
quantity = max(1.0, round(base_qty, 1))
if twin_metrics["h_anxiety"] > 3.5:
stress_scale = float(twin_metrics["h_anxiety"] * twin_metrics["p_impulse"])
quantity = round(np.random.lognormal(mean=1.5, sigma=0.5) * stress_scale, 1)
payload = {"raw_text_input": f"{target_sku} {quantity}"}
response = await self.client.post(f"{self.app_url}/api/v1/inventory/add-by-text", headers=headers, json=payload)
return response.json()