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. Сквозной рантайм-контур взаимодействия

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 результата шага

Диаграмма сквозного рантайм-контура трансляции интентов в сетевые HTTP-вызовы

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()