108 lines
4.0 KiB
Python
108 lines
4.0 KiB
Python
import uuid
|
||
import json
|
||
from typing import Optional, List, Dict, Any
|
||
from sqlalchemy.ext.asyncio import AsyncSession
|
||
from app.services.gigachat_service import gigachat_service
|
||
from app.services.cache_service import cache_service
|
||
from app.models.ai_conversation import AIConversation
|
||
from app.schemas.ai import ChatRequest, ChatResponse
|
||
from app.core.config import settings
|
||
|
||
|
||
# Персона "Планета Земля"
|
||
EARTH_PERSONA = """Ты планета Земля - анимированный персонаж и друг детей с расстройством аутистического спектра (РАС).
|
||
|
||
Твоя личность:
|
||
- Добрая, терпеливая, понимающая
|
||
- Говоришь простым языком
|
||
- Используешь эмодзи 🌍✨
|
||
- Поощряешь любые достижения
|
||
- Даешь четкие инструкции
|
||
|
||
Особенности общения:
|
||
- Короткие предложения
|
||
- Избегай сложных метафор
|
||
- Подтверждай понимание
|
||
- Задавай уточняющие вопросы
|
||
- Будь позитивным и поддерживающим"""
|
||
|
||
|
||
class ChatService:
|
||
async def chat(
|
||
self,
|
||
db: AsyncSession,
|
||
user_id: str,
|
||
request: ChatRequest
|
||
) -> ChatResponse:
|
||
"""Обработка чата с ИИ-агентом"""
|
||
# Получить или создать conversation_id
|
||
conversation_id = request.conversation_id or str(uuid.uuid4())
|
||
|
||
# Загрузить контекст из кэша
|
||
context = await cache_service.get_conversation_context(conversation_id)
|
||
|
||
# Добавить персону в начало, если контекст пустой
|
||
if not context:
|
||
context.append({
|
||
"role": "system",
|
||
"content": EARTH_PERSONA
|
||
})
|
||
|
||
# Добавить сообщение пользователя
|
||
context.append({
|
||
"role": "user",
|
||
"content": request.message
|
||
})
|
||
|
||
# Отправить запрос в GigaChat
|
||
try:
|
||
result = await gigachat_service.chat(
|
||
message=request.message,
|
||
context=context[:-1], # Без последнего сообщения (оно добавится автоматически)
|
||
model=settings.GIGACHAT_MODEL_CHAT
|
||
)
|
||
|
||
# Извлечь ответ
|
||
choices = result.get("choices", [])
|
||
if not choices:
|
||
raise Exception("No response from GigaChat")
|
||
|
||
response_text = choices[0].get("message", {}).get("content", "")
|
||
tokens_used = result.get("usage", {}).get("total_tokens")
|
||
model_used = result.get("model")
|
||
|
||
# Добавить ответ в контекст
|
||
context.append({
|
||
"role": "assistant",
|
||
"content": response_text
|
||
})
|
||
|
||
# Сохранить контекст в кэш
|
||
await cache_service.save_conversation_context(conversation_id, context)
|
||
|
||
# Сохранить в БД
|
||
conversation = AIConversation(
|
||
user_id=user_id,
|
||
conversation_id=conversation_id,
|
||
message=request.message,
|
||
response=response_text,
|
||
tokens_used=tokens_used,
|
||
model=model_used,
|
||
context=context
|
||
)
|
||
db.add(conversation)
|
||
await db.commit()
|
||
|
||
return ChatResponse(
|
||
response=response_text,
|
||
conversation_id=conversation_id,
|
||
tokens_used=tokens_used,
|
||
model=model_used
|
||
)
|
||
except Exception as e:
|
||
raise Exception(f"Chat service error: {str(e)}")
|
||
|
||
|
||
chat_service = ChatService()
|
||
|