diff --git a/logs/app.log b/logs/app.log new file mode 100644 index 0000000..8ddd577 --- /dev/null +++ b/logs/app.log @@ -0,0 +1,36 @@ +2025-12-23 21:37:30 - root - INFO - Starting up... +2025-12-23 21:37:30 - root - INFO - Starting up... +2025-12-23 21:39:37 - root - INFO - Shutting down... +2025-12-23 21:39:37 - root - INFO - Shutting down... +2025-12-23 21:39:42 - root - INFO - Starting up... +2025-12-23 21:39:42 - root - INFO - Starting up... +2025-12-23 22:07:40 - root - INFO - Shutting down... +2025-12-23 22:07:40 - root - INFO - Shutting down... +2025-12-23 22:07:45 - root - INFO - Starting up... +2025-12-23 22:07:45 - root - INFO - Starting up... +2025-12-23 22:12:42 - root - INFO - Shutting down... +2025-12-23 22:12:42 - root - INFO - Shutting down... +2025-12-23 22:12:47 - root - INFO - Starting up... +2025-12-23 22:12:47 - root - INFO - Starting up... +2025-12-23 22:23:22 - root - INFO - Shutting down... +2025-12-23 22:23:22 - root - INFO - Shutting down... +2025-12-23 22:23:27 - root - INFO - Starting up... +2025-12-23 22:23:27 - root - INFO - Starting up... +2025-12-23 22:52:47 - root - INFO - Shutting down... +2025-12-23 22:52:47 - root - INFO - Shutting down... +2025-12-23 22:52:54 - root - INFO - Starting up... +2025-12-23 22:52:54 - root - INFO - Starting up... +2025-12-23 23:12:01 - root - INFO - Shutting down... +2025-12-23 23:12:01 - root - INFO - Shutting down... +2025-12-23 23:12:07 - root - INFO - Starting up... +2025-12-23 23:12:07 - root - INFO - Starting up... +2025-12-23 23:15:05 - root - INFO - Shutting down... +2025-12-23 23:15:05 - root - INFO - Shutting down... +2025-12-23 23:15:10 - root - INFO - Starting up... +2025-12-23 23:15:10 - root - INFO - Starting up... +2025-12-24 00:01:39 - root - INFO - Shutting down... +2025-12-24 00:01:39 - root - INFO - Shutting down... +2025-12-24 00:01:45 - root - INFO - Starting up... +2025-12-24 00:01:45 - root - INFO - Starting up... +2025-12-24 01:38:58 - root - INFO - Shutting down... +2025-12-24 01:38:58 - root - INFO - Shutting down... diff --git a/new-planet-backend/.env b/new-planet-backend/.env index 1ed5ccf..17b240e 100644 --- a/new-planet-backend/.env +++ b/new-planet-backend/.env @@ -1,6 +1,6 @@  -GIGACHAT_CLIENT_ID=019966f4-1c5c-7382-9006-b84419fbe5d1 -GIGACHAT_CLIENT_SECRET=MDE5OTY2ZjQtMWM1Yy03MzgyLTkwMDYtYjg0NDE5ZmJlNWQxOjJjODBmOWE2LWU4YWMtNDE4YS1iOGVkLWE4NTE0YzVkNDAwNw== +GIGACHAT_CLIENT_ID=019966f0-5781-76e6-a84f-ec7de158188a +GIGACHAT_CLIENT_SECRET=MDE5OTY2ZjAtNTc4MS03NmU2LWE4NGYtZWM3ZGUxNTgxODhhOjI3MDMxZjIxLWY3NWYtNGI4NS05MzM1LTI4ZDYyOWM3MmM0MA== GIGACHAT_AUTH_URL=https://ngw.devices.sberbank.ru:9443/api/v2/oauth GIGACHAT_BASE_URL=https://gigachat.devices.sberbank.ru/api/v1 GIGACHAT_MODEL_CHAT=GigaChat-2-Lite @@ -29,3 +29,5 @@ STORAGE_BUCKET=new-planet-images STORAGE_USE_SSL=false STORAGE_REGION=us-east-1 +# Agents +AI_AGENT_BASE_URL=http://localhost:8001 \ No newline at end of file diff --git a/new-planet-backend/app/__pycache__/__init__.cpython-313.pyc b/new-planet-backend/app/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000..76e43ce Binary files /dev/null and b/new-planet-backend/app/__pycache__/__init__.cpython-313.pyc differ diff --git a/new-planet-backend/app/__pycache__/config.cpython-313.pyc b/new-planet-backend/app/__pycache__/config.cpython-313.pyc new file mode 100644 index 0000000..655861b Binary files /dev/null and b/new-planet-backend/app/__pycache__/config.cpython-313.pyc differ diff --git a/new-planet-backend/app/__pycache__/main.cpython-313.pyc b/new-planet-backend/app/__pycache__/main.cpython-313.pyc new file mode 100644 index 0000000..adcc338 Binary files /dev/null and b/new-planet-backend/app/__pycache__/main.cpython-313.pyc differ diff --git a/new-planet-backend/app/api/__pycache__/__init__.cpython-313.pyc b/new-planet-backend/app/api/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000..24c60ba Binary files /dev/null and b/new-planet-backend/app/api/__pycache__/__init__.cpython-313.pyc differ diff --git a/new-planet-backend/app/api/__pycache__/deps.cpython-313.pyc b/new-planet-backend/app/api/__pycache__/deps.cpython-313.pyc new file mode 100644 index 0000000..0be6cd7 Binary files /dev/null and b/new-planet-backend/app/api/__pycache__/deps.cpython-313.pyc differ diff --git a/new-planet-backend/app/api/v1/__pycache__/__init__.cpython-313.pyc b/new-planet-backend/app/api/v1/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000..6014f92 Binary files /dev/null and b/new-planet-backend/app/api/v1/__pycache__/__init__.cpython-313.pyc differ diff --git a/new-planet-backend/app/api/v1/__pycache__/ai.cpython-313.pyc b/new-planet-backend/app/api/v1/__pycache__/ai.cpython-313.pyc new file mode 100644 index 0000000..da73169 Binary files /dev/null and b/new-planet-backend/app/api/v1/__pycache__/ai.cpython-313.pyc differ diff --git a/new-planet-backend/app/api/v1/__pycache__/auth.cpython-313.pyc b/new-planet-backend/app/api/v1/__pycache__/auth.cpython-313.pyc new file mode 100644 index 0000000..1928dce Binary files /dev/null and b/new-planet-backend/app/api/v1/__pycache__/auth.cpython-313.pyc differ diff --git a/new-planet-backend/app/api/v1/__pycache__/images.cpython-313.pyc b/new-planet-backend/app/api/v1/__pycache__/images.cpython-313.pyc new file mode 100644 index 0000000..b0e2804 Binary files /dev/null and b/new-planet-backend/app/api/v1/__pycache__/images.cpython-313.pyc differ diff --git a/new-planet-backend/app/api/v1/__pycache__/rewards.cpython-313.pyc b/new-planet-backend/app/api/v1/__pycache__/rewards.cpython-313.pyc new file mode 100644 index 0000000..087fd5b Binary files /dev/null and b/new-planet-backend/app/api/v1/__pycache__/rewards.cpython-313.pyc differ diff --git a/new-planet-backend/app/api/v1/__pycache__/router.cpython-313.pyc b/new-planet-backend/app/api/v1/__pycache__/router.cpython-313.pyc new file mode 100644 index 0000000..90e07d3 Binary files /dev/null and b/new-planet-backend/app/api/v1/__pycache__/router.cpython-313.pyc differ diff --git a/new-planet-backend/app/api/v1/__pycache__/schedules.cpython-313.pyc b/new-planet-backend/app/api/v1/__pycache__/schedules.cpython-313.pyc new file mode 100644 index 0000000..21d8e14 Binary files /dev/null and b/new-planet-backend/app/api/v1/__pycache__/schedules.cpython-313.pyc differ diff --git a/new-planet-backend/app/api/v1/__pycache__/tasks.cpython-313.pyc b/new-planet-backend/app/api/v1/__pycache__/tasks.cpython-313.pyc new file mode 100644 index 0000000..3435eff Binary files /dev/null and b/new-planet-backend/app/api/v1/__pycache__/tasks.cpython-313.pyc differ diff --git a/new-planet-backend/app/api/v1/__pycache__/websocket.cpython-313.pyc b/new-planet-backend/app/api/v1/__pycache__/websocket.cpython-313.pyc new file mode 100644 index 0000000..4dd4086 Binary files /dev/null and b/new-planet-backend/app/api/v1/__pycache__/websocket.cpython-313.pyc differ diff --git a/new-planet-backend/app/core/__pycache__/__init__.cpython-313.pyc b/new-planet-backend/app/core/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000..7c3e546 Binary files /dev/null and b/new-planet-backend/app/core/__pycache__/__init__.cpython-313.pyc differ diff --git a/new-planet-backend/app/core/__pycache__/config.cpython-313.pyc b/new-planet-backend/app/core/__pycache__/config.cpython-313.pyc new file mode 100644 index 0000000..b4e0c7e Binary files /dev/null and b/new-planet-backend/app/core/__pycache__/config.cpython-313.pyc differ diff --git a/new-planet-backend/app/core/__pycache__/logging.cpython-313.pyc b/new-planet-backend/app/core/__pycache__/logging.cpython-313.pyc new file mode 100644 index 0000000..088f40e Binary files /dev/null and b/new-planet-backend/app/core/__pycache__/logging.cpython-313.pyc differ diff --git a/new-planet-backend/app/core/__pycache__/security.cpython-313.pyc b/new-planet-backend/app/core/__pycache__/security.cpython-313.pyc new file mode 100644 index 0000000..e6464d3 Binary files /dev/null and b/new-planet-backend/app/core/__pycache__/security.cpython-313.pyc differ diff --git a/new-planet-backend/app/core/config.py b/new-planet-backend/app/core/config.py index 7bf8087..635d75e 100644 --- a/new-planet-backend/app/core/config.py +++ b/new-planet-backend/app/core/config.py @@ -1,5 +1,13 @@ from pydantic_settings import BaseSettings from typing import Optional +from dotenv import load_dotenv +from pathlib import Path + +# Загружаем .env файл перед созданием Settings +# Ищем .env в корне проекта (на уровень выше от app/) +env_path = Path(__file__).parent.parent.parent / ".env" +# override=True гарантирует, что переменные из .env перезапишут существующие +load_dotenv(dotenv_path=env_path, override=True) class Settings(BaseSettings): @@ -49,7 +57,14 @@ class Settings(BaseSettings): STORAGE_USE_SSL: bool = False STORAGE_REGION: str = "us-east-1" - # GigaChat + # AI Agent Service (внешний сервис для работы с GigaChat) + # URL можно переопределить через переменную окружения AI_AGENT_BASE_URL + # Для Docker сети используйте: http://ai-agent:8000 (или имя сервиса из docker-compose) + # Для локальной разработки используйте: http://localhost:8000 + AI_AGENT_BASE_URL: str = "http://ai-agent:8000" + AI_AGENT_TIMEOUT: int = 120 # Таймаут в секундах + + # GigaChat (оставлено для обратной совместимости, но используется через AI-agent сервис) GIGACHAT_CLIENT_ID: str = "019966f4-1c5c-7382-9006-b84419fbe5d1" GIGACHAT_CLIENT_SECRET: str = "MDE5OTY2ZjQtMWM1Yy03MzgyLTkwMDYtYjg0NDE5ZmJlNWQxOjJjODBmOWE2LWU4YWMtNDE4YS1iOGVkLWE4NTE0YzVkNDAwNw==" GIGACHAT_AUTH_URL: str = "https://ngw.devices.sberbank.ru:9443/api/v2/oauth" @@ -65,7 +80,9 @@ class Settings(BaseSettings): RATE_LIMIT_PER_MINUTE: int = 60 class Config: - env_file = ".env" + # Путь к .env файлу относительно корня проекта + env_file = str(env_path) if env_path.exists() else ".env" + env_file_encoding = "utf-8" case_sensitive = True diff --git a/new-planet-backend/app/crud/__pycache__/__init__.cpython-313.pyc b/new-planet-backend/app/crud/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000..7226b02 Binary files /dev/null and b/new-planet-backend/app/crud/__pycache__/__init__.cpython-313.pyc differ diff --git a/new-planet-backend/app/crud/__pycache__/base.cpython-313.pyc b/new-planet-backend/app/crud/__pycache__/base.cpython-313.pyc new file mode 100644 index 0000000..67745fa Binary files /dev/null and b/new-planet-backend/app/crud/__pycache__/base.cpython-313.pyc differ diff --git a/new-planet-backend/app/crud/__pycache__/schedule.cpython-313.pyc b/new-planet-backend/app/crud/__pycache__/schedule.cpython-313.pyc new file mode 100644 index 0000000..d5b2f8c Binary files /dev/null and b/new-planet-backend/app/crud/__pycache__/schedule.cpython-313.pyc differ diff --git a/new-planet-backend/app/crud/__pycache__/task.cpython-313.pyc b/new-planet-backend/app/crud/__pycache__/task.cpython-313.pyc new file mode 100644 index 0000000..815cd0e Binary files /dev/null and b/new-planet-backend/app/crud/__pycache__/task.cpython-313.pyc differ diff --git a/new-planet-backend/app/crud/__pycache__/user.cpython-313.pyc b/new-planet-backend/app/crud/__pycache__/user.cpython-313.pyc new file mode 100644 index 0000000..0f4353c Binary files /dev/null and b/new-planet-backend/app/crud/__pycache__/user.cpython-313.pyc differ diff --git a/new-planet-backend/app/db/__pycache__/__init__.cpython-313.pyc b/new-planet-backend/app/db/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000..9e1db1c Binary files /dev/null and b/new-planet-backend/app/db/__pycache__/__init__.cpython-313.pyc differ diff --git a/new-planet-backend/app/db/__pycache__/base.cpython-313.pyc b/new-planet-backend/app/db/__pycache__/base.cpython-313.pyc new file mode 100644 index 0000000..673bbc0 Binary files /dev/null and b/new-planet-backend/app/db/__pycache__/base.cpython-313.pyc differ diff --git a/new-planet-backend/app/db/__pycache__/session.cpython-313.pyc b/new-planet-backend/app/db/__pycache__/session.cpython-313.pyc new file mode 100644 index 0000000..94cd423 Binary files /dev/null and b/new-planet-backend/app/db/__pycache__/session.cpython-313.pyc differ diff --git a/new-planet-backend/app/middleware/__pycache__/__init__.cpython-313.pyc b/new-planet-backend/app/middleware/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000..bedb909 Binary files /dev/null and b/new-planet-backend/app/middleware/__pycache__/__init__.cpython-313.pyc differ diff --git a/new-planet-backend/app/middleware/__pycache__/auth.cpython-313.pyc b/new-planet-backend/app/middleware/__pycache__/auth.cpython-313.pyc new file mode 100644 index 0000000..43b0f99 Binary files /dev/null and b/new-planet-backend/app/middleware/__pycache__/auth.cpython-313.pyc differ diff --git a/new-planet-backend/app/middleware/__pycache__/cors.cpython-313.pyc b/new-planet-backend/app/middleware/__pycache__/cors.cpython-313.pyc new file mode 100644 index 0000000..e1a4dfa Binary files /dev/null and b/new-planet-backend/app/middleware/__pycache__/cors.cpython-313.pyc differ diff --git a/new-planet-backend/app/middleware/__pycache__/error_handler.cpython-313.pyc b/new-planet-backend/app/middleware/__pycache__/error_handler.cpython-313.pyc new file mode 100644 index 0000000..4dcecc0 Binary files /dev/null and b/new-planet-backend/app/middleware/__pycache__/error_handler.cpython-313.pyc differ diff --git a/new-planet-backend/app/middleware/__pycache__/rate_limiter.cpython-313.pyc b/new-planet-backend/app/middleware/__pycache__/rate_limiter.cpython-313.pyc new file mode 100644 index 0000000..5a47b52 Binary files /dev/null and b/new-planet-backend/app/middleware/__pycache__/rate_limiter.cpython-313.pyc differ diff --git a/new-planet-backend/app/models/__pycache__/__init__.cpython-313.pyc b/new-planet-backend/app/models/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000..8c6a960 Binary files /dev/null and b/new-planet-backend/app/models/__pycache__/__init__.cpython-313.pyc differ diff --git a/new-planet-backend/app/models/__pycache__/ai_conversation.cpython-313.pyc b/new-planet-backend/app/models/__pycache__/ai_conversation.cpython-313.pyc new file mode 100644 index 0000000..fb6434c Binary files /dev/null and b/new-planet-backend/app/models/__pycache__/ai_conversation.cpython-313.pyc differ diff --git a/new-planet-backend/app/models/__pycache__/reward.cpython-313.pyc b/new-planet-backend/app/models/__pycache__/reward.cpython-313.pyc new file mode 100644 index 0000000..4bb9bf4 Binary files /dev/null and b/new-planet-backend/app/models/__pycache__/reward.cpython-313.pyc differ diff --git a/new-planet-backend/app/models/__pycache__/schedule.cpython-313.pyc b/new-planet-backend/app/models/__pycache__/schedule.cpython-313.pyc new file mode 100644 index 0000000..ec3a1df Binary files /dev/null and b/new-planet-backend/app/models/__pycache__/schedule.cpython-313.pyc differ diff --git a/new-planet-backend/app/models/__pycache__/task.cpython-313.pyc b/new-planet-backend/app/models/__pycache__/task.cpython-313.pyc new file mode 100644 index 0000000..2484596 Binary files /dev/null and b/new-planet-backend/app/models/__pycache__/task.cpython-313.pyc differ diff --git a/new-planet-backend/app/models/__pycache__/user.cpython-313.pyc b/new-planet-backend/app/models/__pycache__/user.cpython-313.pyc new file mode 100644 index 0000000..1465dbc Binary files /dev/null and b/new-planet-backend/app/models/__pycache__/user.cpython-313.pyc differ diff --git a/new-planet-backend/app/schemas/__pycache__/__init__.cpython-313.pyc b/new-planet-backend/app/schemas/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000..05feed4 Binary files /dev/null and b/new-planet-backend/app/schemas/__pycache__/__init__.cpython-313.pyc differ diff --git a/new-planet-backend/app/schemas/__pycache__/ai.cpython-313.pyc b/new-planet-backend/app/schemas/__pycache__/ai.cpython-313.pyc new file mode 100644 index 0000000..7c950c8 Binary files /dev/null and b/new-planet-backend/app/schemas/__pycache__/ai.cpython-313.pyc differ diff --git a/new-planet-backend/app/schemas/__pycache__/reward.cpython-313.pyc b/new-planet-backend/app/schemas/__pycache__/reward.cpython-313.pyc new file mode 100644 index 0000000..90c9116 Binary files /dev/null and b/new-planet-backend/app/schemas/__pycache__/reward.cpython-313.pyc differ diff --git a/new-planet-backend/app/schemas/__pycache__/schedule.cpython-313.pyc b/new-planet-backend/app/schemas/__pycache__/schedule.cpython-313.pyc new file mode 100644 index 0000000..5bee4f9 Binary files /dev/null and b/new-planet-backend/app/schemas/__pycache__/schedule.cpython-313.pyc differ diff --git a/new-planet-backend/app/schemas/__pycache__/task.cpython-313.pyc b/new-planet-backend/app/schemas/__pycache__/task.cpython-313.pyc new file mode 100644 index 0000000..9df279d Binary files /dev/null and b/new-planet-backend/app/schemas/__pycache__/task.cpython-313.pyc differ diff --git a/new-planet-backend/app/schemas/__pycache__/token.cpython-313.pyc b/new-planet-backend/app/schemas/__pycache__/token.cpython-313.pyc new file mode 100644 index 0000000..a270bea Binary files /dev/null and b/new-planet-backend/app/schemas/__pycache__/token.cpython-313.pyc differ diff --git a/new-planet-backend/app/schemas/__pycache__/user.cpython-313.pyc b/new-planet-backend/app/schemas/__pycache__/user.cpython-313.pyc new file mode 100644 index 0000000..ef7356d Binary files /dev/null and b/new-planet-backend/app/schemas/__pycache__/user.cpython-313.pyc differ diff --git a/new-planet-backend/app/services/__init__.py b/new-planet-backend/app/services/__init__.py index 2bc7d48..a857381 100644 --- a/new-planet-backend/app/services/__init__.py +++ b/new-planet-backend/app/services/__init__.py @@ -4,6 +4,7 @@ from app.services.storage_service import storage_service, StorageService from app.services.gigachat_service import gigachat_service, GigaChatService from app.services.chat_service import chat_service, ChatService from app.services.schedule_generator import schedule_generator, ScheduleGenerator +from app.services.ai_agent_client import ai_agent_client, AIAgentClient __all__ = [ "auth_service", @@ -18,5 +19,7 @@ __all__ = [ "ChatService", "schedule_generator", "ScheduleGenerator", + "ai_agent_client", + "AIAgentClient", ] diff --git a/new-planet-backend/app/services/__pycache__/__init__.cpython-313.pyc b/new-planet-backend/app/services/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000..6decf26 Binary files /dev/null and b/new-planet-backend/app/services/__pycache__/__init__.cpython-313.pyc differ diff --git a/new-planet-backend/app/services/__pycache__/ai_agent_client.cpython-313.pyc b/new-planet-backend/app/services/__pycache__/ai_agent_client.cpython-313.pyc new file mode 100644 index 0000000..94705ce Binary files /dev/null and b/new-planet-backend/app/services/__pycache__/ai_agent_client.cpython-313.pyc differ diff --git a/new-planet-backend/app/services/__pycache__/auth_service.cpython-313.pyc b/new-planet-backend/app/services/__pycache__/auth_service.cpython-313.pyc new file mode 100644 index 0000000..6f2ae65 Binary files /dev/null and b/new-planet-backend/app/services/__pycache__/auth_service.cpython-313.pyc differ diff --git a/new-planet-backend/app/services/__pycache__/cache_service.cpython-313.pyc b/new-planet-backend/app/services/__pycache__/cache_service.cpython-313.pyc new file mode 100644 index 0000000..f1ef06b Binary files /dev/null and b/new-planet-backend/app/services/__pycache__/cache_service.cpython-313.pyc differ diff --git a/new-planet-backend/app/services/__pycache__/chat_service.cpython-313.pyc b/new-planet-backend/app/services/__pycache__/chat_service.cpython-313.pyc new file mode 100644 index 0000000..3722fa3 Binary files /dev/null and b/new-planet-backend/app/services/__pycache__/chat_service.cpython-313.pyc differ diff --git a/new-planet-backend/app/services/__pycache__/gigachat_service.cpython-313.pyc b/new-planet-backend/app/services/__pycache__/gigachat_service.cpython-313.pyc new file mode 100644 index 0000000..1acbb79 Binary files /dev/null and b/new-planet-backend/app/services/__pycache__/gigachat_service.cpython-313.pyc differ diff --git a/new-planet-backend/app/services/__pycache__/schedule_generator.cpython-313.pyc b/new-planet-backend/app/services/__pycache__/schedule_generator.cpython-313.pyc new file mode 100644 index 0000000..325bca1 Binary files /dev/null and b/new-planet-backend/app/services/__pycache__/schedule_generator.cpython-313.pyc differ diff --git a/new-planet-backend/app/services/__pycache__/storage_service.cpython-313.pyc b/new-planet-backend/app/services/__pycache__/storage_service.cpython-313.pyc new file mode 100644 index 0000000..b926ed4 Binary files /dev/null and b/new-planet-backend/app/services/__pycache__/storage_service.cpython-313.pyc differ diff --git a/new-planet-backend/app/services/ai_agent_client.py b/new-planet-backend/app/services/ai_agent_client.py new file mode 100644 index 0000000..69f39cd --- /dev/null +++ b/new-planet-backend/app/services/ai_agent_client.py @@ -0,0 +1,117 @@ +import aiohttp +from typing import Optional, List, Dict, Any +from app.core.config import settings + + +class AIAgentClient: + """ + Клиент для взаимодействия с внешним AI-agent сервисом. + + Сервис должен быть доступен в Docker сети и предоставлять следующие endpoints: + - POST /api/v1/chat - для чата с ИИ + - POST /api/v1/schedule/generate - для генерации расписаний + + Примечание: Структура API endpoints может отличаться в зависимости от реализации + внешнего сервиса. При необходимости измените пути в методах этого класса. + """ + + def __init__(self, base_url: Optional[str] = None): + self.base_url = base_url or settings.AI_AGENT_BASE_URL + if not self.base_url.endswith('/'): + self.base_url = self.base_url.rstrip('/') + + async def chat( + self, + message: str, + conversation_id: Optional[str] = None, + context: Optional[List[Dict[str, Any]]] = None + ) -> Dict[str, Any]: + """ + Отправить сообщение в чат через AI-agent сервис. + + Ожидаемый формат ответа от сервиса: + { + "response": "текст ответа", + "conversation_id": "id беседы", + "tokens_used": 100, + "model": "модель" + } + или формат GigaChat API (с полем choices). + """ + url = f"{self.base_url}/api/v1/chat" + + payload = { + "message": message, + } + + if conversation_id: + payload["conversation_id"] = conversation_id + + if context: + payload["context"] = context + + async with aiohttp.ClientSession() as session: + async with session.post(url, json=payload, timeout=aiohttp.ClientTimeout(total=120)) as response: + if response.status != 200: + error_text = await response.text() + raise Exception( + f"AI-agent service error: HTTP {response.status} - {error_text}" + ) + + result = await response.json() + return result + + async def generate_schedule( + self, + child_age: int, + preferences: List[str], + date: str, + description: Optional[str] = None + ) -> Dict[str, Any]: + """Сгенерировать расписание через AI-agent сервис""" + url = f"{self.base_url}/api/v1/schedule/generate" + + payload = { + "child_age": child_age, + "preferences": preferences, + "date": date + } + + if description: + payload["description"] = description + + async with aiohttp.ClientSession() as session: + async with session.post(url, json=payload, timeout=aiohttp.ClientTimeout(total=120)) as response: + if response.status != 200: + error_text = await response.text() + raise Exception( + f"AI-agent service error: HTTP {response.status} - {error_text}" + ) + + result = await response.json() + return result + + async def generate_text( + self, + prompt: str, + model: Optional[str] = None + ) -> str: + """Генерация текста по промпту через AI-agent сервис""" + # Для совместимости с текущим интерфейсом используем chat endpoint + result = await self.chat(message=prompt) + + # Извлекаем текст ответа + # Предполагаем, что ответ имеет структуру ChatResponse + response_text = result.get("response", "") + if not response_text: + # Если структура другая, пытаемся извлечь из choices (как в GigaChat формате) + choices = result.get("choices", []) + if choices: + response_text = choices[0].get("message", {}).get("content", "") + + return response_text + + +# Создаем экземпляр клиента +ai_agent_client = AIAgentClient() + diff --git a/new-planet-backend/app/services/gigachat_service.py b/new-planet-backend/app/services/gigachat_service.py index e7e73b8..90d5588 100644 --- a/new-planet-backend/app/services/gigachat_service.py +++ b/new-planet-backend/app/services/gigachat_service.py @@ -7,19 +7,26 @@ import time from urllib.parse import urlencode from typing import Optional, List, Dict, Any -from dotenv import load_dotenv - from app.core.config import settings - -load_dotenv() +from app.services.ai_agent_client import ai_agent_client class GigaChatService: + """ + Сервис для работы с GigaChat через внешний AI-agent сервис. + Все запросы к GigaChat теперь проходят через внешний сервис. + """ def __init__(self): self.access_token: Optional[str] = None self.token_expires_at: Optional[float] = None async def _get_token(self) -> str: - """Получить OAuth токен""" + """ + Получить OAuth токен. + + ВНИМАНИЕ: Этот метод больше не используется, так как все запросы + к GigaChat теперь проходят через внешний AI-agent сервис. + Метод оставлен для возможной обратной совместимости. + """ # Проверяем, не истек ли токен (оставляем запас 60 секунд) if self.access_token and self.token_expires_at: if time.time() < (self.token_expires_at - 60): @@ -110,49 +117,59 @@ class GigaChatService: context: Optional[List[Dict[str, Any]]] = None, model: str = None ) -> Dict[str, Any]: - """Отправить сообщение в GigaChat""" - token = await self._get_token() - model = model or settings.GIGACHAT_MODEL_CHAT or "GigaChat" - - messages = context or [] - messages.append({"role": "user", "content": message}) - - headers = { - "Authorization": f"Bearer {token}", - "Content-Type": "application/json" - } - - payload = { - "model": model, - "messages": messages, - "temperature": 0.7, - "max_tokens": 2000 - } - - # Отключаем проверку SSL (только для разработки!) - # Используем ssl=False для полного отключения проверки сертификата - connector = aiohttp.TCPConnector(ssl=False) - async with aiohttp.ClientSession(connector=connector) as session: - async with session.post( - f"{settings.GIGACHAT_BASE_URL}/chat/completions", - headers=headers, - json=payload - ) as response: - if response.status != 200: - error_text = await response.text() - raise Exception(f"GigaChat API error: {response.status} - {error_text}") - - result = await response.json() + """ + Отправить сообщение в GigaChat через внешний AI-agent сервис. + Сохраняет обратную совместимость с форматом ответа GigaChat API. + """ + try: + # Используем внешний AI-agent сервис + result = await ai_agent_client.chat( + message=message, + conversation_id=None, # Если нужен conversation_id, его нужно передавать отдельно + context=context + ) + + # Преобразуем ответ AI-agent сервиса в формат, совместимый с GigaChat API + # Предполагаем, что ai_agent_client возвращает структуру ChatResponse или аналогичную + if "response" in result: + # Если ответ в формате ChatResponse, преобразуем в формат GigaChat + return { + "model": result.get("model", model or settings.GIGACHAT_MODEL_CHAT or "GigaChat"), + "choices": [{ + "message": { + "role": "assistant", + "content": result["response"] + }, + "finish_reason": "stop" + }], + "usage": { + "total_tokens": result.get("tokens_used", 0), + "prompt_tokens": 0, + "completion_tokens": result.get("tokens_used", 0) + } + } + else: + # Если ответ уже в формате GigaChat, возвращаем как есть return result + except Exception as e: + # Если внешний сервис недоступен, пробрасываем ошибку + raise Exception(f"AI-agent service error: {str(e)}") async def generate_text( self, prompt: str, model: str = None ) -> str: - """Генерация текста по промпту""" - result = await self.chat(prompt, model=model) - return result.get("choices", [{}])[0].get("message", {}).get("content", "") + """ + Генерация текста по промпту через внешний AI-agent сервис. + """ + try: + # Используем метод generate_text из ai_agent_client + response_text = await ai_agent_client.generate_text(prompt=prompt, model=model) + return response_text + except Exception as e: + # Если произошла ошибка, пробрасываем её + raise Exception(f"AI-agent service error: {str(e)}") gigachat_service = GigaChatService() diff --git a/new-planet-backend/app/services/schedule_generator.py b/new-planet-backend/app/services/schedule_generator.py index e5be809..c26aa98 100644 --- a/new-planet-backend/app/services/schedule_generator.py +++ b/new-planet-backend/app/services/schedule_generator.py @@ -1,11 +1,14 @@ import json from typing import List, Dict, Any, Optional from sqlalchemy.ext.asyncio import AsyncSession +from sqlalchemy import select +from sqlalchemy.orm import selectinload from app.services.gigachat_service import gigachat_service from app.core.config import settings from app.crud import schedule as crud_schedule, task as crud_task from app.schemas.schedule import ScheduleCreate from app.schemas.task import TaskCreate +from app.models.schedule import Schedule from datetime import date @@ -104,11 +107,17 @@ class ScheduleGenerator: await crud_task.create(db, task_create.model_dump()) - await db.refresh(db_schedule) + # Загружаем расписание с задачами через selectinload для async корректной работы + result = await db.execute( + select(Schedule) + .where(Schedule.id == db_schedule.id) + .options(selectinload(Schedule.tasks)) + ) + db_schedule_with_tasks = result.scalar_one() return { - "schedule_id": db_schedule.id, - "title": db_schedule.title, + "schedule_id": db_schedule_with_tasks.id, + "title": db_schedule_with_tasks.title, "tasks": [ { "title": task.title, @@ -117,7 +126,7 @@ class ScheduleGenerator: "category": task.category, "order": task.order } - for task in db_schedule.tasks + for task in db_schedule_with_tasks.tasks ] } except json.JSONDecodeError as e: diff --git a/new-planet-backend/docker/docker-compose.yml b/new-planet-backend/docker/docker-compose.yml index c75e92b..f46c246 100644 --- a/new-planet-backend/docker/docker-compose.yml +++ b/new-planet-backend/docker/docker-compose.yml @@ -63,4 +63,8 @@ volumes: networks: new-planet-network: driver: bridge + # ВАЖНО: Внешний AI-agent сервис (https://git.bro-js.ru/Glevel/New-planet-ai-agent.git) + # должен быть запущен в этой же сети для доступа к GigaChat. + # Убедитесь, что сервис ai-agent доступен по имени 'ai-agent' в сети new-planet-network. + external: false diff --git a/new-planet-backend/logs/app.log b/new-planet-backend/logs/app.log index fb61425..56cb9dc 100644 --- a/new-planet-backend/logs/app.log +++ b/new-planet-backend/logs/app.log @@ -1580,3 +1580,15 @@ redis.exceptions.ConnectionError: Error 111 connecting to localhost:6379. Connec 2025-12-18 23:00:15 - root - INFO - Starting up... 2025-12-18 23:00:15 - root - INFO - Shutting down... 2025-12-18 23:00:15 - root - INFO - Shutting down... +2025-12-23 19:00:39 - root - INFO - Starting up... +2025-12-23 19:00:39 - root - INFO - Starting up... +2025-12-23 19:52:34 - root - INFO - Shutting down... +2025-12-23 19:52:34 - root - INFO - Shutting down... +2025-12-23 19:52:58 - root - INFO - Starting up... +2025-12-23 19:52:58 - root - INFO - Starting up... +2025-12-23 19:54:27 - root - INFO - Shutting down... +2025-12-23 19:54:27 - root - INFO - Shutting down... +2025-12-23 19:54:34 - root - INFO - Starting up... +2025-12-23 19:54:34 - root - INFO - Starting up... +2025-12-23 20:00:23 - root - INFO - Shutting down... +2025-12-23 20:00:23 - root - INFO - Shutting down...