chore: remove legacy src/ directory
This commit is contained in:
parent
4f5c5679d5
commit
c87b37ad64
6 changed files with 0 additions and 283 deletions
|
|
@ -1,246 +0,0 @@
|
|||
"""
|
||||
MockPlatformClient — заглушка SDK платформы Lambda.
|
||||
|
||||
Единственный файл который нужно заменить при подключении реального SDK.
|
||||
Все обращения к платформе в коде ботов идут только через этот класс.
|
||||
|
||||
При подключении реального SDK:
|
||||
1. Скопируй интерфейс (методы и сигнатуры) из этого файла
|
||||
2. Замени тело методов на реальные API вызовы
|
||||
3. Обнови импорт в telegram_bot/main.py и matrix_bot/main.py
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import uuid
|
||||
from datetime import datetime, timedelta
|
||||
from typing import Any
|
||||
|
||||
import structlog
|
||||
|
||||
logger = structlog.get_logger(__name__)
|
||||
|
||||
|
||||
class PlatformError(Exception):
|
||||
"""Базовый класс ошибок платформы."""
|
||||
def __init__(self, message: str, code: str = "PLATFORM_ERROR"):
|
||||
super().__init__(message)
|
||||
self.code = code
|
||||
|
||||
|
||||
class SessionNotFoundError(PlatformError):
|
||||
def __init__(self, session_id: str):
|
||||
super().__init__(f"Session {session_id} not found", "SESSION_NOT_FOUND")
|
||||
|
||||
|
||||
class MockPlatformClient:
|
||||
"""
|
||||
Имитирует поведение SDK платформы Lambda.
|
||||
|
||||
Хранит состояние в памяти — при перезапуске сбрасывается.
|
||||
Для персистентности в моке используй MockPlatformClient(persistent=True)
|
||||
(тогда сохраняет в /tmp/mock_platform_state.json).
|
||||
"""
|
||||
|
||||
def __init__(self, base_url: str = "http://localhost:8000", timeout: float = 5.0):
|
||||
self._sessions: dict[str, dict] = {}
|
||||
self._messages: dict[str, list] = {} # session_id -> messages
|
||||
self._base_url = base_url
|
||||
self._timeout = timeout
|
||||
logger.info("MockPlatformClient initialized", base_url=base_url)
|
||||
|
||||
# ─── Sessions ────────────────────────────────────────────────────────────
|
||||
|
||||
async def create_session(
|
||||
self,
|
||||
user_id: str,
|
||||
platform: str, # "telegram" | "matrix"
|
||||
context: dict[str, Any] | None = None,
|
||||
) -> dict:
|
||||
"""
|
||||
Создаёт новую сессию пользователя с AI-агентом.
|
||||
|
||||
Returns:
|
||||
{
|
||||
"session_id": str,
|
||||
"agent_id": str,
|
||||
"created_at": ISO8601,
|
||||
"expires_at": ISO8601,
|
||||
}
|
||||
"""
|
||||
await self._simulate_latency()
|
||||
|
||||
session_id = str(uuid.uuid4())
|
||||
agent_id = f"agent-{uuid.uuid4().hex[:8]}"
|
||||
now = datetime.utcnow()
|
||||
|
||||
session = {
|
||||
"session_id": session_id,
|
||||
"agent_id": agent_id,
|
||||
"user_id": user_id,
|
||||
"platform": platform,
|
||||
"context": context or {},
|
||||
"created_at": now.isoformat() + "Z",
|
||||
"expires_at": (now + timedelta(hours=24)).isoformat() + "Z",
|
||||
"status": "active",
|
||||
}
|
||||
|
||||
self._sessions[session_id] = session
|
||||
self._messages[session_id] = []
|
||||
|
||||
logger.info("Session created", session_id=session_id, user_id=user_id, platform=platform)
|
||||
return {k: v for k, v in session.items() if k not in ("user_id", "platform", "context", "status")}
|
||||
|
||||
async def get_session(self, session_id: str) -> dict:
|
||||
"""
|
||||
Возвращает информацию о сессии.
|
||||
|
||||
Raises:
|
||||
SessionNotFoundError: если сессия не существует или истекла
|
||||
"""
|
||||
await self._simulate_latency()
|
||||
|
||||
session = self._sessions.get(session_id)
|
||||
if not session:
|
||||
raise SessionNotFoundError(session_id)
|
||||
|
||||
return session
|
||||
|
||||
async def close_session(self, session_id: str) -> bool:
|
||||
"""
|
||||
Завершает сессию.
|
||||
|
||||
Returns:
|
||||
True если сессия была закрыта, False если уже была закрыта
|
||||
"""
|
||||
await self._simulate_latency()
|
||||
|
||||
session = self._sessions.get(session_id)
|
||||
if not session:
|
||||
raise SessionNotFoundError(session_id)
|
||||
|
||||
was_active = session["status"] == "active"
|
||||
session["status"] = "closed"
|
||||
session["closed_at"] = datetime.utcnow().isoformat() + "Z"
|
||||
|
||||
logger.info("Session closed", session_id=session_id)
|
||||
return was_active
|
||||
|
||||
# ─── Messages ─────────────────────────────────────────────────────────────
|
||||
|
||||
async def send_message(
|
||||
self,
|
||||
session_id: str,
|
||||
text: str,
|
||||
attachments: list[dict] | None = None,
|
||||
) -> dict:
|
||||
"""
|
||||
Отправляет сообщение пользователя в сессию и получает ответ агента.
|
||||
|
||||
Returns:
|
||||
{
|
||||
"message_id": str,
|
||||
"response": str,
|
||||
"tokens_used": int,
|
||||
"finished": bool,
|
||||
}
|
||||
"""
|
||||
await self._simulate_latency(min_ms=200, max_ms=800)
|
||||
|
||||
if session_id not in self._sessions:
|
||||
raise SessionNotFoundError(session_id)
|
||||
|
||||
message_id = str(uuid.uuid4())
|
||||
|
||||
# Mock ответ агента
|
||||
response = f"[MOCK] Ответ на: «{text[:50]}{'...' if len(text) > 50 else ''}»"
|
||||
|
||||
message = {
|
||||
"message_id": message_id,
|
||||
"session_id": session_id,
|
||||
"user_text": text,
|
||||
"response": response,
|
||||
"tokens_used": len(text.split()) * 2, # грубая оценка
|
||||
"finished": True,
|
||||
"created_at": datetime.utcnow().isoformat() + "Z",
|
||||
}
|
||||
|
||||
self._messages[session_id].append(message)
|
||||
|
||||
logger.info("Message sent", session_id=session_id, message_id=message_id)
|
||||
return {
|
||||
"message_id": message["message_id"],
|
||||
"response": message["response"],
|
||||
"tokens_used": message["tokens_used"],
|
||||
"finished": message["finished"],
|
||||
}
|
||||
|
||||
async def get_message_history(
|
||||
self,
|
||||
session_id: str,
|
||||
limit: int = 20,
|
||||
offset: int = 0,
|
||||
) -> list[dict]:
|
||||
"""
|
||||
Возвращает историю сообщений сессии.
|
||||
"""
|
||||
await self._simulate_latency()
|
||||
|
||||
if session_id not in self._sessions:
|
||||
raise SessionNotFoundError(session_id)
|
||||
|
||||
messages = self._messages.get(session_id, [])
|
||||
return messages[offset : offset + limit]
|
||||
|
||||
# ─── User ─────────────────────────────────────────────────────────────────
|
||||
|
||||
async def get_or_create_user(
|
||||
self,
|
||||
external_id: str,
|
||||
platform: str,
|
||||
display_name: str | None = None,
|
||||
) -> dict:
|
||||
"""
|
||||
Возвращает или создаёт пользователя платформы.
|
||||
|
||||
Returns:
|
||||
{
|
||||
"user_id": str,
|
||||
"external_id": str,
|
||||
"platform": str,
|
||||
"display_name": str | None,
|
||||
"created_at": ISO8601,
|
||||
"is_new": bool,
|
||||
}
|
||||
"""
|
||||
await self._simulate_latency()
|
||||
|
||||
# В моке генерируем детерминированный user_id
|
||||
user_id = f"user-{platform}-{external_id}"
|
||||
|
||||
logger.info("User fetched", user_id=user_id, platform=platform)
|
||||
return {
|
||||
"user_id": user_id,
|
||||
"external_id": external_id,
|
||||
"platform": platform,
|
||||
"display_name": display_name,
|
||||
"created_at": "2025-01-01T00:00:00Z",
|
||||
"is_new": False,
|
||||
}
|
||||
|
||||
# ─── Internals ────────────────────────────────────────────────────────────
|
||||
|
||||
async def _simulate_latency(self, min_ms: int = 10, max_ms: int = 100) -> None:
|
||||
"""Имитирует сетевую задержку для реалистичного тестирования."""
|
||||
import random
|
||||
delay = random.randint(min_ms, max_ms) / 1000
|
||||
await asyncio.sleep(delay)
|
||||
|
||||
def get_stats(self) -> dict:
|
||||
"""Возвращает статистику мока (для отладки)."""
|
||||
return {
|
||||
"active_sessions": sum(1 for s in self._sessions.values() if s["status"] == "active"),
|
||||
"total_sessions": len(self._sessions),
|
||||
"total_messages": sum(len(msgs) for msgs in self._messages.values()),
|
||||
}
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
"""Общие Pydantic модели для Telegram и Matrix ботов."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import datetime
|
||||
from enum import Enum
|
||||
from typing import Any
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
|
||||
class Platform(str, Enum):
|
||||
TELEGRAM = "telegram"
|
||||
MATRIX = "matrix"
|
||||
|
||||
|
||||
class Session(BaseModel):
|
||||
session_id: str
|
||||
agent_id: str
|
||||
created_at: datetime
|
||||
expires_at: datetime
|
||||
|
||||
|
||||
class User(BaseModel):
|
||||
user_id: str
|
||||
external_id: str
|
||||
platform: Platform
|
||||
display_name: str | None = None
|
||||
created_at: datetime
|
||||
is_new: bool = False
|
||||
|
||||
|
||||
class MessageResponse(BaseModel):
|
||||
message_id: str
|
||||
response: str
|
||||
tokens_used: int
|
||||
finished: bool
|
||||
Loading…
Add table
Add a link
Reference in a new issue