From 32bfec20745801765698405ecb31ca0676c0137f Mon Sep 17 00:00:00 2001 From: FDKost Date: Wed, 24 Dec 2025 01:59:39 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D1=8B=20=D0=BD=D0=B0=D1=81=D1=82=D1=80=D0=BE=D0=B9=D0=BA?= =?UTF-8?q?=D0=B8=20=D0=B4=D0=BB=D1=8F=20=D0=B8=D0=BD=D1=82=D0=B5=D0=B3?= =?UTF-8?q?=D1=80=D0=B0=D1=86=D0=B8=D0=B8=20=D1=81=20AI-agent=20=D1=81?= =?UTF-8?q?=D0=B5=D1=80=D0=B2=D0=B8=D1=81=D0=BE=D0=BC.=20=D0=98=D0=B7?= =?UTF-8?q?=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD=D1=8B=20=D0=BF=D0=B5=D1=80=D0=B5?= =?UTF-8?q?=D0=BC=D0=B5=D0=BD=D0=BD=D1=8B=D0=B5=20=D0=BE=D0=BA=D1=80=D1=83?= =?UTF-8?q?=D0=B6=D0=B5=D0=BD=D0=B8=D1=8F=20=D0=B2=20.env,=20=D0=B4=D0=BE?= =?UTF-8?q?=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=20=D0=BF=D1=83=D1=82=D1=8C?= =?UTF-8?q?=20=D0=BA=20.env=20=D0=B2=20=D0=BA=D0=BE=D0=BD=D1=84=D0=B8?= =?UTF-8?q?=D0=B3=D1=83=D1=80=D0=B0=D1=86=D0=B8=D0=B8,=20=D0=BE=D0=B1?= =?UTF-8?q?=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5=D0=BD=20GigaChatService=20=D0=B4?= =?UTF-8?q?=D0=BB=D1=8F=20=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D1=8B=20=D1=87?= =?UTF-8?q?=D0=B5=D1=80=D0=B5=D0=B7=20AI-agent.=20=D0=A2=D0=B0=D0=BA=D0=B6?= =?UTF-8?q?=D0=B5=20=D0=B8=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD?= =?UTF-8?q?=D1=8B=20=D0=B7=D0=B0=D0=BF=D1=80=D0=BE=D1=81=D1=8B=20=D0=B2=20?= =?UTF-8?q?ScheduleGenerator=20=D0=B4=D0=BB=D1=8F=20=D0=BA=D0=BE=D1=80?= =?UTF-8?q?=D1=80=D0=B5=D0=BA=D1=82=D0=BD=D0=BE=D0=B9=20=D0=B7=D0=B0=D0=B3?= =?UTF-8?q?=D1=80=D1=83=D0=B7=D0=BA=D0=B8=20=D0=B7=D0=B0=D0=B4=D0=B0=D1=87?= =?UTF-8?q?.=20=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5=D0=BD=20docker-c?= =?UTF-8?q?ompose=20=D0=B4=D0=BB=D1=8F=20=D0=BF=D0=BE=D0=B4=D0=BA=D0=BB?= =?UTF-8?q?=D1=8E=D1=87=D0=B5=D0=BD=D0=B8=D1=8F=20=D0=BA=20AI-agent=20?= =?UTF-8?q?=D1=81=D0=B5=D1=80=D0=B2=D0=B8=D1=81=D1=83.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- logs/app.log | 36 ++++++ new-planet-backend/.env | 6 +- .../app/__pycache__/__init__.cpython-313.pyc | Bin 0 -> 191 bytes .../app/__pycache__/config.cpython-313.pyc | Bin 0 -> 267 bytes .../app/__pycache__/main.cpython-313.pyc | Bin 0 -> 3792 bytes .../api/__pycache__/__init__.cpython-313.pyc | Bin 0 -> 195 bytes .../app/api/__pycache__/deps.cpython-313.pyc | Bin 0 -> 1889 bytes .../v1/__pycache__/__init__.cpython-313.pyc | Bin 0 -> 280 bytes .../app/api/v1/__pycache__/ai.cpython-313.pyc | Bin 0 -> 3526 bytes .../api/v1/__pycache__/auth.cpython-313.pyc | Bin 0 -> 3282 bytes .../api/v1/__pycache__/images.cpython-313.pyc | Bin 0 -> 3050 bytes .../v1/__pycache__/rewards.cpython-313.pyc | Bin 0 -> 5918 bytes .../api/v1/__pycache__/router.cpython-313.pyc | Bin 0 -> 1139 bytes .../v1/__pycache__/schedules.cpython-313.pyc | Bin 0 -> 6531 bytes .../api/v1/__pycache__/tasks.cpython-313.pyc | Bin 0 -> 7023 bytes .../v1/__pycache__/websocket.cpython-313.pyc | Bin 0 -> 5674 bytes .../core/__pycache__/__init__.cpython-313.pyc | Bin 0 -> 480 bytes .../core/__pycache__/config.cpython-313.pyc | Bin 0 -> 4415 bytes .../core/__pycache__/logging.cpython-313.pyc | Bin 0 -> 1445 bytes .../core/__pycache__/security.cpython-313.pyc | Bin 0 -> 4452 bytes new-planet-backend/app/core/config.py | 21 +++- .../crud/__pycache__/__init__.cpython-313.pyc | Bin 0 -> 452 bytes .../app/crud/__pycache__/base.cpython-313.pyc | Bin 0 -> 4562 bytes .../crud/__pycache__/schedule.cpython-313.pyc | Bin 0 -> 3476 bytes .../app/crud/__pycache__/task.cpython-313.pyc | Bin 0 -> 2221 bytes .../app/crud/__pycache__/user.cpython-313.pyc | Bin 0 -> 2955 bytes .../db/__pycache__/__init__.cpython-313.pyc | Bin 0 -> 533 bytes .../app/db/__pycache__/base.cpython-313.pyc | Bin 0 -> 1307 bytes .../db/__pycache__/session.cpython-313.pyc | Bin 0 -> 1261 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 606 bytes .../__pycache__/auth.cpython-313.pyc | Bin 0 -> 2428 bytes .../__pycache__/cors.cpython-313.pyc | Bin 0 -> 734 bytes .../__pycache__/error_handler.cpython-313.pyc | Bin 0 -> 1895 bytes .../__pycache__/rate_limiter.cpython-313.pyc | Bin 0 -> 2070 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 533 bytes .../ai_conversation.cpython-313.pyc | Bin 0 -> 1217 bytes .../models/__pycache__/reward.cpython-313.pyc | Bin 0 -> 1180 bytes .../__pycache__/schedule.cpython-313.pyc | Bin 0 -> 1136 bytes .../models/__pycache__/task.cpython-313.pyc | Bin 0 -> 1292 bytes .../models/__pycache__/user.cpython-313.pyc | Bin 0 -> 1480 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 982 bytes .../schemas/__pycache__/ai.cpython-313.pyc | Bin 0 -> 5331 bytes .../__pycache__/reward.cpython-313.pyc | Bin 0 -> 2260 bytes .../__pycache__/schedule.cpython-313.pyc | Bin 0 -> 2149 bytes .../schemas/__pycache__/task.cpython-313.pyc | Bin 0 -> 2532 bytes .../schemas/__pycache__/token.cpython-313.pyc | Bin 0 -> 965 bytes .../schemas/__pycache__/user.cpython-313.pyc | Bin 0 -> 2210 bytes new-planet-backend/app/services/__init__.py | 3 + .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 943 bytes .../ai_agent_client.cpython-313.pyc | Bin 0 -> 6194 bytes .../__pycache__/auth_service.cpython-313.pyc | Bin 0 -> 3474 bytes .../__pycache__/cache_service.cpython-313.pyc | Bin 0 -> 4519 bytes .../__pycache__/chat_service.cpython-313.pyc | Bin 0 -> 4163 bytes .../gigachat_service.cpython-313.pyc | Bin 0 -> 7704 bytes .../schedule_generator.cpython-313.pyc | Bin 0 -> 6491 bytes .../storage_service.cpython-313.pyc | Bin 0 -> 4002 bytes .../app/services/ai_agent_client.py | 117 ++++++++++++++++++ .../app/services/gigachat_service.py | 99 +++++++++------ .../app/services/schedule_generator.py | 17 ++- new-planet-backend/docker/docker-compose.yml | 4 + new-planet-backend/logs/app.log | 12 ++ 61 files changed, 266 insertions(+), 49 deletions(-) create mode 100644 logs/app.log create mode 100644 new-planet-backend/app/__pycache__/__init__.cpython-313.pyc create mode 100644 new-planet-backend/app/__pycache__/config.cpython-313.pyc create mode 100644 new-planet-backend/app/__pycache__/main.cpython-313.pyc create mode 100644 new-planet-backend/app/api/__pycache__/__init__.cpython-313.pyc create mode 100644 new-planet-backend/app/api/__pycache__/deps.cpython-313.pyc create mode 100644 new-planet-backend/app/api/v1/__pycache__/__init__.cpython-313.pyc create mode 100644 new-planet-backend/app/api/v1/__pycache__/ai.cpython-313.pyc create mode 100644 new-planet-backend/app/api/v1/__pycache__/auth.cpython-313.pyc create mode 100644 new-planet-backend/app/api/v1/__pycache__/images.cpython-313.pyc create mode 100644 new-planet-backend/app/api/v1/__pycache__/rewards.cpython-313.pyc create mode 100644 new-planet-backend/app/api/v1/__pycache__/router.cpython-313.pyc create mode 100644 new-planet-backend/app/api/v1/__pycache__/schedules.cpython-313.pyc create mode 100644 new-planet-backend/app/api/v1/__pycache__/tasks.cpython-313.pyc create mode 100644 new-planet-backend/app/api/v1/__pycache__/websocket.cpython-313.pyc create mode 100644 new-planet-backend/app/core/__pycache__/__init__.cpython-313.pyc create mode 100644 new-planet-backend/app/core/__pycache__/config.cpython-313.pyc create mode 100644 new-planet-backend/app/core/__pycache__/logging.cpython-313.pyc create mode 100644 new-planet-backend/app/core/__pycache__/security.cpython-313.pyc create mode 100644 new-planet-backend/app/crud/__pycache__/__init__.cpython-313.pyc create mode 100644 new-planet-backend/app/crud/__pycache__/base.cpython-313.pyc create mode 100644 new-planet-backend/app/crud/__pycache__/schedule.cpython-313.pyc create mode 100644 new-planet-backend/app/crud/__pycache__/task.cpython-313.pyc create mode 100644 new-planet-backend/app/crud/__pycache__/user.cpython-313.pyc create mode 100644 new-planet-backend/app/db/__pycache__/__init__.cpython-313.pyc create mode 100644 new-planet-backend/app/db/__pycache__/base.cpython-313.pyc create mode 100644 new-planet-backend/app/db/__pycache__/session.cpython-313.pyc create mode 100644 new-planet-backend/app/middleware/__pycache__/__init__.cpython-313.pyc create mode 100644 new-planet-backend/app/middleware/__pycache__/auth.cpython-313.pyc create mode 100644 new-planet-backend/app/middleware/__pycache__/cors.cpython-313.pyc create mode 100644 new-planet-backend/app/middleware/__pycache__/error_handler.cpython-313.pyc create mode 100644 new-planet-backend/app/middleware/__pycache__/rate_limiter.cpython-313.pyc create mode 100644 new-planet-backend/app/models/__pycache__/__init__.cpython-313.pyc create mode 100644 new-planet-backend/app/models/__pycache__/ai_conversation.cpython-313.pyc create mode 100644 new-planet-backend/app/models/__pycache__/reward.cpython-313.pyc create mode 100644 new-planet-backend/app/models/__pycache__/schedule.cpython-313.pyc create mode 100644 new-planet-backend/app/models/__pycache__/task.cpython-313.pyc create mode 100644 new-planet-backend/app/models/__pycache__/user.cpython-313.pyc create mode 100644 new-planet-backend/app/schemas/__pycache__/__init__.cpython-313.pyc create mode 100644 new-planet-backend/app/schemas/__pycache__/ai.cpython-313.pyc create mode 100644 new-planet-backend/app/schemas/__pycache__/reward.cpython-313.pyc create mode 100644 new-planet-backend/app/schemas/__pycache__/schedule.cpython-313.pyc create mode 100644 new-planet-backend/app/schemas/__pycache__/task.cpython-313.pyc create mode 100644 new-planet-backend/app/schemas/__pycache__/token.cpython-313.pyc create mode 100644 new-planet-backend/app/schemas/__pycache__/user.cpython-313.pyc create mode 100644 new-planet-backend/app/services/__pycache__/__init__.cpython-313.pyc create mode 100644 new-planet-backend/app/services/__pycache__/ai_agent_client.cpython-313.pyc create mode 100644 new-planet-backend/app/services/__pycache__/auth_service.cpython-313.pyc create mode 100644 new-planet-backend/app/services/__pycache__/cache_service.cpython-313.pyc create mode 100644 new-planet-backend/app/services/__pycache__/chat_service.cpython-313.pyc create mode 100644 new-planet-backend/app/services/__pycache__/gigachat_service.cpython-313.pyc create mode 100644 new-planet-backend/app/services/__pycache__/schedule_generator.cpython-313.pyc create mode 100644 new-planet-backend/app/services/__pycache__/storage_service.cpython-313.pyc create mode 100644 new-planet-backend/app/services/ai_agent_client.py 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 0000000000000000000000000000000000000000..76e43cecd63ad2f1f2e381bfb6e5cb1aa6adeedd GIT binary patch literal 191 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 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..0be6cd76597e457eb70ea0f502af93e601e9c889 GIT binary patch literal 1889 zcmaJ>&udynd7SCv9GgBSS&}hag z&6{+!-ziN?>ooyV(RYgp%;5X4>^aXl9E!Eim?L zM&T5n!jEu@aD*@VX6R1rnf7&#l?Ai9t^)Xw)bQp5!wp(=NqpAti;DCWh^E_rbu@}sHXyZjuNk}Ds=YWJ?Y z;y$k5tbgu4tS{AXCF@J>kM1LId;#MR?n=`AnK5p;4`96S-eZKv^)Hj|L-zrtuegtZ z`jdO_+MW}oie)5=B_~8!?Ucj1xi9O}xpg%BteOPjm_hlgnvOJJU(Mf9Qz4ZQtpqW@W9q@EaQL^F-

Hp^vGj&4 z3`nlf_acO%yPrjdpGJni6IUbY#Sa>Cpr4Q@&uO61 zvPmdon-XJff7-_I?WR*B^!oR9+MigOr7z&iwKTr!q&0fSnI%GR2rmNvJ8jIu5_ad2 z0CoDQlj@YIjr3DrAN95GJv+Vq7Hmm9O5>NIXDmBSwMytk;e|_-IaaXg@fe!NAxuAn zem5Bevk5P170G`L)>kb2KFNTOR?q$vOq1t0ZVm1J4UN^&*cuvLLzy+ScMa`dqtoQ? zv3+j(cs+JvF}&eN@xJAO)$ZY6diN|>zq!64_HwaCFw*2_zcp0 zE7jR5CbT%Us5quFEi)%G#wE2lyClCLCLkv($@GQ*ho_{_Y_lK6PNg34PQHo5sJr8%i~MVvre8G*Q%A4q&)W@Kc%%b@Xq OTf9TBk-dl=Ce z7ZNO0wcSXu)JjoQMWLVKs+E#dYK4+ojq+BJzhE!<09^$oRX?Mb&PVF)X2(56Hn zqO?Q1(g7VxCv+-Nh$=CNDH2FZ7j)U}z3FZx4sqM|rJqoGpvSiT>0YG|`fR%;Ei3)d zZ`*MY2C z&W3Ys*|teO#~&d%|7lzwR&3Afc&GSmBp1%M=K|S|ocokJ+u2QC5?|sPvB$nAb~M-i zKgEtT#f}|{J-#3%y1r$TN{E&(b@@W3ykbzWJkQe#EfsYu_~Ml-m#1GT(2AjzOO{(V zRAWU?a8@9tuayc}s_TfO?_QurzIYX_7_$m10JLP})qnhvEdoG+JF zDd;K-oA6sL=NDBYL$9w;-LL{RN3WDiI<;ci!XhoMEYTm*5(U+uPBZDzih7s!=IAeK zx>1HTtD_mbh~Nc-E?b>Wkl9MHDR%TQT#wwDp@s7DGOmq1b7v~i!*H!RTc-m4SRQ|S zRVz^RBYORB@(Z=!DYJzM7F2|rnuQm%1%#Tq@|M@>YKexbU&C(xE2z%{#fhUAdU(!= zcy($RT4_PQ;TmJXSR%h+C7eDP{QV0lq5jO4$-Z{I{QKx8C( zFPW=X5|ZH?X2Uo_X8BnzBQ}7BF^fmUq;LTbghd=>+A`kdip(bC5avC}LhF;9v(jE6lYz-mK`5EJRN7S#gr5T$V41DRG{gCsRTnndi<3 z^IXEUGKqc6cg&6IZMk|&HrLJdQFFumz`SRETD@(4W_}_MnQxmPBlf9z50MSodK_vpGgYJ-0TmEor&usea8US8|t^)DksvGxX)rifxXn745KF zI;g#>7Oo)?a%!c5pO#yFGN)?E%33|=U)GGpysE)C4%~;IzKr5qa+B5WU<9q~Pn*zJEn#18)*@2;POr8}*AE$DrBKR^PV`$WW!q4-x) z@0K)Gm8P~k`+q-hSN+|wyOP;Hyyp^H{kuf)`TxBuV9WpLZ0Oru>KOOxz&Lq_ON#Hh z#>pQU@F#AZZ1__H!bgLtUSYG>h34jffHgNFV-C;8>J+69QGq3*O$7zd^Z%a;nMSH( z+I9QvU!(^l>!cCf$z`tce;zR$v)1D`dsGb}^lGPu55%Aqm6IC=C*} zJIGvzV`W(W9x7SST$ckKBBA$tN$6Yo0roL}TVoxv?56o4exI4|Gg?-EC8M)Zy=DFt z;afHlKQ!;j)z|En_sqZ8tWCJ>)Q3R~W%&w=+EOvEE>Nqb0(73@l~ka3sW}^*XGgx( zQlxqTH2a2|L6$lPG?LL}XvPvnh3Bk}G=B=i!Wkx>MscI(1*9-7%0^jsQbl&UpOxV# zwn+pbhRX6f4FHcb0uxM}WECQt1F+j3*ue$EOt7u6nGYk(I)UO*db^R{D@z6>vG#!8 zFov$x;S85|=EJD?ELO2W^*^AfQ89vyiY2yU6JNw8ny47<*@_NTqeI(L-sad6dV`;B;?u=LWb}Q=!x-*^F?h5plCU#_VB+Z;o)x9`&D- zh0QaA=iL-GX$9kF=6KfBOH+M5`aua)Q(%o#M*1`JShZ^KS>GT>7&-6`uX!|BpzClqe~dX~(rqyP{-S{!yJ4r7Wcpl`1Y*wB2X{VnvQ@CK5@{ zE|o}^%5u=CXwU=*0;Go~23iyfdT|oC75vxc((}?rA!T7DG1^OR6y!sV_R#m1yOJ!_ zXb0HYH*em1JNxFF@6Bc);3d$$xs@*d+D*vcabP#6C2ancBjf`j5s4cmX^wGep7Cjc z32BjuX$Nz}agHB#rd`Zs%EG8S?O`5M7Dv5lAM=^AW7MAxus}MVsv!=R3v&t1Xn!SD)h_p) zQ&jbhGAm^0l`2)W7t3r0CjBXOu9TOks)8$wotLPVD@-PM!<$tpJIkn|QA0!-W*y_@ z*D0F$6$qIFIsBx=XZZufO~#!2$b@KzaS`PpAthk~zh<@xI9H99G0&PkYP=@`_Bbop zJ1Fr3Jmn;=B&38XZi;+g*h{9kQy?dV>I-16U)OKypX)2NtF^`2f_|g+bCBPS>v#2g z`e*QbuHTF6e+J=p?H&D3rt(H@5qxgf-W~gdXJLq8I15x$iqi=f3*yji=hyI_SEj3U zn6WZr4wzy{1V#kGk?Zg6%?+l8a+%?uWQV13Lr^uA5Lq*twV;`Z**7?)uvNR;#yP7l5ayGq0|5T zhcCKGM6e2WK8$s(#*Wuw#~-$|zIWyQlN%19$y+Ca$NR6k04D!ddm-*3mulzUYClMR z!yOPmavUVTMaA#9gXH(#RI6}fUn(qo5q5z1MXLZa^Uj{>@}(j`orS>N@JzvR$rTh$ zc?z1CVH28nKxjboe*-hK1v+rDT9#xm)~f;!z9Y$8y=RRCfHOS28274i7>2E{NQKw?jkXQZb)^ZMFwL=`eSg9ReB0 z>QA9V{5|%Qmc6UZNAEWuT^?NR9jx^Z{$*r!=zMMH{DbBTtNsfM!(aJAHuU;yvHrD| z-nHnV<(MAn+i-~pKhfi@dx<~1@bX3z30&l!s7(-ku_yH$_bHd^5I;+RH17s-oB~d~ zoE%4Tr8ASXU<52(&RlZds(|242%c&aZc8Bie{jnZo1IErmfHeN3_yd?%r>zFz04Np z*>eQgv%zZ@?g)1N#odV@N0oo+U7L z2*?O(60W2XRmI9+p};gTJG`Q(L(rKR@RHbp)wa|3+fJ|SdC>MFU5tF?>wJ38k8D%T zV>j%z-j!TAUGoj;;?NTnQ@WTUDW01bdH}b6yEr0}pW0MhjJc^u=Z#Ix5-YV_^&BYm zkIj;Bt@bvY$;H|`amejmIGp#OhTO4^=da>WJIted3y$zFURXTgC>|sla-ysAJfIQCuW6M6dc@GqRVhiDNw^JMTRGfA+hb) z2`r^X$g)VP6jD&s<``nkXjQLFE7SSQbY?C|-_(){UPFpyhD>Gzp;jadli*@rOBj-x z5kjSk9*Ua8EHVTnLz*+fJLgQum%)yI()?@`LUlZxEh~T`xSw7kV7t;6Y+P HguMI*0-sNB literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..b0e280485bafdfb12f16c2974f1426ff1fc98658 GIT binary patch literal 3050 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 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..21d8e140d17ebc28285e9e060c368c21b6c530bc GIT binary patch literal 6531 zcmdT|TX0jy8Q!CFbhj*97fY70Enfl_zG4gn0!idcz;cj@jzuzKbu>acHVQ@-dn6L* zv>4Jh%rrA4)5+9Kn?k2Aqz|prgn=YYGVqkgBRn0MGdLmBzVIdwOxvV==>H$-NVYMQ znWhijnX~)v<^22a?zjJC?^`S;0_pC@f#hX7A%DS&nyN~~{byN1-XT2UnK2SzDC0$1 zGo}f!lnro{3uvh}prg8gp6Zo8cFYhkQlmn1W2S(aniX0*Ru!;Ni$d$hssmPPRcQTK zO`w+6DzstD7O+!$z(E}WCv_@q#<9A9i@FusG*%z*P>({J#~K2g=%zp;ZS;}|+e&tn zM5axVrqFZhLMkO+6=5QFEi~|!-I|EL6<0#|>Jn|`Yj`VPyPH*dY&)3ZpAoK=M67FS z7PU5@CIE^-9Taf;B#V#>R+a)r?K+X50)jj#v1p6#wL_X^c3_{0)5b zI{qENpI5n7O5m>xO;qYC#e3ldAHSZpJJ_;rzRpMNU~8oD2~MXivZ=fl9pAo=ch|Jd z_tZTU)yK%(i%Bu#)5=Ewq0!K6HX~43KP;q$R6>+32PP&Cjl3Qg(wXFJO4f;)SSBmV z+Ly8dJq7<(`NdPII4_7IbR(}sEF(avn-((B#1WueNX4_13aLyq7SAM43el`6P#he_ zl9dg7{HTz~&Iod~N)1r~7**=wbcwM+ERBW#Z7Lm|7E%I@WoD^QBfC@{`-_c2NH~!d z#Ek5IxI;|OrbI!;U8tr)u@*f(n-FH8MKdkjOTZT0!#n5GP!|-kW=06goOmpmmbEj< z3Hm$a{*38h+>9yQY| z%#PCh56z?t>)MHd1fPM=u#25ye46YSu$3-JpGlwO-pIWvUC*7%z2(iFl|BdZEHr=Y z&CN**<%R|6Q|Y?&kr(>$m$#&AQ2r4HoRh9X{bxZRCtKn)n~18LE}IcwM@~hR&DSIo z%V%CINGiJ4r$wrlrDC(i^Ehc$tXio&eDMn6BC1;Y6VL?2WnN3Fy z&BRhdCK420>rN|VcPyP;UrkkdkHq4~;2uR{=`?)F$jNPy@`OFe-U_Y`^8%zA*T?^&{&Sjzv#6?+BkaE?M1@!M$Q6j+dDg9dRCJz7bnshI3v19_IIq ze=GNg0ibTQG5#*@M!O#AE(Y?`)xF;H&k z?~W3}A3_ovW>w54+;At#H)yhq)Q|xtT9ws&+m_^pjEX)f#NaB)rg|kl9{8?OiVl`Qrskp zaF%VTzM}(u1JU64MD&I6aBx`G^;OOx1Nbo(5;_k1zDk5HcydHEj z{#UgcxpV-UP!ur@83Ok~HK}XMJGb3(Zd+(wbPndNgL4PIG~4e~H{5YI<=xwI?rlr< zEh}2qYAO)cXet)OGcYX(<2=EhfCq-F@Pj92EI$G?;L z72_Y^-u1hI1btlx&9n=$)v!&ifi12{f$dvBl+-Z^F;H2TRG%ru0*p3L%wd*i@b*q3 zMIP*qz90j1iu3iO&aikb^^3Z!%jq}Xf^{3rbe^xrkF-!uU1ZpY%Y*%R32uW%Y6h&gKc#OW&%UUTYFzr~fPU z!fmKtG~cOuVM1u1)+Juc>vl6K?JCu3TQ>x%fU<$G_K^;OinAY=&9pxI6#ORrT6(_( zu#%bHKz#-2Rv1bm#Ls+Ng94+Dna6W@hQ(M2_iF4}y{x%o0( zbnePqcYT+-$VBW-d0R)$*0GS0Y#owq@7&lbxL-FfI*0StVHNO=q~_@r52+ae#nlQD zp7RWD2E{el3X1DlAa6D>gYDeSO?sr;8OVK%qQ%xIuJVQGdGZVKe{FA9K_1opx&)Aa zMK(_)yl2Bt<>kz!v1WtcXt4m>unq^%GTfsI|Q z{ecOlFxkkaLhA;uAhd4e0+Nk%G|%kTfeX6U8ncsVlavIuoyGeGC08o7Sb{EQ6^rd| zA(LfL>PgH;NQ#?;x2s~Bbf{DaU6OT)*H6}~O<_)b!>K0QHM{|xSzeRk{M-~XMfS1H zWQtKBY|P?I5_kt6KwR{xbQOZA>+qFgB@D4PfU_3@FdTVRy5^PUrFoyO7zm+OmW}bF z$(cknHZ92JG!>=`OXc=BW9{VxF1EdEq!wr;;-IJRX z2X{wbUvxA$F%k;;UySl2p~EAg=tw9u9+FuxL&4!0MlR*hPu4-KpPk9bjIiF%sa1uk zT+f%_UlG6GL00s1Y+BPDmoM+?zvb#*veqs+yuTQKdwi*`F<-YOSGQ%!-JExK=G>i2 zo|a2p7rV;!6^q_&`a99vOy_kEYDi7TlDldC2RV25lFdEudb_t&tmwHK@QOL3X{8p% z{^Nm%R5|Yx4rVR6&--%jeM`>%54SIz_+aNkhh%@I;vE08z{1FXiO+zz=a|7Z=12Z& ze>b^dWBi@m4Z92Jt=N8}lR>)MH0Wh->}nruU~e{PfxhWwq1V?f>oTX($<#Dufs?GC zia}_SPEx#?6!Bj<28uUOt`kqp#AYC6I-EJY#K^GXF3W5>n^D{oI*4QKrBN81MTf=#zrhKL z#(*N^-Xr%RC&g&Xuow0K*7z(Hpbg^_5u=a-%P`C`aeYOG|4fFLN$)bLUnVWfq;Hvc zzapbKGP+E9mdUeUkr%%<+J4$Frz_})#_*=+tmpjTeCG0ji$9$6NKDVyHO>pMdH>th zw`=Pzi1Q~d^SN5zZBO%M?w6gn>%CIT(~I@HZ@Zf2PyYPOirK={FPSU_7RtNk>Vg(Z zVC!%f^hg7}YoS6;!ncfyN=r)BL7`dY@ZRO=|P zP~NrG6|_*o48RS0klU_;2HQH2Tf^Cg^P$Uzg{l0`gSnjt=Ncp?xDit$GHoufP%2EJ zEHMQNnT|6B4K}(TmeKH#j7DckMkwzBTP>8p4%V(m%7D`1n3A;E)`xr>&o)Zd<|~Ku z-TQOh`{x=Z=DgvG`#bqgjXpC8vgxDh)yV_LGb7g#72 Uc2Jhs0fp>_m=z6>Gy&N9H>%6we*gdg literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..3435eff057416e418f7ca1bb506c79f7e64d175a GIT binary patch literal 7023 zcmeHL>u(!X7Qf>eKVmz6<>BBYt%hl)D`TeJ;7e;_L3OCi|kkDMEhcWkw>)&Hu7jkjEgz+P!ToH=wiYy z60`2-YVE9K)=E>ls3qo!T4T0oXUsHZh}t~lDd8!uK0^OCBiLh(dywt8MYgj=_5jG9 zZOmHZqOO=DW{Avb5jST@=ej+7WqRU ze@T7W%LpSdLZ~5G<6s4b$Pum7$fNytJ^x$JXrN`h z-Ny%gJH9}HK28yiq@}!1P&yW#JRHdu@*-7?0Wl|LQj*g7#Paf!OV1|7Tt1!6Cx!kRU9oD@!0{DbYAwk(HjyBb&cb(d5aqg_b4k>HLhdh9Goc;a46%G%FInn7khF&krDH;u=va) zImSMc$faA0nMUhcBKb7HFqX*W;7i9&?TxXa#&f5Y4xAe+(FbARPWYr3fqX%Vr-3*r+qsreS1rNd#`ov-qQ1SbCvKN=BkO992KLx zWOSdOdt?50^JU}1w{{+DbpFyzx&|t)v8%4J3;wceu40`lE?u)YibuBkiDP=Jk8~dV zO4K7`=72tDo_HP?foN8YD%T#Rf$soHSL+zv z#y$+U!|S#-15g!dgI7R(9jUO3YPuup+u&J4{R+>J`vM^MfQnpHnA?$ChivJr7r^?V z_i!NmwQU(rr-4xFhF_@%h|f%ikRL!&ha4TmVm}gwlpV|Lt8tEbU@#&}&rcS|P6HUi6?RESo_o3qv0pzu$Z8fdcJE3`GX|?W?+WDU*@6^T*fu6R} z-nyQ)8>5Y0YkIm`*Wn17)|Q0cDT2z^lC+R^+m&mc>ui(fLM4>{0G{hz=A)S3`T&aW zfFt`=lkX~>4bxue+obi@nsPI(XByt3`nM`PgNR~CszDA5QR1n>$sBl+Jt(+=1l$>l zaA-w>rS>h+C9Kueo0=do9SH=#N#txNx<}3F3Z`RsR#caI&KNMy)&-fvat6it3|=87^aJifd7y zTM}SvYQ?Z$jg4=MY&8V^6%cd+J~Q(o#sZpp`E~hi2=GxS8>L(=m4*@XhyFDEO@0wD|n@aoly9g=N4_k$AS@gD~HsE^trA^C^nJIp3JR_ zd2t!SVUv$Y zyL=g_dL?Uuq*s0qZeZ`>HSHyg@#Oaby_ezp0A1e%E3|ED#j?+G|HxIGDi~Fj!j}U> z4Zn}U#G9O99lsK~*BWGNi0#zWvE~o)4ocyZ-U9NiVHR#g=pgr8b?&(kx#BB30~Jd^ z1L#m4pf+M%;_3+HFm9Y>2<2GZcn}flSme0PDb7DHZ0%N1UJ3U)v-k(mM9v7d@k0Ari zniXZiKPrx5pzH;fU8@yd%2W2b!!E&!kjqMW#lar6_D$}MFGiLYmX`wTQlRj;LY{>% ziawXfCr>ECS~j~*nSq=|$zAGy_!t&nJQ`kJ3NKUCkBj6cP@>+u=U_$f=6Z-8g*vb) zL>h%B&nnMx+;!sqoE$8ZgV)K#bux6FOkOA6&&f=Q%zRE3{@LMrslRBb8i>yHqG!V+ zTOYiXx-#|lQ$>%=Eo>QxXGk8JEjHTsrnqCyRBD;baFk24vgtr9g2&=4RjrcmF33cyHay4!0^A@*DQ9svdGxG;%f3 zz@g{^RUOt%q3FSl!E-;m&|C2>mVArFL75A*+l5|LIOJ?=Ay;<+I25_WZRvoeVbGWV E02P#}vj6}9 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..4dd40869302ae9d5496360b8c0722bad47647f71 GIT binary patch literal 5674 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 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..b4e0c7e06a03b01d65ee328c9d06044ac9171568 GIT binary patch literal 4415 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 d&Nb*2s;n{R%tiD2bBnhM5le*KLPng@*n^J literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..7226b020d5da965dfd139b09d923f15d53a92565 GIT binary patch literal 452 zcmZ8eyH3ME5Zv>dKoAu4DRGg|P@#w>sV-6km~>Fm7q-S)pU_5vq#lv zqiD8@%h}KDHL}ptHkxRMz$Neqe1ZUB9JWk5E{a~F7t0x3P_DEdJc0#KzJ1 zQpQ;(zoEY4LW#_F+KtZ6qc(*H7Vx;Jq$Q~6Zj yQi8S>Ql@!YN!crwCg?xR={?T%0cPT#KzW4lX*0%FaJ+(3#4pF+wVr&vkDYH_$asqY literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..67745fa95f3abe32287a54105415bb6b1923aa72 GIT binary patch literal 4562 zcmdT|U2Idy6`t$+<7>x>?KsXKe&_tSQVOm+DE&Vn(P&5sVY_C%_vz_NPXxz@`sn)A#Ch|O!K zb{7d5I!HhY*#pKy2HMz4z>?cZz!c&_jUueRpD+9t>Xz<+EHtNP7DhY+EQQdfE zW?K1igz5q+x_oLnr6v=RxGs#UT1pp&)o4oRJ&74Nr&~PQOd=XkG!0zbye?@N$ZekTK2JPZlGM$J;3%{@+Ek$GFF(@}k zh)^y-s3E{nK41t5ArU`nz!2cu$$5cF0U=}zh#?uaz*Ov$0!G$n-bwIZz`=Y>p}K$> z{_4Qb5|Tsp0|uN4|6puGajZFD!LjE#YGtG9D}BLF9FPJHY<3&#w}!;Pt3GnT#(eA* zzpfER+F7e3&`6smWOtJ;5BY<`xHZoZO1e0OI}|m5UMi?#05@zPZjiIKc&Ud>5I5($ z%TXt^xDC1hTRzSV4F|bgdU$9s6x0-|g=WUpxEdN(vu+Z1s*sq8F4zEEJiZ4n=7?78-+J+&?{|%i*w^P*dTsZZCaEf2pYseuHKN@gZ4v zw*S(+0V>fAu`%7C#&n4)sWeSQi`c|If;saM{B8UNL?>~<=LR`H2S!ynR~{84exa%p z%>BhNeq6q))E?o7{H-oQ!{9qxbCu>i0hv4r>tEt-@IKK(5`2*NgRl>J3!C3`jdsSC_|*^e`S%sj|mb!8r99=c8p``nUlRIVt| zbV{K(JBzC>UY=B_LU%%g-l#<*@dynk6G}Kq!wIPG3bYk{cc5TSu+3UJp3-oWTu^8m z4&^75lx`_U46Fud)lTlePBbta~%^-se1N{1Nv;YlI1}dKx^hajQ1Y z(=DvpouK;wsTb5~U5u+!YDzZ(G~pw)C?;a5VBi=OmLZe{D4Z(;0YX@rA;mGJ042nr z&{J%Syh}(>@K?@U@-Eg6@{X5~G|V?Wajp!P+A9R5{l#@l^T)tG*#T>aep7M6it1b$ z7XN9!ps^Ba3GpO^qK>$5-uj9Oi)zqN`c}WSMlWCLg`MF1_8J~y$>S9;%R$-icy&Yx z%zmVrs#5A>K<_95y&s%j0ebeQfbJEL4>J#5LOnG6-sgtH4n`G$uBMbJO*c+Pv`8vN zDeN)PjQ~`%bSXJLt|=+%M*rQctB?$u&PU>Lx2YlxFjNJ{z33=jOe=Io=PxKTx_BuP z2Md!@!|-8(uu{kp6D${=g6vWC#>!kNwBaskOCT^~Hf_Y-GM~b%$=Nz)#edW_uJ7!= zJ+(M>D|y{K&p&pwFAUrsTpV1|)*QV#NALRf-M2>;M}B8q7QQgwGp`KgdVcWdP>E_N%-omPS9a5$Ib(ZzeL2C zFD&~Wf>I=6;s?FDz*WQW1_>I5xdR*!A?Gg>^Ok3@j7PvT_kFoojYj5Q&dFLc))>Jv z9PR?rl^GWK^fnlo`4wR7i_9M~%db$b?=Eo*1=R787@SPeC6%MY<21XdejO2t>mu=rA@N0pXS^0D;>}87jnaRf)&w05oX0#}!mUEnrsw zqi|bBj?|(c5E%IevZM3%=;G)t-`wcz@yFKY`AcioZb;-i-MPJoAKO|Mq^0yTW{)CL;S)^K=SrCKVkCX_@n9Hz(?6rVY?9R+(4@fw`|2tT?9gwCt5 zQ!<)(U{gFCDDnk8ih`w?FqTZl3tQ(5hc!rEH5$eYR>$Bnt-(5n&==^5uydZ`NzMc= zs67YqbCNf3;+Is5roSp|(>HJ8@E|mL05GY5FHxh26l7@WG>0O3h5Gi3y5_ITcW_$gn7|9WMt! zZ`LlxBk|~@GBwk$TuJpu@c#$YWFdCutCxNphu8X3-#;V0zvZ%JR4^gSW3Jt4dQ hW^v4qEX`ysZ+>Xnln!#8vzO;*vew<-5zyHV{2O?N;ROHy literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..d5b2f8c9368a4546fa71ee44f90345e963fe9be3 GIT binary patch literal 3476 zcmc&$U2NOd6~2^6iKa-&mLgaAtzsvwWH0KvHC>iu?PBMllLxgBp{_s(5VS*70 zS3F^^G^?_1n$QAz#MJA0)j~@T8O?f2tAWneG)o7`%hg4_wp`a?zPOKPsSegaueAN% zv*pUk8O_wIz5VoRv9D~t3*ZV-2xVkKLo!3d`^Y{b$K{a1%3+0*StTNK@I{oU!sCy= zAjr{O}Uk=DY3saq6J)#Y2X2CSQ3p?Kloa=KY{qh?jBYt(eZTD_i+03r4I0v&}8 z-n2A{$QusqG?(j^iOXlb;#OymDivU|sjMs*bwfF+n@d)!t-My(n!2Tw^s|TB9z3MA zjjd`ku+D4MCB0cww02vm(&d_B_MlSQUMVE0i!~RqlvY^wOYfwET@00E* z$?UrN&ZT$$EhaA?>4UMKPN{luh`nCv7D+Wf&sV_^P|i6?k|=K0wS^Tp4Z*>U!Z7bXF_lK+n?2D9qG zXQB7N=cj%IpC9rkFEhb@hDs&u#f4C>sXT}QL6=hr9}mrheA-fcuiGl0@Ito2mbZxt z|Kn*p`kn?c>-%_`eJcwNcOz@x0XMsA-vM8|1+I1%-1CoF`zHFGbD@+MC`OdP-{@1Q zqPKY-L^Fu+vM5FwH`#L~wbj(s7FC-d^BjE|?SVfXKs5`MiBaBjBf1~Zfab`C?P-pd zeK>LnDv##z@1*%n{!{4_>GQqLPfH!?)omER8D){ktVd)4ht)& z&)^eBXHv|)RR>82wltt^bPow{5s`BT2f|B7%c)K*VEhT>m zC-XgmKTy&+mxZ{0!{grvApdFKF6BqI_bmxkT`;I=)s3d!Y^f?m zKXb#TMcuH`v?wyx%bs)s5vD?l=R=>xY8omxt*WM_Sw>aWEQ=cRkaSI$=n&X8;UnHL zQhe)p6+Vv4KSA|-(iKR0{Ht{4QEZfZ=7E^$av-}Al1z7_h4zHcPd4v5^eHxOihAR?Y*_H;)O2}DS)<(!e-k7KCriE`7|-|Z3*w^N?@Jo9DF zIUz%G;-=|~{w7QL9d5*0X&cScy(7SXcE`;(>slR>ZDXaNzikyXe6Jg=-kAx3(Tjm@ zJZLDiXruSi;4v&&MnmttDpHWc3ve}h-7NSSuJ>5kffj6PXhSBU=vVWaCw@&u1lV{h-&UKR8 mATO_ziN}!~Gre}?+AB`#;9~;#(d!HmGuQY|Z2vjloBY3b>JE_r literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..815cd0e50d934c8b71726f5cdac5c5cb32103cbb GIT binary patch literal 2221 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 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..673bbc0a06554af9620d02b85e073a49de139a16 GIT binary patch literal 1307 zcmb7D&2QX96d$j>w%7S=Xq%-RSVcv`Ld}Vl2tqle5eKJ4s1BzZjb`mhu;R71&vx7G zX%P|<5>la6R0Necb1SHbidOJ1cvTLYK?o{Ny%BAD=Z(E-XvG2E;m!M+H^2GKoAJzy zMNt0u(FyO=2>DYwhf<#y<1IAyh)Y~$gE$H(Eos*_YK{u3qk-nsq3-CQmvME&0K-$3 zNPDs!%qCePu6ByJb6xN3#O)mJny z%UA=^sjji2c-Hxo|7=>>M>lcnuDPPZ^#9xSAG$UW%ZzKm?9P-uEgEY`z&lC6qemt} z$lpL!d|uoxekgt_zAJ7IueFN%Xx=HlFYXOLZ4Ezcq4(|Zlj1JM@3xAc(Y-gkCY`Nk zSkkbQizI`RE5DyPCw@u8CQ^#w8APQU`KGY!#Zg2s4TEUV!siMnN9B zY0n9h(wKEQrNW}Ln*@0z?P*Fc<}8|I<|y3`Agy93;IV+g+cc7!a538 z96Y^x$p*~GB2B)2b&qH7h7(fpz6!5mp&Z-v6;ywzilY2RUi+Q2ACUI1Wa^=@_`rB^ Rpgq=)EBa^J6M{<#?r+hvQqBMX literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..94cd42367fca4a7a7273f33d24b5b1944f4cdaf8 GIT binary patch literal 1261 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 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..5a47b527dea382d7c91db88e59e911c459b31cb3 GIT binary patch literal 2070 zcmah~&2Jk;6rc5eCb8?raT+J7it|BRlO}E5G$mDQDPRliG*0oxhZ0Mx&3ck7an|na zx@~$u2qcsv94anIM1lhdq?TKSI8e2JK++sshE!02kaA0vBE*e1Yi}J&3nR~)_c8Cy zZ^rMv-3^bNEiNxkwvyHe>PM>7gH*X7p62VJN!x-LQ?{89$CC2Wo_E;i?P#uNzeh-qfOos6n+Mat%8R`J`(L!=ygY~$l!YY9eg<pkJ@N_T$`Dm)}|)1m$Y2!t$a$I zQ7I3V3B(~Wg$gz<%@aR!X)*LtNwe@Z2Uz!P&8#pjE8Qi$LiZb0LI9H1s4|<1M!5=T z6oTza*|M?CU`88*F28=ZkcXPL3oG+x$t)zXz2uZDg^MNK!cHNJuMSsSc37{N&x%&l zI;R^;*eVwEN~N&;w8a#fe+4EZl@+QKO}nBy#v(oVoCY!CSz7?2y#r($y@$4fUA5pV z@cXg5f9=d>_fV~4Xx%@wBcWrbZYFLfK6>Mm?8n(!_{jb6k=rY)Enw*CUyH5vu7`(L zTb@X$|9Gu0e!nk%Ykafse69EVx)S-lt#>QjwH`UT8IG-{9t6XmDz(ViMr3R=IJR|Q zU@LmK7M<9LPCV#6@mS=$LOY0W4?R&(N3<3ixE~r=OMheEI(_@(x8q;G`@`HuC|&cX zH~i_}LN9stFYVj$jZmWIPptbBkDAC=l?TDD)!^gfD17X32pvoS31qlOu&HC{FZ&W) z`u)CS7xy`r3M+V0X0mv%Dx70SkBs%V;}FJn!kt(vx6E>=s7_iNhas$ObXf|@pO65A=67PiWo zMp&~Zhk?*eO=HDl8k+7n#GI=-*oFbrG4*F4POPhiMz1 zF?-}6U$uIP3XZvq>j)X@IuwSQD(C9&kszZWvVLF>0@>j?j{6zKH&FZ`di5b1e27MW TLTyi^9xk%pbL<$k)2X?3b=7C`{sb?|$vDVdxq@&sZK!w7_s!_eYZ zOUG7ZhYoiPx1(CDC+jTd=J z11SBte@By{;m#!y1C?_x=!oz{v8AJvZk|0*E=bApEO5E4260D2O@ph!)8H%U1&eZ- z6h-GgPiQJSL!~q8kn3|LF_krA{xp@!gqbT>=k9Z3$w+TBNbXMx5yEM@4Jib0td=qx1}Em4n-+J&KQQn3GFHmhEf{(xo)Qu^p;MT9ZS ySc!3`7)$>^CDl_N@-?NZz88p11)nyA@D=P-V7mgX3T#zi@5}KT)}zN)RQ(&`?3AYf literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..fb6434c697ce5bfc1446c981470ce0aea48abf21 GIT binary patch literal 1217 zcmZ8hQE%H+6uwRz+i{$v4eh89h_Oiw1B-ZINCgCxq%CvQZrbgJhAdq<$z5jEvE5?_ zRvsV{63<0wQhD1G3jbi@7w|YgL9a9c;;C<-!aL{MskZe>zCP!C=bU@acaMEiubTwd zA3r<(YMGF~q;k3{bK&F$3ik;mROt~%0mUgn$tgqGQ9*SoP;oTS&P%-1(;WkhTrT&j zjtS;@vO+Eps=h#I#WkdNM;7MVqT50ri`Hoaqn@KpSQ;(Zi=wf1wG)M(b4c#idaMie3mJmniZc1alFBnZ5Iz(vJJ`#rl1i!zxu3H`kZhZZWf zlG~1l5>RhqPEmj6Ak5n6dxKpTNAUz%=gCiG+g=t1W1%U8VR#?ry9A3mFz4{v8LZ9cm3=_5AC8pG-4(YY57Z_W6_ z?k{R~Zfkn&2pxAGtY?ka5o<0V3?JOgnr}=$IclvOK0kXqYrQq?9a*jK-Z{MZ{d=>e z%xX{9iIzmko| W&AEQ9O_LWQZKw!3ZF3|(cjS}K7{W^#9WX(q{@ zByC4u1_bfZQVQd{595=si+@GuN#{aQ@oC?btDBC*d=OwT94ci1Ww@dws zZGm;3Y>*4Y(OxA^*|jc}ikwg#=^f)lf{rfq?I_5`q0pTacsLTqZkVzW17Tf{fbmh- zXA_|vum`Cyu0~P7ys)E)8nD1ic@!phc#ODm)l1mT$Y;T@*rZs^GjRGn8jp!fKye7D zjshh|1`DY77E^;D?jjD>L$RbRwaU&Iwm zEobWZR?VsRO3=vh3S!-9AYOHwn0>`jomI@!a++{%)aslQ`aZkwfq$aouEKyEBwv_W z!XW8#Ul`k0ob4++*HE48Bz6FG6WvW_KFH0 zdm~0O2tbacScxMZrU?ahlyP7_$QBEWCv+Hie2k8YbZ9cMXj7V`I3`2tr8r%K47E@S z8yInlHxa|_%dV81xRXO3aCe6#che|#KMA~$rS2ZPzZK`^mKXE?!|)|5%f&+9_2SsY z%CI1Di^g^13Dj_>e36oqd$@c}ep%a`-u%6>_U&iieLlC2Z!b1)JlVhXgbo)Ce|lqC zYdw5-_Qs?4=Iur8?di2;Yh$)H*A}gF#pkqmE{O&;hMhcm-w8cIb(GuqS#hiQqZy}W9mu%wlXGu|% cU&-#zWcMk#_>{c2E3>vU z<5k&kSqTaCScEF2>ZQkU>k;u+WW|MyQ~}~bZlJ&!-q@QKVad<$&G+Wb`#!%pX*7HU z&o4jp;wL6Tzv{9ypH>M%d`1o*|5$Da@WFte!3GWxa0pD?LXzg>UuUo+rFz zw1h4oY`=nVCGb|QvX-cBIc@h?2W?w9>nR@%6XoDs#L1SjyEJFYzn%&fZzX*;ZX2pD z7^iuhCUQH@Ag+EyCA*nMjE7~((t5MtWFMSIC_uu%NSN3V7B+<)R4$;v30&yN!Zxm~ znb^TD_SS6Sl^7t^Rimr|n7?LWWY%6}x!k@WWjVWk zt8FST8F5YroT*9->t7uI12x))n1fIJJ4meTPoW6xYYu3*L$Wj*fp|7*ip3YIvl+jB!ILmDyYLobuT_&c=Oo>v|r2^}&*luyVo z)qKFO6S6y^e1^;saxWG#=W)W46yOFSxo*D1g`NmuYf~uUYWf7&SMoULOz7cLcBBWQ z7BLx$IMY)g++tlPLnbsV)gmD>hY<-0&0&rPBOpwOSc1e8c#&f39|T$#8I146JPx`{ z?&N6}e9URW@?ewQU&#u0g=X>p!{jBZHDyT@&@2mpG~+Tj6||F$g}z9I(R^eA=41#I*Ke>HK!f7*_+&HSYzPYsj#l zT|9`Uwf868qt?>nb5HFjuRgP-F%6|KOdI5)___k8gvG5$ArF8B`GasS^X{Wl=orz s%dd)eAk=q8o(J=XWf;cK=<<)~@^kd|bM*ROj&JN555|8Z{VfXo3%UnFc>n+a literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..2484596243b18041d032dabe418239c424142d09 GIT binary patch literal 1292 zcmZ8h&5zqu5Px=J$4Q(`Hchsre6>Xg1!;poYEb|c_M=rdQ5VG99zd3!ocL{O#j)M7 z!!~e_+jpCULUlu)HbnhGdQ71U-5Qq44^n;K|M9rP=bS6i8;0Y-vT zt!y&~xhv!nxkhOEGNGE4yN)^JfqYl5Wo8oAbfIqq-k|RboyOq$U6I-HW8UQ;GV4L$ zaoZQU+W~O5>$mt&q<8qkxTXjbxM#<1;79k}5cTZ39r3$?!@Z7-yEw)fIQ<#HA+ZQ3 zlz>VVNKqBimUfL;x|P8iQ#4JrhDvpsp++MO#+*YYdtI4FK`z%&A)7Ec^pjft+%JFb zH)qU*Dd1ZsEi_WFl;}m&b-ILl>6|Yn{PKCE(sPl@)&;C%nX0sm87uSxRJ)a06`Ns4 zy_t^H2`xq#eQ8FW``j6LJgU2n$ZV|9jkV2N*dHVCu{S*Cw|8o)F#Lh%*=>&t%|-je z*}oX0rob{j+^2Zm*(=hZCI*pl_^v(hV$`c>PK=-;nmH(hLC9H^f2RI!b z{Xn*BE5cyRxBHwikz=eM$np@Ij6E3G-WgM5Y}bV-_FSL)0n!D=Vp-vw2e~?smLel_ z<`?&5cug&KV~>NJwa7a>>VO-{)eu>?Z+AHxfCqA&MadaJvNWvk`U9*FlHO%IK|hqe z!B7D>xOzqhtM3LdgsgneSY#7b#-bQQbeJ9Ey0&Ey#^43?I>jFm_QreGy@*3(4R>A7 zwKjRwi-XYm#It=KTibkZHB8{D9lFn}{xeqgk^7EihoOZn<6dOR3D?6Rn3yLKviRr_ z#W&>F%8R4Bf0QqcSH8bI+5YLX>D7;qKWE3?-n8tES|?_C|Hk;WgZC%ZsrlCE)(JXR zCh2K;6}i&N{ukrU!B>-=Y3ZHO*2%?}$K50CF-$M6AEzrwKiZpUkF{y(CX#0P(YxQ> zJ6fBXH!w`Gy1zT72ffMWwD|Vu&fhvIy)7%Q6rT0|c>VAE0-;E0L4Z|aiK;;a5K^!cVuz%aH%0s`T5aq}vg&$w^Jcec z%EhP>>akH&5yYj(a_h15LeHGyTQaBu#3?sW!WrJIME!)FVAbB;Xh?QS=T`y zC(n}$#8AhGp_wUDYxF(#Bj7%%^aM!9wn?# zm!ps}w92FI5I@50$~&e=ikX`$j_a6J%C3igU|w}?kA~(V-IxescES#v|BBwJcG+%T zr(VmngTTaGsmsg=-Ijw*NMW3qh?>~|lCQ~LcBnJ6mmBHK?iF6RJqN>mn=|bd2gEx3 z3CaK4YpNHBsUaTZ$>WPK6ayP>Xj2L#pP^Na63G+nQn~6vCa@fpOPW_ z3{OhzDQD&}ddf%}86%69g;>s=$i-OBpU4A70R~r#r2(#po*%?lq>4VVgTFEG(yYK_ zjR<+>NSuD$G1t~y?e-YiLQ4sA+_c;m?yU9lrK4Xo#n(dVmJTETD3j82KU{l7EO`A3C7Uf!lZrIS``RQ84_ikV+G4NxEES83#fH9#c zh`2czM8b2H6^hJyAOta5Af}G1v~4>sFRa-NbFu=Pu?-(upbCo^2Lhj50UQCITEPNi zh=Ukoo?^#^V0I8E#dxmyubdbR2|oh7J;00z?zuh@-DF=OL3jeT+!$iPcGpFPrc=ge;Li%xAnKeqGs!`a>HC*Ay~oe%ei$9K=a z`Q+8z#!7d1_4Yz9JCRr^%hPP#wOuT&y?NTHxFbA&sw(@??zKUo_y+L|4pOi6moTgt2X-0BAF?D#zmSVva`7p7?PrpCO3oi?vNU#w a-K~C8+o~NA6ppePX-&E_^%oI)oc%vA=znJb literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..05feed426b966031206ba562a7d491557c5ded57 GIT binary patch literal 982 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 BP6+@2 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..90c911613e69a31c0a46573aa2e0f73fdbebc529 GIT binary patch literal 2260 zcmaJ?QEwYX5Z*iAozG`GP9ROwIB86S0kp8SSnBOYO9&vs(4x{|+}ot>H8o&9Fq zNvAae-qUF(bSmn&e?m{_8u%xT6xb%YZHlJL zN+Hd(ubsOVwejR_1soRJ{{S8eOsiP;OwaMl;cX^|Zs(gu7?{-As=L&&4@qH+six^$6~{E0W}20%UH4EsI%q!$1|9ejX0NUow*rR-#`dP`xyCgoxD!@u##f%@JE5`e+`U-i;zg_G z{&(shuWneSJC1J~R;^|PrQ1%$3Jl8gx>(z$Ds068^Ba5u@Q}Qim}&%1f}@EGJD=^o z-;^%2-pKE)HKz9$_U4*WzBRwFb7S}3e(cdtO=;mpHg_;_uyvGO+PT@#pG!-0t{-xU zN%#ynI(WljCg~!T%CUmPQqg;_QU|!$#;o#utRKqs6i%iPP9sbs%pzd8Xv?!G<@$i$ z9ZdWK!X!1az{R0M4e0#~tPCG&6umj2)gH-33KTcuJ)OddD^l%*juXFEB&wd^Bv*`7 z&qM2Zq`_mXr|Z){Qx<{#y>#5FVQID};E3xKI}%MI@bqwcab}H!t{~9YaEY@_a|5&F zSy0h7Pf}rgWD*Aij#zpI{bvx4Lt{9aMZhC7X`@>8MkYUxHVAmu;9CG7Q#SWx^6A1+ zb{WX@L1XpNM@?z@m4wQlKe+Vt)1&+{5bC@A(%ug}hhjtBpWGXJF6E=w#Epht6R(1! z^CQ6jU(=9v5iej!AjNq0B?>PHGv2lg6(s(ST;i{H+=DNR;0l96yP{e-SxEKU(+&UH z)i&mhiLTA!b*Nd>wXa9X(n_4nHdHy&>ii{99y<4+G?3N9=f={|V^l6n1({7m<$?Px zu2%g`x7^Nw$2U=t6qHf#%QBm^S~<~UMm-!;qHuHx!ePiD4)B1qX3qYciIRN@6uo_t zqxPZ4#KFwccM!0rQ0_UZRL|oo0=fq80z4!wHF^K@R(kyY7p>E?JH>|7lxADw(@kkQ z!oMX!p6?QX=ve4JI+w3#GfI@l_M6}w-HD#-i&0qKN|sTF!0i@r##OTQITRL_jkH!4ODlC| zO>5}EU`T9wQ4fJ0bIqmn-2WmNf;v!K=%MIVkV=p3d$W=(rJ@V|>CKxrZ{Ejmp1av> zioo~V&!zAWm5|?YG5GYp(ESmF=fok7vPnt`Q%WjR7jdm_Y9-2ONoTrTYnw*NWM;`= zhFsH4t7J2Kk>toF;^_0lF8w)S95R+|*E;mRcLMsS(?Z)TTk38L`buZ5Fgs zZg%Klsybbm>EI;=RoHiZ9^7kGf|}4j4TD+*bk_Z595y1qCg@hkW6;ow9|yuhjKg|R zPy~JG^WAb1X@bLYY{B|DaS2l#!c<3L+6r+gB&a%?LvN`}cMaEc^ebTJS|AxHIVQ8+ zlxv_H&{5vjWWjaLhzYWzg#aTwPEhWpzh zT?u%Zg))_wq>vGo=S6-!@H~<7ym|xOft>NYulD>}e`nhBc0$JES{MaU!}AygUu*_I zXgp>D_WdYo#6A{?!#>`{W)U!Oao+PdZk9bij#>D4FAmV^E!gYA9}zq2x7|lPVBFo` z32ULd5%Ar((R3fw{3wXs?cnRxrW9BGX87hZI@^8hmv@7x;`+^|%b_@RpUYp&s@U9T zX}C-R2FNc1JR`r%UTE}@=qLpUSTq|z*+2?E~CuLD3!^NTO$ zep-H&zX>hr5k0^q-ebah9?Vz?9} zO-cqxbSTNkET@eD)5ctbS&1Kmhs><1J^F+{k2dahFlV8L6=CkdWAH#ol_hH`@Nh(G zPnH@?KUlC`u3wd^dx zQ5dl>_xb;(_W{^31Hnd+%$}6qHQYr&#~f!Yq?elqBHw7yzJCm>~7|J%B$oMNv-4$|+eoCCk5(rJkWFms_`b1b%uMMX_5hbV9Lv7V5w3>rG{$ Vb*D$*r#Gi4`J-?D0-L-{@L%4GyIlYP literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..9df279db24ecfb1650c47b7dbc5b32df292c0caf GIT binary patch literal 2532 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 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..6decf264ab9168906c247109f9cbfdbf5885cc16 GIT binary patch literal 943 zcmZWnO>fgc5M4VTPU5emEl54vNQ4`FX_dJW*U{eR2n)f}Ij$uqE zFsZrW?a*D=rF*bbO2SB(b7cO8V9^eFcoE%I zt%anj>=xw;c&r4Dzey;`I8I{xh?jSpxJ%3|Fr!3PLtr+GI|cSUzfL0-M_B|MJBW#Y zn_F&EIIPPPhQnkf3)2K&!k)jKOTMV-)B(H>0$m9`34IBMgn@*i1bKI0O0Xo@5*!Jx zgfYU&^r3jf^L$opY$|5=9aKHUenZr7QuP-H4OPofHJvzY=-RHT;ajuacUGNCJZ|jv zzr*U_tpQseD_exY7*A8izLPb&L`1xJ7M!6+MR4;mNt57pR9u#;Jb0h-EGmPO=<{)2 zhsQim+B8$u4?Mh#vhx5Z4z`vDj3rr8GB(R^#NheWO8y@&-~jt-_!LhN{&X}=tH{fW YysF5Xig+Yf< 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 G>F7VB;n(Z{ literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..6f2ae652f15e7940a5b95994c4813456a00d2dea GIT binary patch literal 3474 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 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..3722fa344c559bcae9fe1b4aeeed766eced40bf6 GIT binary patch literal 4163 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 literal 0 HcmV?d00001 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...