From 01be71bbd96874e43011dc41441f0458525b32d7 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Thu, 11 Sep 2025 13:30:28 +0000 Subject: [PATCH] run delete --- Html/runs/run_20250906-141209_g777ho/.config | 7 - .../run_20250906-141209_g777ho/agentscope.db | Bin 16384 -> 0 bytes .../run_20250906-141209_g777ho/code/app.py | 20 - .../code/app_back.py | 480 ------------------ .../code/backboardManager.py | 80 --- .../code/bootstrap.py | 31 -- .../run_20250906-141209_g777ho/code/wsgi.py | 6 - .../run_20250906-141209_g777ho/logging.chat | 0 .../run_20250906-141209_g777ho/logging.log | 1 - Html/runs/run_20250906-141216_d08zym/.config | 7 - .../run_20250906-141216_d08zym/agentscope.db | Bin 16384 -> 0 bytes .../run_20250906-141216_d08zym/code/app.py | 20 - .../code/app_back.py | 480 ------------------ .../code/backboardManager.py | 80 --- .../code/bootstrap.py | 31 -- .../run_20250906-141216_d08zym/code/wsgi.py | 6 - .../run_20250906-141216_d08zym/logging.chat | 0 .../run_20250906-141216_d08zym/logging.log | 13 - Html/runs/run_20250906-141430_i7aihi/.config | 7 - .../run_20250906-141430_i7aihi/agentscope.db | Bin 16384 -> 0 bytes .../run_20250906-141430_i7aihi/code/app.py | 20 - .../code/app_back.py | 480 ------------------ .../code/backboardManager.py | 80 --- .../code/bootstrap.py | 31 -- .../run_20250906-141430_i7aihi/code/wsgi.py | 6 - .../run_20250906-141430_i7aihi/logging.chat | 0 .../run_20250906-141430_i7aihi/logging.log | 9 - Html/runs/run_20250906-141607_ym9kvd/.config | 7 - .../run_20250906-141607_ym9kvd/agentscope.db | Bin 16384 -> 0 bytes .../run_20250906-141607_ym9kvd/code/app.py | 20 - .../code/app_back.py | 480 ------------------ .../code/backboardManager.py | 80 --- .../code/bootstrap.py | 31 -- .../run_20250906-141607_ym9kvd/code/wsgi.py | 6 - .../run_20250906-141607_ym9kvd/logging.chat | 0 .../run_20250906-141607_ym9kvd/logging.log | 1 - Html/runs/run_20250908-144720_kkn0r6/.config | 7 - .../run_20250908-144720_kkn0r6/agentscope.db | Bin 16384 -> 0 bytes .../run_20250908-144720_kkn0r6/code/app.py | 20 - .../code/app_back.py | 480 ------------------ .../code/backboardManager.py | 80 --- .../code/bootstrap.py | 31 -- .../run_20250908-144720_kkn0r6/code/wsgi.py | 6 - .../run_20250908-144720_kkn0r6/logging.chat | 0 .../run_20250908-144720_kkn0r6/logging.log | 1 - Html/runs/run_20250908-145013_ycavxx/.config | 7 - .../run_20250908-145013_ycavxx/agentscope.db | Bin 16384 -> 0 bytes .../run_20250908-145013_ycavxx/code/app.py | 20 - .../code/app_back.py | 480 ------------------ .../code/backboardManager.py | 80 --- .../code/bootstrap.py | 31 -- .../run_20250908-145013_ycavxx/code/wsgi.py | 6 - .../run_20250908-145013_ycavxx/logging.chat | 0 .../run_20250908-145013_ycavxx/logging.log | 1 - Html/runs/run_20250911-033735_3vhfbh/.config | 7 - .../run_20250911-033735_3vhfbh/agentscope.db | Bin 16384 -> 0 bytes .../run_20250911-033735_3vhfbh/code/app.py | 21 - .../code/app_back.py | 480 ------------------ .../code/backboardManager.py | 80 --- .../code/bootstrap.py | 31 -- .../run_20250911-033735_3vhfbh/code/wsgi.py | 6 - .../run_20250911-033735_3vhfbh/logging.chat | 0 .../run_20250911-033735_3vhfbh/logging.log | 1 - Html/runs/run_20250911-033739_mqgj3c/.config | 7 - .../run_20250911-033739_mqgj3c/agentscope.db | Bin 16384 -> 0 bytes .../run_20250911-033739_mqgj3c/code/app.py | 21 - .../code/app_back.py | 480 ------------------ .../code/backboardManager.py | 80 --- .../code/bootstrap.py | 31 -- .../run_20250911-033739_mqgj3c/code/wsgi.py | 6 - .../run_20250911-033739_mqgj3c/logging.chat | 0 .../run_20250911-033739_mqgj3c/logging.log | 1 - Html/runs/run_20250911-042255_ebhoff/.config | 7 - .../run_20250911-042255_ebhoff/agentscope.db | Bin 16384 -> 0 bytes .../run_20250911-042255_ebhoff/code/app.py | 21 - .../code/app_back.py | 480 ------------------ .../code/backboardManager.py | 80 --- .../code/bootstrap.py | 31 -- .../run_20250911-042255_ebhoff/code/wsgi.py | 6 - .../run_20250911-042255_ebhoff/logging.chat | 0 .../run_20250911-042255_ebhoff/logging.log | 1 - Html/runs/run_20250911-042303_dshgn3/.config | 7 - .../run_20250911-042303_dshgn3/agentscope.db | Bin 16384 -> 0 bytes .../run_20250911-042303_dshgn3/code/app.py | 21 - .../code/app_back.py | 480 ------------------ .../code/backboardManager.py | 80 --- .../code/bootstrap.py | 31 -- .../run_20250911-042303_dshgn3/code/wsgi.py | 6 - .../run_20250911-042303_dshgn3/logging.chat | 0 .../run_20250911-042303_dshgn3/logging.log | 1 - Html/runs/run_20250911-042540_a7q7yd/.config | 7 - .../run_20250911-042540_a7q7yd/agentscope.db | Bin 16384 -> 0 bytes .../run_20250911-042540_a7q7yd/code/app.py | 21 - .../code/app_back.py | 480 ------------------ .../code/backboardManager.py | 80 --- .../code/bootstrap.py | 31 -- .../run_20250911-042540_a7q7yd/code/wsgi.py | 6 - .../run_20250911-042540_a7q7yd/logging.chat | 0 .../run_20250911-042540_a7q7yd/logging.log | 1 - Html/runs/run_20250911-042825_sfp33j/.config | 7 - .../run_20250911-042825_sfp33j/agentscope.db | Bin 16384 -> 0 bytes .../run_20250911-042825_sfp33j/code/app.py | 21 - .../code/app_back.py | 480 ------------------ .../code/backboardManager.py | 80 --- .../code/bootstrap.py | 31 -- .../run_20250911-042825_sfp33j/code/wsgi.py | 6 - .../run_20250911-042825_sfp33j/logging.chat | 0 .../run_20250911-042825_sfp33j/logging.log | 1 - Html/runs/run_20250911-055537_tio6to/.config | 7 - .../run_20250911-055537_tio6to/agentscope.db | Bin 16384 -> 0 bytes .../run_20250911-055537_tio6to/code/app.py | 21 - .../code/app_back.py | 480 ------------------ .../code/backboardManager.py | 80 --- .../code/bootstrap.py | 31 -- .../run_20250911-055537_tio6to/code/wsgi.py | 6 - .../run_20250911-055537_tio6to/logging.chat | 0 .../run_20250911-055537_tio6to/logging.log | 1 - Html/runs/run_20250911-055544_hp3t1k/.config | 7 - .../run_20250911-055544_hp3t1k/agentscope.db | Bin 16384 -> 0 bytes .../run_20250911-055544_hp3t1k/code/app.py | 21 - .../code/app_back.py | 480 ------------------ .../code/backboardManager.py | 80 --- .../code/bootstrap.py | 31 -- .../run_20250911-055544_hp3t1k/code/wsgi.py | 6 - .../run_20250911-055544_hp3t1k/logging.chat | 0 .../run_20250911-055544_hp3t1k/logging.log | 1 - Html/runs/run_20250911-055810_isow4t/.config | 7 - .../run_20250911-055810_isow4t/agentscope.db | Bin 16384 -> 0 bytes .../run_20250911-055810_isow4t/code/app.py | 21 - .../code/app_back.py | 480 ------------------ .../code/backboardManager.py | 80 --- .../code/bootstrap.py | 31 -- .../run_20250911-055810_isow4t/code/wsgi.py | 6 - .../run_20250911-055810_isow4t/logging.chat | 0 .../run_20250911-055810_isow4t/logging.log | 1 - Html/runs/run_20250911-055837_qf7qys/.config | 7 - .../run_20250911-055837_qf7qys/agentscope.db | Bin 16384 -> 0 bytes .../run_20250911-055837_qf7qys/code/app.py | 21 - .../code/app_back.py | 480 ------------------ .../code/backboardManager.py | 80 --- .../code/bootstrap.py | 31 -- .../run_20250911-055837_qf7qys/code/wsgi.py | 6 - .../run_20250911-055837_qf7qys/logging.chat | 0 .../run_20250911-055837_qf7qys/logging.log | 1 - Html/runs/run_20250911-055913_b9hlng/.config | 7 - .../run_20250911-055913_b9hlng/agentscope.db | Bin 16384 -> 0 bytes .../run_20250911-055913_b9hlng/code/app.py | 21 - .../code/app_back.py | 480 ------------------ .../code/backboardManager.py | 80 --- .../code/bootstrap.py | 31 -- .../run_20250911-055913_b9hlng/code/wsgi.py | 6 - .../run_20250911-055913_b9hlng/logging.chat | 0 .../run_20250911-055913_b9hlng/logging.log | 1 - Html/runs/run_20250911-060203_yfghxt/.config | 7 - .../run_20250911-060203_yfghxt/agentscope.db | Bin 16384 -> 0 bytes .../run_20250911-060203_yfghxt/code/app.py | 21 - .../code/app_back.py | 480 ------------------ .../code/backboardManager.py | 80 --- .../code/bootstrap.py | 31 -- .../run_20250911-060203_yfghxt/code/wsgi.py | 6 - .../run_20250911-060203_yfghxt/logging.chat | 0 .../run_20250911-060203_yfghxt/logging.log | 1 - Html/runs/run_20250911-060207_rce61h/.config | 7 - .../run_20250911-060207_rce61h/agentscope.db | Bin 16384 -> 0 bytes .../run_20250911-060207_rce61h/code/app.py | 21 - .../code/app_back.py | 480 ------------------ .../code/backboardManager.py | 80 --- .../code/bootstrap.py | 31 -- .../run_20250911-060207_rce61h/code/wsgi.py | 6 - .../run_20250911-060207_rce61h/logging.chat | 0 .../run_20250911-060207_rce61h/logging.log | 1 - Html/runs/run_20250911-060246_40ksl2/.config | 7 - .../run_20250911-060246_40ksl2/agentscope.db | Bin 16384 -> 0 bytes .../run_20250911-060246_40ksl2/code/app.py | 21 - .../code/app_back.py | 480 ------------------ .../code/backboardManager.py | 80 --- .../code/bootstrap.py | 31 -- .../run_20250911-060246_40ksl2/code/wsgi.py | 6 - .../run_20250911-060246_40ksl2/logging.chat | 0 .../run_20250911-060246_40ksl2/logging.log | 1 - Html/runs/run_20250911-060318_ec1mwg/.config | 7 - .../run_20250911-060318_ec1mwg/agentscope.db | Bin 16384 -> 0 bytes .../run_20250911-060318_ec1mwg/code/app.py | 21 - .../code/app_back.py | 480 ------------------ .../code/backboardManager.py | 80 --- .../code/bootstrap.py | 31 -- .../run_20250911-060318_ec1mwg/code/wsgi.py | 6 - .../run_20250911-060318_ec1mwg/logging.chat | 0 .../run_20250911-060318_ec1mwg/logging.log | 1 - Html/runs/run_20250911-060514_w6745q/.config | 7 - .../run_20250911-060514_w6745q/agentscope.db | Bin 16384 -> 0 bytes .../run_20250911-060514_w6745q/code/app.py | 21 - .../code/app_back.py | 480 ------------------ .../code/backboardManager.py | 80 --- .../code/bootstrap.py | 31 -- .../run_20250911-060514_w6745q/code/wsgi.py | 6 - .../run_20250911-060514_w6745q/logging.chat | 0 .../run_20250911-060514_w6745q/logging.log | 1 - Html/runs/run_20250911-060518_fd3vqd/.config | 7 - .../run_20250911-060518_fd3vqd/agentscope.db | Bin 16384 -> 0 bytes .../run_20250911-060518_fd3vqd/code/app.py | 21 - .../code/app_back.py | 480 ------------------ .../code/backboardManager.py | 80 --- .../code/bootstrap.py | 31 -- .../run_20250911-060518_fd3vqd/code/wsgi.py | 6 - .../run_20250911-060518_fd3vqd/logging.chat | 0 .../run_20250911-060518_fd3vqd/logging.log | 1 - Html/runs/run_20250911-060940_yzij8b/.config | 7 - .../run_20250911-060940_yzij8b/agentscope.db | Bin 16384 -> 0 bytes .../run_20250911-060940_yzij8b/code/app.py | 21 - .../code/app_back.py | 480 ------------------ .../code/backboardManager.py | 80 --- .../code/bootstrap.py | 31 -- .../run_20250911-060940_yzij8b/code/wsgi.py | 6 - .../run_20250911-060940_yzij8b/logging.chat | 0 .../run_20250911-060940_yzij8b/logging.log | 1 - Html/runs/run_20250911-060944_a5y9ow/.config | 7 - .../run_20250911-060944_a5y9ow/agentscope.db | Bin 16384 -> 0 bytes .../run_20250911-060944_a5y9ow/code/app.py | 21 - .../code/app_back.py | 480 ------------------ .../code/backboardManager.py | 80 --- .../code/bootstrap.py | 31 -- .../run_20250911-060944_a5y9ow/code/wsgi.py | 6 - .../run_20250911-060944_a5y9ow/logging.chat | 0 .../run_20250911-060944_a5y9ow/logging.log | 1 - Html/runs/run_20250911-074447_ax0g50/.config | 7 - .../run_20250911-074447_ax0g50/agentscope.db | Bin 16384 -> 0 bytes .../run_20250911-074447_ax0g50/code/app.py | 21 - .../code/app_back.py | 480 ------------------ .../code/backboardManager.py | 80 --- .../code/bootstrap.py | 31 -- .../run_20250911-074447_ax0g50/code/wsgi.py | 6 - .../run_20250911-074447_ax0g50/logging.chat | 0 .../run_20250911-074447_ax0g50/logging.log | 1 - Html/runs/run_20250911-074454_2y1m70/.config | 7 - .../run_20250911-074454_2y1m70/agentscope.db | Bin 16384 -> 0 bytes .../run_20250911-074454_2y1m70/code/app.py | 21 - .../code/app_back.py | 480 ------------------ .../code/backboardManager.py | 80 --- .../code/bootstrap.py | 31 -- .../run_20250911-074454_2y1m70/code/wsgi.py | 6 - .../run_20250911-074454_2y1m70/logging.chat | 0 .../run_20250911-074454_2y1m70/logging.log | 1 - Html/runs/run_20250911-074554_cwc4d6/.config | 7 - .../run_20250911-074554_cwc4d6/agentscope.db | Bin 16384 -> 0 bytes .../run_20250911-074554_cwc4d6/code/app.py | 21 - .../code/app_back.py | 480 ------------------ .../code/backboardManager.py | 80 --- .../code/bootstrap.py | 31 -- .../run_20250911-074554_cwc4d6/code/wsgi.py | 6 - .../run_20250911-074554_cwc4d6/logging.chat | 0 .../run_20250911-074554_cwc4d6/logging.log | 1 - Html/runs/run_20250911-074558_y0uxsk/.config | 7 - .../run_20250911-074558_y0uxsk/agentscope.db | Bin 16384 -> 0 bytes .../run_20250911-074558_y0uxsk/code/app.py | 21 - .../code/app_back.py | 480 ------------------ .../code/backboardManager.py | 80 --- .../code/bootstrap.py | 31 -- .../run_20250911-074558_y0uxsk/code/wsgi.py | 6 - .../run_20250911-074558_y0uxsk/logging.chat | 0 .../run_20250911-074558_y0uxsk/logging.log | 1 - Html/runs/run_20250911-090314_4fof7d/.config | 7 - .../run_20250911-090314_4fof7d/agentscope.db | Bin 16384 -> 0 bytes .../run_20250911-090314_4fof7d/code/app.py | 21 - .../code/app_back.py | 480 ------------------ .../code/backboardManager.py | 80 --- .../code/bootstrap.py | 31 -- .../run_20250911-090314_4fof7d/code/wsgi.py | 6 - .../run_20250911-090314_4fof7d/logging.chat | 0 .../run_20250911-090314_4fof7d/logging.log | 1 - Html/runs/run_20250911-090321_2uj10i/.config | 7 - .../run_20250911-090321_2uj10i/agentscope.db | Bin 16384 -> 0 bytes .../run_20250911-090321_2uj10i/code/app.py | 21 - .../code/app_back.py | 480 ------------------ .../code/backboardManager.py | 80 --- .../code/bootstrap.py | 31 -- .../run_20250911-090321_2uj10i/code/wsgi.py | 6 - .../run_20250911-090321_2uj10i/logging.chat | 0 .../run_20250911-090321_2uj10i/logging.log | 1 - Html/runs/run_20250911-090909_8r99r2/.config | 7 - .../run_20250911-090909_8r99r2/agentscope.db | Bin 16384 -> 0 bytes .../run_20250911-090909_8r99r2/code/app.py | 21 - .../code/app_back.py | 480 ------------------ .../code/backboardManager.py | 80 --- .../code/bootstrap.py | 31 -- .../run_20250911-090909_8r99r2/code/wsgi.py | 6 - .../run_20250911-090909_8r99r2/logging.chat | 0 .../run_20250911-090909_8r99r2/logging.log | 1 - Html/runs/run_20250911-090913_pb8uat/.config | 7 - .../run_20250911-090913_pb8uat/agentscope.db | Bin 16384 -> 0 bytes .../run_20250911-090913_pb8uat/code/app.py | 21 - .../code/app_back.py | 480 ------------------ .../code/backboardManager.py | 80 --- .../code/bootstrap.py | 31 -- .../run_20250911-090913_pb8uat/code/wsgi.py | 6 - .../run_20250911-090913_pb8uat/logging.chat | 0 .../run_20250911-090913_pb8uat/logging.log | 1 - Html/runs/run_20250911-092225_wfvsed/.config | 7 - .../run_20250911-092225_wfvsed/agentscope.db | Bin 16384 -> 0 bytes .../run_20250911-092225_wfvsed/code/app.py | 21 - .../code/app_back.py | 480 ------------------ .../code/backboardManager.py | 80 --- .../code/bootstrap.py | 31 -- .../run_20250911-092225_wfvsed/code/wsgi.py | 6 - .../run_20250911-092225_wfvsed/logging.chat | 0 .../run_20250911-092225_wfvsed/logging.log | 1 - Html/runs/run_20250911-092231_bhi1fr/.config | 7 - .../run_20250911-092231_bhi1fr/agentscope.db | Bin 16384 -> 0 bytes .../run_20250911-092231_bhi1fr/code/app.py | 21 - .../code/app_back.py | 480 ------------------ .../code/backboardManager.py | 80 --- .../code/bootstrap.py | 31 -- .../run_20250911-092231_bhi1fr/code/wsgi.py | 6 - .../run_20250911-092231_bhi1fr/logging.chat | 0 .../run_20250911-092231_bhi1fr/logging.log | 1 - Html/runs/run_20250911-092325_o2aue5/.config | 7 - .../run_20250911-092325_o2aue5/agentscope.db | Bin 16384 -> 0 bytes .../run_20250911-092325_o2aue5/code/app.py | 21 - .../code/app_back.py | 480 ------------------ .../code/backboardManager.py | 80 --- .../code/bootstrap.py | 31 -- .../run_20250911-092325_o2aue5/code/wsgi.py | 6 - .../run_20250911-092325_o2aue5/logging.chat | 0 .../run_20250911-092325_o2aue5/logging.log | 1 - Html/runs/run_20250911-092331_bvossb/.config | 7 - .../run_20250911-092331_bvossb/agentscope.db | Bin 16384 -> 0 bytes .../run_20250911-092331_bvossb/code/app.py | 21 - .../code/app_back.py | 480 ------------------ .../code/backboardManager.py | 80 --- .../code/bootstrap.py | 31 -- .../run_20250911-092331_bvossb/code/wsgi.py | 6 - .../run_20250911-092331_bvossb/logging.chat | 0 .../run_20250911-092331_bvossb/logging.log | 1 - Html/runs/run_20250911-092722_nuvx5a/.config | 7 - .../run_20250911-092722_nuvx5a/agentscope.db | Bin 16384 -> 0 bytes .../run_20250911-092722_nuvx5a/code/app.py | 21 - .../code/app_back.py | 480 ------------------ .../code/backboardManager.py | 80 --- .../code/bootstrap.py | 31 -- .../run_20250911-092722_nuvx5a/code/wsgi.py | 6 - .../run_20250911-092722_nuvx5a/logging.chat | 0 .../run_20250911-092722_nuvx5a/logging.log | 1 - Html/runs/run_20250911-092728_5rmbf4/.config | 7 - .../run_20250911-092728_5rmbf4/agentscope.db | Bin 16384 -> 0 bytes .../run_20250911-092728_5rmbf4/code/app.py | 21 - .../code/app_back.py | 480 ------------------ .../code/backboardManager.py | 80 --- .../code/bootstrap.py | 31 -- .../run_20250911-092728_5rmbf4/code/wsgi.py | 6 - .../run_20250911-092728_5rmbf4/logging.chat | 0 .../run_20250911-092728_5rmbf4/logging.log | 1 - Html/runs/run_20250911-104127_qlzs2b/.config | 7 - .../run_20250911-104127_qlzs2b/agentscope.db | Bin 16384 -> 0 bytes .../run_20250911-104127_qlzs2b/code/app.py | 21 - .../code/app_back.py | 480 ------------------ .../code/backboardManager.py | 80 --- .../code/bootstrap.py | 31 -- .../run_20250911-104127_qlzs2b/code/wsgi.py | 6 - .../run_20250911-104127_qlzs2b/logging.chat | 0 .../run_20250911-104127_qlzs2b/logging.log | 1 - Html/runs/run_20250911-104133_7ghm53/.config | 7 - .../run_20250911-104133_7ghm53/agentscope.db | Bin 16384 -> 0 bytes .../run_20250911-104133_7ghm53/code/app.py | 21 - .../code/app_back.py | 480 ------------------ .../code/backboardManager.py | 80 --- .../code/bootstrap.py | 31 -- .../run_20250911-104133_7ghm53/code/wsgi.py | 6 - .../run_20250911-104133_7ghm53/logging.chat | 0 .../run_20250911-104133_7ghm53/logging.log | 1 - Html/runs/run_20250911-132607_r8195b/.config | 7 - .../run_20250911-132607_r8195b/agentscope.db | Bin 16384 -> 0 bytes .../run_20250911-132607_r8195b/code/app.py | 21 - .../code/app_back.py | 480 ------------------ .../code/backboardManager.py | 80 --- .../code/bootstrap.py | 31 -- .../run_20250911-132607_r8195b/code/wsgi.py | 6 - .../run_20250911-132607_r8195b/logging.chat | 0 .../run_20250911-132607_r8195b/logging.log | 1 - 378 files changed, 26306 deletions(-) delete mode 100644 Html/runs/run_20250906-141209_g777ho/.config delete mode 100644 Html/runs/run_20250906-141209_g777ho/agentscope.db delete mode 100644 Html/runs/run_20250906-141209_g777ho/code/app.py delete mode 100644 Html/runs/run_20250906-141209_g777ho/code/app_back.py delete mode 100644 Html/runs/run_20250906-141209_g777ho/code/backboardManager.py delete mode 100644 Html/runs/run_20250906-141209_g777ho/code/bootstrap.py delete mode 100644 Html/runs/run_20250906-141209_g777ho/code/wsgi.py delete mode 100644 Html/runs/run_20250906-141209_g777ho/logging.chat delete mode 100644 Html/runs/run_20250906-141209_g777ho/logging.log delete mode 100644 Html/runs/run_20250906-141216_d08zym/.config delete mode 100644 Html/runs/run_20250906-141216_d08zym/agentscope.db delete mode 100644 Html/runs/run_20250906-141216_d08zym/code/app.py delete mode 100644 Html/runs/run_20250906-141216_d08zym/code/app_back.py delete mode 100644 Html/runs/run_20250906-141216_d08zym/code/backboardManager.py delete mode 100644 Html/runs/run_20250906-141216_d08zym/code/bootstrap.py delete mode 100644 Html/runs/run_20250906-141216_d08zym/code/wsgi.py delete mode 100644 Html/runs/run_20250906-141216_d08zym/logging.chat delete mode 100644 Html/runs/run_20250906-141216_d08zym/logging.log delete mode 100644 Html/runs/run_20250906-141430_i7aihi/.config delete mode 100644 Html/runs/run_20250906-141430_i7aihi/agentscope.db delete mode 100644 Html/runs/run_20250906-141430_i7aihi/code/app.py delete mode 100644 Html/runs/run_20250906-141430_i7aihi/code/app_back.py delete mode 100644 Html/runs/run_20250906-141430_i7aihi/code/backboardManager.py delete mode 100644 Html/runs/run_20250906-141430_i7aihi/code/bootstrap.py delete mode 100644 Html/runs/run_20250906-141430_i7aihi/code/wsgi.py delete mode 100644 Html/runs/run_20250906-141430_i7aihi/logging.chat delete mode 100644 Html/runs/run_20250906-141430_i7aihi/logging.log delete mode 100644 Html/runs/run_20250906-141607_ym9kvd/.config delete mode 100644 Html/runs/run_20250906-141607_ym9kvd/agentscope.db delete mode 100644 Html/runs/run_20250906-141607_ym9kvd/code/app.py delete mode 100644 Html/runs/run_20250906-141607_ym9kvd/code/app_back.py delete mode 100644 Html/runs/run_20250906-141607_ym9kvd/code/backboardManager.py delete mode 100644 Html/runs/run_20250906-141607_ym9kvd/code/bootstrap.py delete mode 100644 Html/runs/run_20250906-141607_ym9kvd/code/wsgi.py delete mode 100644 Html/runs/run_20250906-141607_ym9kvd/logging.chat delete mode 100644 Html/runs/run_20250906-141607_ym9kvd/logging.log delete mode 100644 Html/runs/run_20250908-144720_kkn0r6/.config delete mode 100644 Html/runs/run_20250908-144720_kkn0r6/agentscope.db delete mode 100644 Html/runs/run_20250908-144720_kkn0r6/code/app.py delete mode 100644 Html/runs/run_20250908-144720_kkn0r6/code/app_back.py delete mode 100644 Html/runs/run_20250908-144720_kkn0r6/code/backboardManager.py delete mode 100644 Html/runs/run_20250908-144720_kkn0r6/code/bootstrap.py delete mode 100644 Html/runs/run_20250908-144720_kkn0r6/code/wsgi.py delete mode 100644 Html/runs/run_20250908-144720_kkn0r6/logging.chat delete mode 100644 Html/runs/run_20250908-144720_kkn0r6/logging.log delete mode 100644 Html/runs/run_20250908-145013_ycavxx/.config delete mode 100644 Html/runs/run_20250908-145013_ycavxx/agentscope.db delete mode 100644 Html/runs/run_20250908-145013_ycavxx/code/app.py delete mode 100644 Html/runs/run_20250908-145013_ycavxx/code/app_back.py delete mode 100644 Html/runs/run_20250908-145013_ycavxx/code/backboardManager.py delete mode 100644 Html/runs/run_20250908-145013_ycavxx/code/bootstrap.py delete mode 100644 Html/runs/run_20250908-145013_ycavxx/code/wsgi.py delete mode 100644 Html/runs/run_20250908-145013_ycavxx/logging.chat delete mode 100644 Html/runs/run_20250908-145013_ycavxx/logging.log delete mode 100644 Html/runs/run_20250911-033735_3vhfbh/.config delete mode 100644 Html/runs/run_20250911-033735_3vhfbh/agentscope.db delete mode 100644 Html/runs/run_20250911-033735_3vhfbh/code/app.py delete mode 100644 Html/runs/run_20250911-033735_3vhfbh/code/app_back.py delete mode 100644 Html/runs/run_20250911-033735_3vhfbh/code/backboardManager.py delete mode 100644 Html/runs/run_20250911-033735_3vhfbh/code/bootstrap.py delete mode 100644 Html/runs/run_20250911-033735_3vhfbh/code/wsgi.py delete mode 100644 Html/runs/run_20250911-033735_3vhfbh/logging.chat delete mode 100644 Html/runs/run_20250911-033735_3vhfbh/logging.log delete mode 100644 Html/runs/run_20250911-033739_mqgj3c/.config delete mode 100644 Html/runs/run_20250911-033739_mqgj3c/agentscope.db delete mode 100644 Html/runs/run_20250911-033739_mqgj3c/code/app.py delete mode 100644 Html/runs/run_20250911-033739_mqgj3c/code/app_back.py delete mode 100644 Html/runs/run_20250911-033739_mqgj3c/code/backboardManager.py delete mode 100644 Html/runs/run_20250911-033739_mqgj3c/code/bootstrap.py delete mode 100644 Html/runs/run_20250911-033739_mqgj3c/code/wsgi.py delete mode 100644 Html/runs/run_20250911-033739_mqgj3c/logging.chat delete mode 100644 Html/runs/run_20250911-033739_mqgj3c/logging.log delete mode 100644 Html/runs/run_20250911-042255_ebhoff/.config delete mode 100644 Html/runs/run_20250911-042255_ebhoff/agentscope.db delete mode 100644 Html/runs/run_20250911-042255_ebhoff/code/app.py delete mode 100644 Html/runs/run_20250911-042255_ebhoff/code/app_back.py delete mode 100644 Html/runs/run_20250911-042255_ebhoff/code/backboardManager.py delete mode 100644 Html/runs/run_20250911-042255_ebhoff/code/bootstrap.py delete mode 100644 Html/runs/run_20250911-042255_ebhoff/code/wsgi.py delete mode 100644 Html/runs/run_20250911-042255_ebhoff/logging.chat delete mode 100644 Html/runs/run_20250911-042255_ebhoff/logging.log delete mode 100644 Html/runs/run_20250911-042303_dshgn3/.config delete mode 100644 Html/runs/run_20250911-042303_dshgn3/agentscope.db delete mode 100644 Html/runs/run_20250911-042303_dshgn3/code/app.py delete mode 100644 Html/runs/run_20250911-042303_dshgn3/code/app_back.py delete mode 100644 Html/runs/run_20250911-042303_dshgn3/code/backboardManager.py delete mode 100644 Html/runs/run_20250911-042303_dshgn3/code/bootstrap.py delete mode 100644 Html/runs/run_20250911-042303_dshgn3/code/wsgi.py delete mode 100644 Html/runs/run_20250911-042303_dshgn3/logging.chat delete mode 100644 Html/runs/run_20250911-042303_dshgn3/logging.log delete mode 100644 Html/runs/run_20250911-042540_a7q7yd/.config delete mode 100644 Html/runs/run_20250911-042540_a7q7yd/agentscope.db delete mode 100644 Html/runs/run_20250911-042540_a7q7yd/code/app.py delete mode 100644 Html/runs/run_20250911-042540_a7q7yd/code/app_back.py delete mode 100644 Html/runs/run_20250911-042540_a7q7yd/code/backboardManager.py delete mode 100644 Html/runs/run_20250911-042540_a7q7yd/code/bootstrap.py delete mode 100644 Html/runs/run_20250911-042540_a7q7yd/code/wsgi.py delete mode 100644 Html/runs/run_20250911-042540_a7q7yd/logging.chat delete mode 100644 Html/runs/run_20250911-042540_a7q7yd/logging.log delete mode 100644 Html/runs/run_20250911-042825_sfp33j/.config delete mode 100644 Html/runs/run_20250911-042825_sfp33j/agentscope.db delete mode 100644 Html/runs/run_20250911-042825_sfp33j/code/app.py delete mode 100644 Html/runs/run_20250911-042825_sfp33j/code/app_back.py delete mode 100644 Html/runs/run_20250911-042825_sfp33j/code/backboardManager.py delete mode 100644 Html/runs/run_20250911-042825_sfp33j/code/bootstrap.py delete mode 100644 Html/runs/run_20250911-042825_sfp33j/code/wsgi.py delete mode 100644 Html/runs/run_20250911-042825_sfp33j/logging.chat delete mode 100644 Html/runs/run_20250911-042825_sfp33j/logging.log delete mode 100644 Html/runs/run_20250911-055537_tio6to/.config delete mode 100644 Html/runs/run_20250911-055537_tio6to/agentscope.db delete mode 100644 Html/runs/run_20250911-055537_tio6to/code/app.py delete mode 100644 Html/runs/run_20250911-055537_tio6to/code/app_back.py delete mode 100644 Html/runs/run_20250911-055537_tio6to/code/backboardManager.py delete mode 100644 Html/runs/run_20250911-055537_tio6to/code/bootstrap.py delete mode 100644 Html/runs/run_20250911-055537_tio6to/code/wsgi.py delete mode 100644 Html/runs/run_20250911-055537_tio6to/logging.chat delete mode 100644 Html/runs/run_20250911-055537_tio6to/logging.log delete mode 100644 Html/runs/run_20250911-055544_hp3t1k/.config delete mode 100644 Html/runs/run_20250911-055544_hp3t1k/agentscope.db delete mode 100644 Html/runs/run_20250911-055544_hp3t1k/code/app.py delete mode 100644 Html/runs/run_20250911-055544_hp3t1k/code/app_back.py delete mode 100644 Html/runs/run_20250911-055544_hp3t1k/code/backboardManager.py delete mode 100644 Html/runs/run_20250911-055544_hp3t1k/code/bootstrap.py delete mode 100644 Html/runs/run_20250911-055544_hp3t1k/code/wsgi.py delete mode 100644 Html/runs/run_20250911-055544_hp3t1k/logging.chat delete mode 100644 Html/runs/run_20250911-055544_hp3t1k/logging.log delete mode 100644 Html/runs/run_20250911-055810_isow4t/.config delete mode 100644 Html/runs/run_20250911-055810_isow4t/agentscope.db delete mode 100644 Html/runs/run_20250911-055810_isow4t/code/app.py delete mode 100644 Html/runs/run_20250911-055810_isow4t/code/app_back.py delete mode 100644 Html/runs/run_20250911-055810_isow4t/code/backboardManager.py delete mode 100644 Html/runs/run_20250911-055810_isow4t/code/bootstrap.py delete mode 100644 Html/runs/run_20250911-055810_isow4t/code/wsgi.py delete mode 100644 Html/runs/run_20250911-055810_isow4t/logging.chat delete mode 100644 Html/runs/run_20250911-055810_isow4t/logging.log delete mode 100644 Html/runs/run_20250911-055837_qf7qys/.config delete mode 100644 Html/runs/run_20250911-055837_qf7qys/agentscope.db delete mode 100644 Html/runs/run_20250911-055837_qf7qys/code/app.py delete mode 100644 Html/runs/run_20250911-055837_qf7qys/code/app_back.py delete mode 100644 Html/runs/run_20250911-055837_qf7qys/code/backboardManager.py delete mode 100644 Html/runs/run_20250911-055837_qf7qys/code/bootstrap.py delete mode 100644 Html/runs/run_20250911-055837_qf7qys/code/wsgi.py delete mode 100644 Html/runs/run_20250911-055837_qf7qys/logging.chat delete mode 100644 Html/runs/run_20250911-055837_qf7qys/logging.log delete mode 100644 Html/runs/run_20250911-055913_b9hlng/.config delete mode 100644 Html/runs/run_20250911-055913_b9hlng/agentscope.db delete mode 100644 Html/runs/run_20250911-055913_b9hlng/code/app.py delete mode 100644 Html/runs/run_20250911-055913_b9hlng/code/app_back.py delete mode 100644 Html/runs/run_20250911-055913_b9hlng/code/backboardManager.py delete mode 100644 Html/runs/run_20250911-055913_b9hlng/code/bootstrap.py delete mode 100644 Html/runs/run_20250911-055913_b9hlng/code/wsgi.py delete mode 100644 Html/runs/run_20250911-055913_b9hlng/logging.chat delete mode 100644 Html/runs/run_20250911-055913_b9hlng/logging.log delete mode 100644 Html/runs/run_20250911-060203_yfghxt/.config delete mode 100644 Html/runs/run_20250911-060203_yfghxt/agentscope.db delete mode 100644 Html/runs/run_20250911-060203_yfghxt/code/app.py delete mode 100644 Html/runs/run_20250911-060203_yfghxt/code/app_back.py delete mode 100644 Html/runs/run_20250911-060203_yfghxt/code/backboardManager.py delete mode 100644 Html/runs/run_20250911-060203_yfghxt/code/bootstrap.py delete mode 100644 Html/runs/run_20250911-060203_yfghxt/code/wsgi.py delete mode 100644 Html/runs/run_20250911-060203_yfghxt/logging.chat delete mode 100644 Html/runs/run_20250911-060203_yfghxt/logging.log delete mode 100644 Html/runs/run_20250911-060207_rce61h/.config delete mode 100644 Html/runs/run_20250911-060207_rce61h/agentscope.db delete mode 100644 Html/runs/run_20250911-060207_rce61h/code/app.py delete mode 100644 Html/runs/run_20250911-060207_rce61h/code/app_back.py delete mode 100644 Html/runs/run_20250911-060207_rce61h/code/backboardManager.py delete mode 100644 Html/runs/run_20250911-060207_rce61h/code/bootstrap.py delete mode 100644 Html/runs/run_20250911-060207_rce61h/code/wsgi.py delete mode 100644 Html/runs/run_20250911-060207_rce61h/logging.chat delete mode 100644 Html/runs/run_20250911-060207_rce61h/logging.log delete mode 100644 Html/runs/run_20250911-060246_40ksl2/.config delete mode 100644 Html/runs/run_20250911-060246_40ksl2/agentscope.db delete mode 100644 Html/runs/run_20250911-060246_40ksl2/code/app.py delete mode 100644 Html/runs/run_20250911-060246_40ksl2/code/app_back.py delete mode 100644 Html/runs/run_20250911-060246_40ksl2/code/backboardManager.py delete mode 100644 Html/runs/run_20250911-060246_40ksl2/code/bootstrap.py delete mode 100644 Html/runs/run_20250911-060246_40ksl2/code/wsgi.py delete mode 100644 Html/runs/run_20250911-060246_40ksl2/logging.chat delete mode 100644 Html/runs/run_20250911-060246_40ksl2/logging.log delete mode 100644 Html/runs/run_20250911-060318_ec1mwg/.config delete mode 100644 Html/runs/run_20250911-060318_ec1mwg/agentscope.db delete mode 100644 Html/runs/run_20250911-060318_ec1mwg/code/app.py delete mode 100644 Html/runs/run_20250911-060318_ec1mwg/code/app_back.py delete mode 100644 Html/runs/run_20250911-060318_ec1mwg/code/backboardManager.py delete mode 100644 Html/runs/run_20250911-060318_ec1mwg/code/bootstrap.py delete mode 100644 Html/runs/run_20250911-060318_ec1mwg/code/wsgi.py delete mode 100644 Html/runs/run_20250911-060318_ec1mwg/logging.chat delete mode 100644 Html/runs/run_20250911-060318_ec1mwg/logging.log delete mode 100644 Html/runs/run_20250911-060514_w6745q/.config delete mode 100644 Html/runs/run_20250911-060514_w6745q/agentscope.db delete mode 100644 Html/runs/run_20250911-060514_w6745q/code/app.py delete mode 100644 Html/runs/run_20250911-060514_w6745q/code/app_back.py delete mode 100644 Html/runs/run_20250911-060514_w6745q/code/backboardManager.py delete mode 100644 Html/runs/run_20250911-060514_w6745q/code/bootstrap.py delete mode 100644 Html/runs/run_20250911-060514_w6745q/code/wsgi.py delete mode 100644 Html/runs/run_20250911-060514_w6745q/logging.chat delete mode 100644 Html/runs/run_20250911-060514_w6745q/logging.log delete mode 100644 Html/runs/run_20250911-060518_fd3vqd/.config delete mode 100644 Html/runs/run_20250911-060518_fd3vqd/agentscope.db delete mode 100644 Html/runs/run_20250911-060518_fd3vqd/code/app.py delete mode 100644 Html/runs/run_20250911-060518_fd3vqd/code/app_back.py delete mode 100644 Html/runs/run_20250911-060518_fd3vqd/code/backboardManager.py delete mode 100644 Html/runs/run_20250911-060518_fd3vqd/code/bootstrap.py delete mode 100644 Html/runs/run_20250911-060518_fd3vqd/code/wsgi.py delete mode 100644 Html/runs/run_20250911-060518_fd3vqd/logging.chat delete mode 100644 Html/runs/run_20250911-060518_fd3vqd/logging.log delete mode 100644 Html/runs/run_20250911-060940_yzij8b/.config delete mode 100644 Html/runs/run_20250911-060940_yzij8b/agentscope.db delete mode 100644 Html/runs/run_20250911-060940_yzij8b/code/app.py delete mode 100644 Html/runs/run_20250911-060940_yzij8b/code/app_back.py delete mode 100644 Html/runs/run_20250911-060940_yzij8b/code/backboardManager.py delete mode 100644 Html/runs/run_20250911-060940_yzij8b/code/bootstrap.py delete mode 100644 Html/runs/run_20250911-060940_yzij8b/code/wsgi.py delete mode 100644 Html/runs/run_20250911-060940_yzij8b/logging.chat delete mode 100644 Html/runs/run_20250911-060940_yzij8b/logging.log delete mode 100644 Html/runs/run_20250911-060944_a5y9ow/.config delete mode 100644 Html/runs/run_20250911-060944_a5y9ow/agentscope.db delete mode 100644 Html/runs/run_20250911-060944_a5y9ow/code/app.py delete mode 100644 Html/runs/run_20250911-060944_a5y9ow/code/app_back.py delete mode 100644 Html/runs/run_20250911-060944_a5y9ow/code/backboardManager.py delete mode 100644 Html/runs/run_20250911-060944_a5y9ow/code/bootstrap.py delete mode 100644 Html/runs/run_20250911-060944_a5y9ow/code/wsgi.py delete mode 100644 Html/runs/run_20250911-060944_a5y9ow/logging.chat delete mode 100644 Html/runs/run_20250911-060944_a5y9ow/logging.log delete mode 100644 Html/runs/run_20250911-074447_ax0g50/.config delete mode 100644 Html/runs/run_20250911-074447_ax0g50/agentscope.db delete mode 100644 Html/runs/run_20250911-074447_ax0g50/code/app.py delete mode 100644 Html/runs/run_20250911-074447_ax0g50/code/app_back.py delete mode 100644 Html/runs/run_20250911-074447_ax0g50/code/backboardManager.py delete mode 100644 Html/runs/run_20250911-074447_ax0g50/code/bootstrap.py delete mode 100644 Html/runs/run_20250911-074447_ax0g50/code/wsgi.py delete mode 100644 Html/runs/run_20250911-074447_ax0g50/logging.chat delete mode 100644 Html/runs/run_20250911-074447_ax0g50/logging.log delete mode 100644 Html/runs/run_20250911-074454_2y1m70/.config delete mode 100644 Html/runs/run_20250911-074454_2y1m70/agentscope.db delete mode 100644 Html/runs/run_20250911-074454_2y1m70/code/app.py delete mode 100644 Html/runs/run_20250911-074454_2y1m70/code/app_back.py delete mode 100644 Html/runs/run_20250911-074454_2y1m70/code/backboardManager.py delete mode 100644 Html/runs/run_20250911-074454_2y1m70/code/bootstrap.py delete mode 100644 Html/runs/run_20250911-074454_2y1m70/code/wsgi.py delete mode 100644 Html/runs/run_20250911-074454_2y1m70/logging.chat delete mode 100644 Html/runs/run_20250911-074454_2y1m70/logging.log delete mode 100644 Html/runs/run_20250911-074554_cwc4d6/.config delete mode 100644 Html/runs/run_20250911-074554_cwc4d6/agentscope.db delete mode 100644 Html/runs/run_20250911-074554_cwc4d6/code/app.py delete mode 100644 Html/runs/run_20250911-074554_cwc4d6/code/app_back.py delete mode 100644 Html/runs/run_20250911-074554_cwc4d6/code/backboardManager.py delete mode 100644 Html/runs/run_20250911-074554_cwc4d6/code/bootstrap.py delete mode 100644 Html/runs/run_20250911-074554_cwc4d6/code/wsgi.py delete mode 100644 Html/runs/run_20250911-074554_cwc4d6/logging.chat delete mode 100644 Html/runs/run_20250911-074554_cwc4d6/logging.log delete mode 100644 Html/runs/run_20250911-074558_y0uxsk/.config delete mode 100644 Html/runs/run_20250911-074558_y0uxsk/agentscope.db delete mode 100644 Html/runs/run_20250911-074558_y0uxsk/code/app.py delete mode 100644 Html/runs/run_20250911-074558_y0uxsk/code/app_back.py delete mode 100644 Html/runs/run_20250911-074558_y0uxsk/code/backboardManager.py delete mode 100644 Html/runs/run_20250911-074558_y0uxsk/code/bootstrap.py delete mode 100644 Html/runs/run_20250911-074558_y0uxsk/code/wsgi.py delete mode 100644 Html/runs/run_20250911-074558_y0uxsk/logging.chat delete mode 100644 Html/runs/run_20250911-074558_y0uxsk/logging.log delete mode 100644 Html/runs/run_20250911-090314_4fof7d/.config delete mode 100644 Html/runs/run_20250911-090314_4fof7d/agentscope.db delete mode 100644 Html/runs/run_20250911-090314_4fof7d/code/app.py delete mode 100644 Html/runs/run_20250911-090314_4fof7d/code/app_back.py delete mode 100644 Html/runs/run_20250911-090314_4fof7d/code/backboardManager.py delete mode 100644 Html/runs/run_20250911-090314_4fof7d/code/bootstrap.py delete mode 100644 Html/runs/run_20250911-090314_4fof7d/code/wsgi.py delete mode 100644 Html/runs/run_20250911-090314_4fof7d/logging.chat delete mode 100644 Html/runs/run_20250911-090314_4fof7d/logging.log delete mode 100644 Html/runs/run_20250911-090321_2uj10i/.config delete mode 100644 Html/runs/run_20250911-090321_2uj10i/agentscope.db delete mode 100644 Html/runs/run_20250911-090321_2uj10i/code/app.py delete mode 100644 Html/runs/run_20250911-090321_2uj10i/code/app_back.py delete mode 100644 Html/runs/run_20250911-090321_2uj10i/code/backboardManager.py delete mode 100644 Html/runs/run_20250911-090321_2uj10i/code/bootstrap.py delete mode 100644 Html/runs/run_20250911-090321_2uj10i/code/wsgi.py delete mode 100644 Html/runs/run_20250911-090321_2uj10i/logging.chat delete mode 100644 Html/runs/run_20250911-090321_2uj10i/logging.log delete mode 100644 Html/runs/run_20250911-090909_8r99r2/.config delete mode 100644 Html/runs/run_20250911-090909_8r99r2/agentscope.db delete mode 100644 Html/runs/run_20250911-090909_8r99r2/code/app.py delete mode 100644 Html/runs/run_20250911-090909_8r99r2/code/app_back.py delete mode 100644 Html/runs/run_20250911-090909_8r99r2/code/backboardManager.py delete mode 100644 Html/runs/run_20250911-090909_8r99r2/code/bootstrap.py delete mode 100644 Html/runs/run_20250911-090909_8r99r2/code/wsgi.py delete mode 100644 Html/runs/run_20250911-090909_8r99r2/logging.chat delete mode 100644 Html/runs/run_20250911-090909_8r99r2/logging.log delete mode 100644 Html/runs/run_20250911-090913_pb8uat/.config delete mode 100644 Html/runs/run_20250911-090913_pb8uat/agentscope.db delete mode 100644 Html/runs/run_20250911-090913_pb8uat/code/app.py delete mode 100644 Html/runs/run_20250911-090913_pb8uat/code/app_back.py delete mode 100644 Html/runs/run_20250911-090913_pb8uat/code/backboardManager.py delete mode 100644 Html/runs/run_20250911-090913_pb8uat/code/bootstrap.py delete mode 100644 Html/runs/run_20250911-090913_pb8uat/code/wsgi.py delete mode 100644 Html/runs/run_20250911-090913_pb8uat/logging.chat delete mode 100644 Html/runs/run_20250911-090913_pb8uat/logging.log delete mode 100644 Html/runs/run_20250911-092225_wfvsed/.config delete mode 100644 Html/runs/run_20250911-092225_wfvsed/agentscope.db delete mode 100644 Html/runs/run_20250911-092225_wfvsed/code/app.py delete mode 100644 Html/runs/run_20250911-092225_wfvsed/code/app_back.py delete mode 100644 Html/runs/run_20250911-092225_wfvsed/code/backboardManager.py delete mode 100644 Html/runs/run_20250911-092225_wfvsed/code/bootstrap.py delete mode 100644 Html/runs/run_20250911-092225_wfvsed/code/wsgi.py delete mode 100644 Html/runs/run_20250911-092225_wfvsed/logging.chat delete mode 100644 Html/runs/run_20250911-092225_wfvsed/logging.log delete mode 100644 Html/runs/run_20250911-092231_bhi1fr/.config delete mode 100644 Html/runs/run_20250911-092231_bhi1fr/agentscope.db delete mode 100644 Html/runs/run_20250911-092231_bhi1fr/code/app.py delete mode 100644 Html/runs/run_20250911-092231_bhi1fr/code/app_back.py delete mode 100644 Html/runs/run_20250911-092231_bhi1fr/code/backboardManager.py delete mode 100644 Html/runs/run_20250911-092231_bhi1fr/code/bootstrap.py delete mode 100644 Html/runs/run_20250911-092231_bhi1fr/code/wsgi.py delete mode 100644 Html/runs/run_20250911-092231_bhi1fr/logging.chat delete mode 100644 Html/runs/run_20250911-092231_bhi1fr/logging.log delete mode 100644 Html/runs/run_20250911-092325_o2aue5/.config delete mode 100644 Html/runs/run_20250911-092325_o2aue5/agentscope.db delete mode 100644 Html/runs/run_20250911-092325_o2aue5/code/app.py delete mode 100644 Html/runs/run_20250911-092325_o2aue5/code/app_back.py delete mode 100644 Html/runs/run_20250911-092325_o2aue5/code/backboardManager.py delete mode 100644 Html/runs/run_20250911-092325_o2aue5/code/bootstrap.py delete mode 100644 Html/runs/run_20250911-092325_o2aue5/code/wsgi.py delete mode 100644 Html/runs/run_20250911-092325_o2aue5/logging.chat delete mode 100644 Html/runs/run_20250911-092325_o2aue5/logging.log delete mode 100644 Html/runs/run_20250911-092331_bvossb/.config delete mode 100644 Html/runs/run_20250911-092331_bvossb/agentscope.db delete mode 100644 Html/runs/run_20250911-092331_bvossb/code/app.py delete mode 100644 Html/runs/run_20250911-092331_bvossb/code/app_back.py delete mode 100644 Html/runs/run_20250911-092331_bvossb/code/backboardManager.py delete mode 100644 Html/runs/run_20250911-092331_bvossb/code/bootstrap.py delete mode 100644 Html/runs/run_20250911-092331_bvossb/code/wsgi.py delete mode 100644 Html/runs/run_20250911-092331_bvossb/logging.chat delete mode 100644 Html/runs/run_20250911-092331_bvossb/logging.log delete mode 100644 Html/runs/run_20250911-092722_nuvx5a/.config delete mode 100644 Html/runs/run_20250911-092722_nuvx5a/agentscope.db delete mode 100644 Html/runs/run_20250911-092722_nuvx5a/code/app.py delete mode 100644 Html/runs/run_20250911-092722_nuvx5a/code/app_back.py delete mode 100644 Html/runs/run_20250911-092722_nuvx5a/code/backboardManager.py delete mode 100644 Html/runs/run_20250911-092722_nuvx5a/code/bootstrap.py delete mode 100644 Html/runs/run_20250911-092722_nuvx5a/code/wsgi.py delete mode 100644 Html/runs/run_20250911-092722_nuvx5a/logging.chat delete mode 100644 Html/runs/run_20250911-092722_nuvx5a/logging.log delete mode 100644 Html/runs/run_20250911-092728_5rmbf4/.config delete mode 100644 Html/runs/run_20250911-092728_5rmbf4/agentscope.db delete mode 100644 Html/runs/run_20250911-092728_5rmbf4/code/app.py delete mode 100644 Html/runs/run_20250911-092728_5rmbf4/code/app_back.py delete mode 100644 Html/runs/run_20250911-092728_5rmbf4/code/backboardManager.py delete mode 100644 Html/runs/run_20250911-092728_5rmbf4/code/bootstrap.py delete mode 100644 Html/runs/run_20250911-092728_5rmbf4/code/wsgi.py delete mode 100644 Html/runs/run_20250911-092728_5rmbf4/logging.chat delete mode 100644 Html/runs/run_20250911-092728_5rmbf4/logging.log delete mode 100644 Html/runs/run_20250911-104127_qlzs2b/.config delete mode 100644 Html/runs/run_20250911-104127_qlzs2b/agentscope.db delete mode 100644 Html/runs/run_20250911-104127_qlzs2b/code/app.py delete mode 100644 Html/runs/run_20250911-104127_qlzs2b/code/app_back.py delete mode 100644 Html/runs/run_20250911-104127_qlzs2b/code/backboardManager.py delete mode 100644 Html/runs/run_20250911-104127_qlzs2b/code/bootstrap.py delete mode 100644 Html/runs/run_20250911-104127_qlzs2b/code/wsgi.py delete mode 100644 Html/runs/run_20250911-104127_qlzs2b/logging.chat delete mode 100644 Html/runs/run_20250911-104127_qlzs2b/logging.log delete mode 100644 Html/runs/run_20250911-104133_7ghm53/.config delete mode 100644 Html/runs/run_20250911-104133_7ghm53/agentscope.db delete mode 100644 Html/runs/run_20250911-104133_7ghm53/code/app.py delete mode 100644 Html/runs/run_20250911-104133_7ghm53/code/app_back.py delete mode 100644 Html/runs/run_20250911-104133_7ghm53/code/backboardManager.py delete mode 100644 Html/runs/run_20250911-104133_7ghm53/code/bootstrap.py delete mode 100644 Html/runs/run_20250911-104133_7ghm53/code/wsgi.py delete mode 100644 Html/runs/run_20250911-104133_7ghm53/logging.chat delete mode 100644 Html/runs/run_20250911-104133_7ghm53/logging.log delete mode 100644 Html/runs/run_20250911-132607_r8195b/.config delete mode 100644 Html/runs/run_20250911-132607_r8195b/agentscope.db delete mode 100644 Html/runs/run_20250911-132607_r8195b/code/app.py delete mode 100644 Html/runs/run_20250911-132607_r8195b/code/app_back.py delete mode 100644 Html/runs/run_20250911-132607_r8195b/code/backboardManager.py delete mode 100644 Html/runs/run_20250911-132607_r8195b/code/bootstrap.py delete mode 100644 Html/runs/run_20250911-132607_r8195b/code/wsgi.py delete mode 100644 Html/runs/run_20250911-132607_r8195b/logging.chat delete mode 100644 Html/runs/run_20250911-132607_r8195b/logging.log diff --git a/Html/runs/run_20250906-141209_g777ho/.config b/Html/runs/run_20250906-141209_g777ho/.config deleted file mode 100644 index cf1cc6c..0000000 --- a/Html/runs/run_20250906-141209_g777ho/.config +++ /dev/null @@ -1,7 +0,0 @@ -{ - "project": "0oWn86", - "name": "g777ho", - "run_id": "run_20250906-141209_g777ho", - "timestamp": "2025-09-06 14:12:09", - "pid": 16311 -} \ No newline at end of file diff --git a/Html/runs/run_20250906-141209_g777ho/agentscope.db b/Html/runs/run_20250906-141209_g777ho/agentscope.db deleted file mode 100644 index 666055b77679cda29c14fcf23b4ef1d039c5b52a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI%L2KJE6bEoS4Q(k)+glI2yjv3-0%NB!Hs&O1YUav`W0U1F<0V=#BsNLx(sSu$ z>=W&q?4#^B$!*yt2YT5l`~^0a^z(#~{ zkyg6w!t)u0!@f%5aeaJcfD9*Q_b$ozCY8>~CFA6|{Z2V!N;Z^cIq}eS$>x3HY|^=j z7lokrf1)Z$x@_R^N~@apn7OPMkZ(I<*1WJCw@v3GWy2n6&RcIQ0~zlR_x8^$%be!% zmxb7@7V;}H+K5#l(wSbZKXKY!mys6ROyi|!%aN@+%REpi?;B-K4PC3&{>iCzQnNB+ zwbW!z4iA{x(V_2L+5VJ1vMJeN;5l68yJ9?OZyl-TNCEp4P{^H8$cTGExdq$9ANE6@ zA@`ZUhb>is+Y=S?%$C1fnN{muZU1a!nMRV%#qFbMT;y3hf|KlJ)00Izz00bZa0SG_<0uX=z1a@EGHy1PL*Z=?k diff --git a/Html/runs/run_20250906-141209_g777ho/code/app.py b/Html/runs/run_20250906-141209_g777ho/code/app.py deleted file mode 100644 index df3bc94..0000000 --- a/Html/runs/run_20250906-141209_g777ho/code/app.py +++ /dev/null @@ -1,20 +0,0 @@ -# app.py 0.1.1 rise to factory mode -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -from apps.extensions import socketio - -# 工厂创建 app,工厂里已经做了:加载配置/注册蓝图/注册 namespaces -app = create_app() - -if __name__ == "__main__": - # 仅本地开发用;生产不要用 werkzeug 自带的开发服务器 - socketio.run( - app, - host="0.0.0.0", - port=5551, - debug=True, # 开发期打开 - allow_unsafe_werkzeug=True # 避免 dev server 的安全限制提示 - ) - - diff --git a/Html/runs/run_20250906-141209_g777ho/code/app_back.py b/Html/runs/run_20250906-141209_g777ho/code/app_back.py deleted file mode 100644 index 246853c..0000000 --- a/Html/runs/run_20250906-141209_g777ho/code/app_back.py +++ /dev/null @@ -1,480 +0,0 @@ -from bootstrap import bootstrap_paths -bootstrap_paths() -from functools import wraps -from flask import Flask, redirect, session, request, jsonify, render_template, send_from_directory, url_for -from flask_cors import CORS -from flask_socketio import SocketIO, join_room, emit, Namespace -import markdown -import os -import uuid -import shutil -import sys -import json -from apps.auth.decorators import require_role -parent_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) -sys.path.insert(0, parent_dir) -student_workspace_root_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../study')) -current_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '.')) -sys.path.insert(0, current_dir) -from AlgoriAgent.projects.algoriAgent.agent_manager import AgentManager - - -import configparser - -from db.user_list import UserList -from db.user import User, load_user_from_json, create_user_json -from db.course_list import CourseList -from db.course import Course, load_course_from_json -GLOBAL_CONFIG = configparser.ConfigParser() -GLOBAL_CONFIG.read('config.ini') -VSCODE_WEB_URL = GLOBAL_CONFIG['VSCODE_WEB']['url'] -USER_DATA_DIR = GLOBAL_CONFIG['USER_DATA']['dir'] -COURSE_DATA_DIR = GLOBAL_CONFIG['COURSE_DATA']['dir'] - -app = Flask(__name__) -socketio = SocketIO(app, cors_allowed_origins="*",ping_timeout=60, ping_interval=5) -# socketio = SocketIO(app, cors_allowed_origins="http://localhost:9888") # 设置跨域支持 -import logging -app.secret_key = 'cakebaker' -app.logger.setLevel(logging.DEBUG) -# 配置 CORS -CORS(app, resources={r"/*": {"origins": VSCODE_WEB_URL},}, supports_credentials=True) - - -userid_recorder = {} # user_id&path -> session['user_id'] - -''' -Backboard -''' -from backboardManager import BackBoardManager, Backboard - -backboard_manager = BackBoardManager() -uuid2username = {} -username2uuid = {} - - - -# 定义命名空间:用于和 VSCode 插件交流 -class VSCodeNamespace(Namespace): - def on_login(self,data): - print("VSCode client connected") - print(data) - dataconfig = data['config'] - user_id = dataconfig.get('user_id') - path = dataconfig.get('path') - course_id = dataconfig.get('course_id') - lesson_id = dataconfig.get('chapter_id') - print(f"User {user_id} connected with path: {path}") - useruuid = username2uuid[user_id] - join_room(useruuid, namespace='/vscode') - if backboard_manager.get_backboard(useruuid) == None: - backboard_manager.add_backboard(useruuid,user_id, course_id, lesson_id, path) - - - def on_message(self, data): - print(f"Received from VSCode client: {data}") - dataconfig = data['config'] - realtime_response(dataconfig, data) - # emit('response', {'message': 'Config data received and connection established'}) - def on_disconnect(self, data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - -def realtime_response(config, realtime_action): - user_id = config['user_id'] - folder_path = config['path'] - useruuid = username2uuid[user_id] - bb = backboard_manager.get_backboard(useruuid) - assert type(bb) == Backboard - - bb.add_history(realtime_action) - - if realtime_action['type'] == 'workspaceFolders': - bb.file_tree = realtime_action['fileTree'] - - if realtime_action['type'] == 'activeFile': - file_path = realtime_action['filePath'] - assert type(file_path) == str - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - if realtime_action['type'] == 'paste': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.pasted_file_path = file_path - bb.pasted_content = realtime_action['content'] - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - if realtime_action['type'] == 'fileEdit': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - - - print("config"+str(config)) - print("realtime_action"+str(realtime_action)) - pass - - -''' -Agent and Chat -''' -agent_manager = AgentManager(app = app, socketio = socketio) -user_threads = {} -import threading -from concurrent.futures import ThreadPoolExecutor, as_completed - -# 初始化线程池 -executor = ThreadPoolExecutor(max_workers=10) -class AgentNamespace(Namespace): - def on_login(self, data): - data = json.loads(data) - user = data['username'] - course_id = data['course_id'] - chapter_id = data['chapter_id'] - user_uuid = username2uuid[user] - session['user_id'] = user_uuid - print(f'User connected with session user_id: {user_uuid}') - # 从markdown、markdown_prompts、score_prompts中各读取数据folder.md并进行new_agent - with open(f'books/markdown/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fmd,\ - open(f'books/markdown_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8')as fmdp,\ - open(f'books/score_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fsp: - markdown = fmd.read() - markdown_prompts = fmdp.read() - score_prompts = fsp.read() - user_uuid, agent = agent_manager.new_agent(course_id, chapter_id, markdown, markdown_prompts, score_prompts, id=user_uuid, - root_path=f'../../study/{user}/{course_id}/{chapter_id}') - print(user_uuid) - join_room(user_uuid, namespace='/agent') # 将该用户加入以user_id为名的room - backboard_manager.add_backboard(user_uuid, user, course_id, chapter_id, root_path=f'../../study/{user}/{course_id}/{chapter_id}') - - def on_language(self, language): - id = session.get('user_id') - agent_manager.change_language(id, language) - - def on_message(self, data): - print(f"Message from client: {data}") - id = session.get('user_id') - if (type(data)==str): - data = json.loads(data) - print(id) - if data['type'] == 'text': - res = agent_manager.invoke(id, data['data'], backboard_manager.get_backboard(id).get_info_prompt()) - print('=*='*20) - print(res.content) - reply = f"{res.content['speak']}" - with app.app_context(): - emit('message',reply, room=id, namespace='/agent') - emit('request_function',res.content['function'], room=id, namespace='/agent') - - if data['type'] == 'function': - agent_manager.function_call(id, data['data']) - - def on_initiative(self,data): - print("User active function call") - user_id = session['user_id'] - if data['name'] == 'sample_judge': - agent_manager.sample_judge(user_id, backboard_manager.get_backboard(user_id)) - if data['name'] == 'judge': - agent_manager.judge(user_id, backboard_manager.get_backboard(user_id)) - - - - def on_disconnect(self,data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - - -''' -Markdown to HTML -''' -# 配置文件路径 -MARKDOWN_DIR = 'books/markdown' # 存放 markdown 文件的文件夹 -STATIC_DIR = 'static' # 存放生成的 HTML 和图片资源的文件夹 -IMAGE_DIR = 'image' # 图片资源相对于 markdown 的位置 - - - -@app.route('/--markdown', methods=['GET']) -def convert_md(course_id, filename): - md_file_path = os.path.join(MARKDOWN_DIR,course_id, f'{filename}.md') - - if not os.path.exists(md_file_path): - return jsonify({'error': 'Markdown file not found'}), 404 - - # 读取 markdown 文件内容 - with open(md_file_path, 'r', encoding='utf-8') as file: - md_content = file.read() - - # 将 markdown 转换为 HTML - html_content = markdown.markdown(md_content) - # 插入 CSS 样式,限制图片最大宽度为 100%,高度自动调整 - html_with_styles = f""" - - - - - - - {html_content} - - - """ - # 保存 HTML 文件到 static 文件夹 - html_output_path = os.path.join(STATIC_DIR, f'{filename}.html') - with open(html_output_path, 'w', encoding='utf-8') as html_file: - html_file.write(html_with_styles) - - # 处理图片资源,将 image/xxx 文件夹拷贝到 static/image/xxx - image_source_dir = os.path.join(MARKDOWN_DIR,course_id, IMAGE_DIR, filename) - image_target_dir = os.path.join(STATIC_DIR, IMAGE_DIR, filename) - print(f"Copying image resources from {image_source_dir} to {image_target_dir}") - if os.path.exists(image_source_dir): - # 确保 static/image/xxx 目录存在 - if not os.path.exists(image_target_dir): - os.makedirs(image_target_dir) - - # 拷贝图片资源 - for image_file in os.listdir(image_source_dir): - full_image_file_path = os.path.join(image_source_dir, image_file) - if os.path.isfile(full_image_file_path): - shutil.copy(full_image_file_path, image_target_dir) - - return jsonify({'html_url': f'/static/{filename}.html'}) - -# 静态文件(HTML 和图片资源)的访问 -@app.route('/static/') -def serve_static(filename): - return send_from_directory(STATIC_DIR, filename) - - -''' -Vscode -''' -@app.route('/desktop///') -def desktop(user_id, course_id, chapter_id): - if 'user_id' not in session: - # return redirect(url_for('login')) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ user_id + "uuid is"+ session['user_id']) - username2uuid[user_id] = session['user_id'] - uuid2username[session['user_id']] = user_id - userid_recorder[user_id+'&'+course_id] = session['user_id'] - - # 在学习目录下创建一个名为 user_id_path 的文件夹 - path_dir = os.path.join(student_workspace_root_path, user_id, course_id,chapter_id) - os.makedirs(path_dir, exist_ok=True) - # 在此文件夹内部创建一个.config文件,并写入 user_id=user_id\n path=path - config_path = os.path.join(path_dir, '.config') - if GLOBAL_CONFIG['VSCODE_WEB_PATH']['is_wsl']: # 如果是在 WSL 中运行,则将路径转换为 WSL 路径 - path_dir = path_dir.replace('\\', '/') - path_dir = path_dir.replace(GLOBAL_CONFIG['VSCODE_WEB_PATH']['windows_path'] , GLOBAL_CONFIG['VSCODE_WEB_PATH']['wsl_path']) - with open(config_path, 'w', encoding='utf-8') as f: - tmpd = {'user_id': user_id, 'course_id': course_id, 'chapter_id': chapter_id, 'path': path_dir} - json.dump(tmpd, f) - print('---------------------') - print(config_path) - return render_template('desktop.html', vscode_web_url=VSCODE_WEB_URL, user_id=user_id, course_id=course_id, chapter_id=chapter_id, workspace_path=path_dir) - -@app.route('/desktop_nouser//') -def desktop_nouser(course_id, chapter_id): - if 'user_id' not in session: - return redirect(url_for('login')) - user_id = session['user_id'] - username = uuid2username[user_id] - return redirect(url_for('desktop', user_id=username, course_id=course_id, chapter_id=chapter_id)) - -@app.route('/vscode_data', methods=['POST']) -def vscode_data(): - data = request.json - config = data['config'] - realtime_response(config,data) - print(f"Received data from VSCode: {data}") - return jsonify({"status": "success", "received": data}) - - - -''' -Login - -''' -users_list = UserList() -course_list = CourseList() - - -@app.route('/register') -def register(): - return render_template('register.html') - -@app.route('/register_teacher') -def register_teacher(): - return render_template('register_teacher.html') - -@app.route('/register_teacher_post', methods=['POST']) -def register_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password, teacher=True) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - -@app.route('/register_post', methods=['POST']) -def register_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - - -@app.route('/login') -def login(): - return render_template('login.html') - if 'user_id' not in session: - return render_template('login.html') - else: - return redirect(url_for('/')) - -@app.route('/login_post', methods=['POST']) -def login_post(): - # 获取请求的 JSON 数据 - data = request.get_json() - - username = data.get('username') - password = data.get('password') - - pswd = users_list.get_user_pswd(username) - - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/login_teacher_post', methods=['POST']) -def login_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - pswd = users_list.get_user_pswd(username) - is_teacher = users_list.get_user_is_teacher(username) - if is_teacher is None or is_teacher == False: - return jsonify({'success': False, 'message': '用户名不存在或非教师账号'}) - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/teacherboard') -@require_role(roles="teacher") -def teacherboard(): - return render_template('teacherboard.html') - - -@app.route('/logout') -def logout(): - session.pop('user_id', None) - return redirect(url_for('login')) - -@app.route('/get_session') -def get_session(): - user_session = session.get('user_id', 'default_session') - return jsonify({"session": user_session}) - - -''' -DashBoard -''' -user_id2UserClass = {} -@app.route('/dashboard') -@require_role -def dashboard(): - user_id = session['user_id'] - username = uuid2username[user_id] - if (user_id not in user_id2UserClass): - user_id2UserClass[user_id] = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - user_course_data = [] - for course_id in user_id2UserClass[user_id].select_course: - course_brief_info = course_list.get_course_brief_info(course_id, load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR)) - user_course_data.append(course_brief_info) - return render_template('dashboard.html',user_data = user_id2UserClass[user_id].to_json_without_dialog(), user_course_data = json.dumps(user_course_data)) - -''' -Course -''' - -@app.route('/course/') -@require_role -def course(course_id): - c = load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR) - return render_template('course.html', course_id=course_id, course_data=c) - -@app.route('/select_course', methods=['POST']) -@require_role -def select_course(): - user = user_id2UserClass[session['user_id']] - data = request.get_json() - course_id = data.get('course_id') - if course_id: - user.select_new_course(course_id, load_course_from_json(course_id, COURSE_DATA_DIR)) - return jsonify({'success': True, 'message': '课程选择成功'}) - - -@app.route('/') -@require_role -def home_index(): - selected_courses=[] - if ('user_id' in session): - if (session['user_id'] not in user_id2UserClass): return redirect(url_for('login')) - user = user_id2UserClass[session['user_id']] - for course_id in user.select_course: - selected_courses.append(course_id) - - return render_template('index.html', courses_data = course_list, selected_courses =selected_courses) - -# 一些app辅助函数,主要提供给Agent与数据库的交互能力 - -class MyFunction: - def save_chapter_memory(self, id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal): - print("-=-=-=-=-=-=-=-") - print(id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - username = uuid2username[id] - u = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - u.save_chapter_memory(course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - -app.my_function = MyFunction() -if __name__ == '__main__': - socketio.on_namespace(VSCodeNamespace('/vscode')) - socketio.on_namespace(AgentNamespace('/agent')) - socketio.run(app, host='0.0.0.0', port=5551, debug=False,allow_unsafe_werkzeug=True) - diff --git a/Html/runs/run_20250906-141209_g777ho/code/backboardManager.py b/Html/runs/run_20250906-141209_g777ho/code/backboardManager.py deleted file mode 100644 index 1777f8d..0000000 --- a/Html/runs/run_20250906-141209_g777ho/code/backboardManager.py +++ /dev/null @@ -1,80 +0,0 @@ - - - -import time -import os - -class Backboard: - def __init__(self, user_id, username, course_id, lesson_id, root_path): - self.user_id = user_id - self.username = username - self.course_id = course_id - self.lesson_id = lesson_id - self.root_path = root_path - self.create_time = time.time() - self.enter_chapter_time = time.time() - self.history = [] - self.file_tree = "[]" - self.active_file_path = "" - self.active_file_content = "" - self.pasted_file_path = "" - self.pasted_content = "" - - - def next_chapter(self): - self.enter_chapter_time = time.time() - - def get_info_prompt(self): - - five_history = "" - for h in self.history[-5:]: - five_history += h['type'] + "\n" + h.get('filePath', '') + "\n\n" - - endl = "\n" - return (f"###Global Info:###{endl}" - f"Here are some info about now user's IDE, refer to it when you need to handle some code.{endl}" - f"- User's total study time is {self.get_deltatime_mmss(self.create_time, time.time())}{endl}" - f"- User's current chapter study time is {self.get_deltatime_mmss(self.enter_chapter_time, time.time())}{endl}" - f"- Activated file path: {self.active_file_path}{endl}" - f"```{endl}" - f"{self.active_file_content[-10:]}{endl}" - f"```{endl}" - f"- Last five action:{five_history}{endl}" - f"- File tree: {self.file_tree}{endl}") - # f"- Activated file content (current editing 10 lines): {endl}" - def add_history(self, realtime_action): - if(realtime_action['type']=='config'):return - if len(self.history)!=0: - if (self.history[-1]['type']=='fileEdit'): - if(self.history[-1]['filePath'] == realtime_action['filePath']): - self.history[-1]['content'] = realtime_action['content'] - return - self.history.append(realtime_action) - - - def get_deltatime_mmss(self, start_time, end_time): - elapsed_time = end_time - start_time - hours = int(elapsed_time // 3600) - minutes = int((elapsed_time % 3600) // 60) - seconds = int(elapsed_time % 60) - return f"{hours:02d}:{minutes:02d}:{seconds:02d}" - - - def get_active_file_reletive_path(self): - relative_path = os.path.relpath(self.active_file_path, self.root_path) - return relative_path - - - -class BackBoardManager: - def __init__(self): - self.backboards = {} # user_id: Backboard - - def add_backboard(self, user_id, username, course_id, lesson_id, root_path): - self.backboards[user_id] = Backboard(user_id,username, course_id, lesson_id, root_path) - - def get_backboard(self, user_id) -> Backboard: - return self.backboards[user_id] - - - diff --git a/Html/runs/run_20250906-141209_g777ho/code/bootstrap.py b/Html/runs/run_20250906-141209_g777ho/code/bootstrap.py deleted file mode 100644 index bcb15ce..0000000 --- a/Html/runs/run_20250906-141209_g777ho/code/bootstrap.py +++ /dev/null @@ -1,31 +0,0 @@ -from pathlib import Path -import sys, os - -def bootstrap_paths(): - """ - 让 'AlgoriAgent'(位于 repo_root/AlgoriAgent)可被 import; - 并提供 STUDENT_WORKSPACE_ROOT 的默认值(repo_root/study)。 - 适配当前工厂位置:repo_root/Html/apps/__init__.py - """ - here = Path(__file__).resolve() - # repo_root = .../Html/apps/../../ => parents[2] - repo_root = here.parents[2] - - # 兜底:如果目录结构变化,尝试向上搜索包含 AlgoriAgent 的目录作为 repo_root - if not (repo_root / "AlgoriAgent").exists(): - for p in here.parents: - if (p / "AlgoriAgent").is_dir(): - repo_root = p - break - - # 确保仓库根在 sys.path(这样 'AlgoriAgent' 顶层包可被发现) - repo_root_str = str(repo_root) - if repo_root_str not in sys.path: - sys.path.insert(0, repo_root_str) - - # 可选:如果你还有其它顶层包,也可在此处继续插入 - - # 默认学习工作区目录(也可放到 config.ini / 环境变量覆盖) - os.environ.setdefault("STUDENT_WORKSPACE_ROOT", str(repo_root / "study")) - - return repo_root # 方便调试/日志 \ No newline at end of file diff --git a/Html/runs/run_20250906-141209_g777ho/code/wsgi.py b/Html/runs/run_20250906-141209_g777ho/code/wsgi.py deleted file mode 100644 index bbcbe5f..0000000 --- a/Html/runs/run_20250906-141209_g777ho/code/wsgi.py +++ /dev/null @@ -1,6 +0,0 @@ -# wsgi.py -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -# 提供一个可被 WSGI/进程管理器导入的 app 对象 -app = create_app() diff --git a/Html/runs/run_20250906-141209_g777ho/logging.chat b/Html/runs/run_20250906-141209_g777ho/logging.chat deleted file mode 100644 index e69de29..0000000 diff --git a/Html/runs/run_20250906-141209_g777ho/logging.log b/Html/runs/run_20250906-141209_g777ho/logging.log deleted file mode 100644 index 1ff4e81..0000000 --- a/Html/runs/run_20250906-141209_g777ho/logging.log +++ /dev/null @@ -1 +0,0 @@ -2025-09-06 14:12:16.009 | INFO | agentscope.models:read_model_configs:186 - Load configs for model wrapper: openai_cfg diff --git a/Html/runs/run_20250906-141216_d08zym/.config b/Html/runs/run_20250906-141216_d08zym/.config deleted file mode 100644 index 3445f9d..0000000 --- a/Html/runs/run_20250906-141216_d08zym/.config +++ /dev/null @@ -1,7 +0,0 @@ -{ - "project": "3Sas8M", - "name": "d08zym", - "run_id": "run_20250906-141216_d08zym", - "timestamp": "2025-09-06 14:12:16", - "pid": 16360 -} \ No newline at end of file diff --git a/Html/runs/run_20250906-141216_d08zym/agentscope.db b/Html/runs/run_20250906-141216_d08zym/agentscope.db deleted file mode 100644 index 417dfe775a0a6a8d3ad21bcb5915a2e71e0be111..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI(&u-H&90zcx$+|JI1&PBB{E>x*wyImD2`&i1$X0KQ$kH`UHFhD&S~EqY$=15l z&SM7Aw?In-4fbte*>zDT>BP|$ni z8qqZJgi=Dtgxn0dU6z8Z4DV}~4ZrxDAeG}cGv+s9T>V65-U)mj_zC;HaO9FyJRG&fC1Lw61&1 z@)`9#dvlX{RB2WEPE)0aKCgX{|YoDzS@6*x^gEXX&)8 zO=c<2W(GMGbY-_Nl2d7DO#m=G$hjzcjXI zHb&~RXFhGZcD>1{Tk{7~Fh2ZzKIA>*{3h^xO0&T6iTd)M9h^5es?wuEajst0NR+hs z$%Sdy7wKR>P(Xqe<$x|9wW;iJn~|Gg?i2H~`QCgjD<}|v00bZa0SG_<0uX=z1Rwwb z2>gM-yip{pQ)KSoP%PiCtSl#Cl2(LVV2J~fzT`=7@Ltl3#8#tPY3DHJB1)6t(7S~q zvDDDRu8bAKVe{IU^R~h`4q9nH5xgs+4)0CND>BSi#Qb8uGe61-3Irek0SG_<0uX=z z1Rwwb2tWV=|3cuFzN-Cnalp8v+oP?yMFIV`ZjFYFECv*A>Z?~q@((WpWWWDw=2s$L kC=h@E1Rwwb2tWV=5P$##AOHaf{Qm;iHNC7U{{t|-1M%Eaxc~qF diff --git a/Html/runs/run_20250906-141216_d08zym/code/app.py b/Html/runs/run_20250906-141216_d08zym/code/app.py deleted file mode 100644 index b761bd2..0000000 --- a/Html/runs/run_20250906-141216_d08zym/code/app.py +++ /dev/null @@ -1,20 +0,0 @@ -# app.py 0.1.1 rise to factory mode -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -from apps.extensions import socketio - -# 工厂创建 app,工厂里已经做了:加载配置/注册蓝图/注册 namespaces -app = create_app() - -if __name__ == "__main__": - # 仅本地开发用;生产不要用 werkzeug 自带的开发服务器 - socketio.run( - app, - host="0.0.0.0", - port=5551, - debug=False, # 开发期打开 - allow_unsafe_werkzeug=True # 避免 dev server 的安全限制提示 - ) - - diff --git a/Html/runs/run_20250906-141216_d08zym/code/app_back.py b/Html/runs/run_20250906-141216_d08zym/code/app_back.py deleted file mode 100644 index 246853c..0000000 --- a/Html/runs/run_20250906-141216_d08zym/code/app_back.py +++ /dev/null @@ -1,480 +0,0 @@ -from bootstrap import bootstrap_paths -bootstrap_paths() -from functools import wraps -from flask import Flask, redirect, session, request, jsonify, render_template, send_from_directory, url_for -from flask_cors import CORS -from flask_socketio import SocketIO, join_room, emit, Namespace -import markdown -import os -import uuid -import shutil -import sys -import json -from apps.auth.decorators import require_role -parent_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) -sys.path.insert(0, parent_dir) -student_workspace_root_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../study')) -current_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '.')) -sys.path.insert(0, current_dir) -from AlgoriAgent.projects.algoriAgent.agent_manager import AgentManager - - -import configparser - -from db.user_list import UserList -from db.user import User, load_user_from_json, create_user_json -from db.course_list import CourseList -from db.course import Course, load_course_from_json -GLOBAL_CONFIG = configparser.ConfigParser() -GLOBAL_CONFIG.read('config.ini') -VSCODE_WEB_URL = GLOBAL_CONFIG['VSCODE_WEB']['url'] -USER_DATA_DIR = GLOBAL_CONFIG['USER_DATA']['dir'] -COURSE_DATA_DIR = GLOBAL_CONFIG['COURSE_DATA']['dir'] - -app = Flask(__name__) -socketio = SocketIO(app, cors_allowed_origins="*",ping_timeout=60, ping_interval=5) -# socketio = SocketIO(app, cors_allowed_origins="http://localhost:9888") # 设置跨域支持 -import logging -app.secret_key = 'cakebaker' -app.logger.setLevel(logging.DEBUG) -# 配置 CORS -CORS(app, resources={r"/*": {"origins": VSCODE_WEB_URL},}, supports_credentials=True) - - -userid_recorder = {} # user_id&path -> session['user_id'] - -''' -Backboard -''' -from backboardManager import BackBoardManager, Backboard - -backboard_manager = BackBoardManager() -uuid2username = {} -username2uuid = {} - - - -# 定义命名空间:用于和 VSCode 插件交流 -class VSCodeNamespace(Namespace): - def on_login(self,data): - print("VSCode client connected") - print(data) - dataconfig = data['config'] - user_id = dataconfig.get('user_id') - path = dataconfig.get('path') - course_id = dataconfig.get('course_id') - lesson_id = dataconfig.get('chapter_id') - print(f"User {user_id} connected with path: {path}") - useruuid = username2uuid[user_id] - join_room(useruuid, namespace='/vscode') - if backboard_manager.get_backboard(useruuid) == None: - backboard_manager.add_backboard(useruuid,user_id, course_id, lesson_id, path) - - - def on_message(self, data): - print(f"Received from VSCode client: {data}") - dataconfig = data['config'] - realtime_response(dataconfig, data) - # emit('response', {'message': 'Config data received and connection established'}) - def on_disconnect(self, data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - -def realtime_response(config, realtime_action): - user_id = config['user_id'] - folder_path = config['path'] - useruuid = username2uuid[user_id] - bb = backboard_manager.get_backboard(useruuid) - assert type(bb) == Backboard - - bb.add_history(realtime_action) - - if realtime_action['type'] == 'workspaceFolders': - bb.file_tree = realtime_action['fileTree'] - - if realtime_action['type'] == 'activeFile': - file_path = realtime_action['filePath'] - assert type(file_path) == str - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - if realtime_action['type'] == 'paste': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.pasted_file_path = file_path - bb.pasted_content = realtime_action['content'] - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - if realtime_action['type'] == 'fileEdit': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - - - print("config"+str(config)) - print("realtime_action"+str(realtime_action)) - pass - - -''' -Agent and Chat -''' -agent_manager = AgentManager(app = app, socketio = socketio) -user_threads = {} -import threading -from concurrent.futures import ThreadPoolExecutor, as_completed - -# 初始化线程池 -executor = ThreadPoolExecutor(max_workers=10) -class AgentNamespace(Namespace): - def on_login(self, data): - data = json.loads(data) - user = data['username'] - course_id = data['course_id'] - chapter_id = data['chapter_id'] - user_uuid = username2uuid[user] - session['user_id'] = user_uuid - print(f'User connected with session user_id: {user_uuid}') - # 从markdown、markdown_prompts、score_prompts中各读取数据folder.md并进行new_agent - with open(f'books/markdown/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fmd,\ - open(f'books/markdown_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8')as fmdp,\ - open(f'books/score_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fsp: - markdown = fmd.read() - markdown_prompts = fmdp.read() - score_prompts = fsp.read() - user_uuid, agent = agent_manager.new_agent(course_id, chapter_id, markdown, markdown_prompts, score_prompts, id=user_uuid, - root_path=f'../../study/{user}/{course_id}/{chapter_id}') - print(user_uuid) - join_room(user_uuid, namespace='/agent') # 将该用户加入以user_id为名的room - backboard_manager.add_backboard(user_uuid, user, course_id, chapter_id, root_path=f'../../study/{user}/{course_id}/{chapter_id}') - - def on_language(self, language): - id = session.get('user_id') - agent_manager.change_language(id, language) - - def on_message(self, data): - print(f"Message from client: {data}") - id = session.get('user_id') - if (type(data)==str): - data = json.loads(data) - print(id) - if data['type'] == 'text': - res = agent_manager.invoke(id, data['data'], backboard_manager.get_backboard(id).get_info_prompt()) - print('=*='*20) - print(res.content) - reply = f"{res.content['speak']}" - with app.app_context(): - emit('message',reply, room=id, namespace='/agent') - emit('request_function',res.content['function'], room=id, namespace='/agent') - - if data['type'] == 'function': - agent_manager.function_call(id, data['data']) - - def on_initiative(self,data): - print("User active function call") - user_id = session['user_id'] - if data['name'] == 'sample_judge': - agent_manager.sample_judge(user_id, backboard_manager.get_backboard(user_id)) - if data['name'] == 'judge': - agent_manager.judge(user_id, backboard_manager.get_backboard(user_id)) - - - - def on_disconnect(self,data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - - -''' -Markdown to HTML -''' -# 配置文件路径 -MARKDOWN_DIR = 'books/markdown' # 存放 markdown 文件的文件夹 -STATIC_DIR = 'static' # 存放生成的 HTML 和图片资源的文件夹 -IMAGE_DIR = 'image' # 图片资源相对于 markdown 的位置 - - - -@app.route('/--markdown', methods=['GET']) -def convert_md(course_id, filename): - md_file_path = os.path.join(MARKDOWN_DIR,course_id, f'{filename}.md') - - if not os.path.exists(md_file_path): - return jsonify({'error': 'Markdown file not found'}), 404 - - # 读取 markdown 文件内容 - with open(md_file_path, 'r', encoding='utf-8') as file: - md_content = file.read() - - # 将 markdown 转换为 HTML - html_content = markdown.markdown(md_content) - # 插入 CSS 样式,限制图片最大宽度为 100%,高度自动调整 - html_with_styles = f""" - - - - - - - {html_content} - - - """ - # 保存 HTML 文件到 static 文件夹 - html_output_path = os.path.join(STATIC_DIR, f'{filename}.html') - with open(html_output_path, 'w', encoding='utf-8') as html_file: - html_file.write(html_with_styles) - - # 处理图片资源,将 image/xxx 文件夹拷贝到 static/image/xxx - image_source_dir = os.path.join(MARKDOWN_DIR,course_id, IMAGE_DIR, filename) - image_target_dir = os.path.join(STATIC_DIR, IMAGE_DIR, filename) - print(f"Copying image resources from {image_source_dir} to {image_target_dir}") - if os.path.exists(image_source_dir): - # 确保 static/image/xxx 目录存在 - if not os.path.exists(image_target_dir): - os.makedirs(image_target_dir) - - # 拷贝图片资源 - for image_file in os.listdir(image_source_dir): - full_image_file_path = os.path.join(image_source_dir, image_file) - if os.path.isfile(full_image_file_path): - shutil.copy(full_image_file_path, image_target_dir) - - return jsonify({'html_url': f'/static/{filename}.html'}) - -# 静态文件(HTML 和图片资源)的访问 -@app.route('/static/') -def serve_static(filename): - return send_from_directory(STATIC_DIR, filename) - - -''' -Vscode -''' -@app.route('/desktop///') -def desktop(user_id, course_id, chapter_id): - if 'user_id' not in session: - # return redirect(url_for('login')) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ user_id + "uuid is"+ session['user_id']) - username2uuid[user_id] = session['user_id'] - uuid2username[session['user_id']] = user_id - userid_recorder[user_id+'&'+course_id] = session['user_id'] - - # 在学习目录下创建一个名为 user_id_path 的文件夹 - path_dir = os.path.join(student_workspace_root_path, user_id, course_id,chapter_id) - os.makedirs(path_dir, exist_ok=True) - # 在此文件夹内部创建一个.config文件,并写入 user_id=user_id\n path=path - config_path = os.path.join(path_dir, '.config') - if GLOBAL_CONFIG['VSCODE_WEB_PATH']['is_wsl']: # 如果是在 WSL 中运行,则将路径转换为 WSL 路径 - path_dir = path_dir.replace('\\', '/') - path_dir = path_dir.replace(GLOBAL_CONFIG['VSCODE_WEB_PATH']['windows_path'] , GLOBAL_CONFIG['VSCODE_WEB_PATH']['wsl_path']) - with open(config_path, 'w', encoding='utf-8') as f: - tmpd = {'user_id': user_id, 'course_id': course_id, 'chapter_id': chapter_id, 'path': path_dir} - json.dump(tmpd, f) - print('---------------------') - print(config_path) - return render_template('desktop.html', vscode_web_url=VSCODE_WEB_URL, user_id=user_id, course_id=course_id, chapter_id=chapter_id, workspace_path=path_dir) - -@app.route('/desktop_nouser//') -def desktop_nouser(course_id, chapter_id): - if 'user_id' not in session: - return redirect(url_for('login')) - user_id = session['user_id'] - username = uuid2username[user_id] - return redirect(url_for('desktop', user_id=username, course_id=course_id, chapter_id=chapter_id)) - -@app.route('/vscode_data', methods=['POST']) -def vscode_data(): - data = request.json - config = data['config'] - realtime_response(config,data) - print(f"Received data from VSCode: {data}") - return jsonify({"status": "success", "received": data}) - - - -''' -Login - -''' -users_list = UserList() -course_list = CourseList() - - -@app.route('/register') -def register(): - return render_template('register.html') - -@app.route('/register_teacher') -def register_teacher(): - return render_template('register_teacher.html') - -@app.route('/register_teacher_post', methods=['POST']) -def register_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password, teacher=True) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - -@app.route('/register_post', methods=['POST']) -def register_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - - -@app.route('/login') -def login(): - return render_template('login.html') - if 'user_id' not in session: - return render_template('login.html') - else: - return redirect(url_for('/')) - -@app.route('/login_post', methods=['POST']) -def login_post(): - # 获取请求的 JSON 数据 - data = request.get_json() - - username = data.get('username') - password = data.get('password') - - pswd = users_list.get_user_pswd(username) - - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/login_teacher_post', methods=['POST']) -def login_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - pswd = users_list.get_user_pswd(username) - is_teacher = users_list.get_user_is_teacher(username) - if is_teacher is None or is_teacher == False: - return jsonify({'success': False, 'message': '用户名不存在或非教师账号'}) - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/teacherboard') -@require_role(roles="teacher") -def teacherboard(): - return render_template('teacherboard.html') - - -@app.route('/logout') -def logout(): - session.pop('user_id', None) - return redirect(url_for('login')) - -@app.route('/get_session') -def get_session(): - user_session = session.get('user_id', 'default_session') - return jsonify({"session": user_session}) - - -''' -DashBoard -''' -user_id2UserClass = {} -@app.route('/dashboard') -@require_role -def dashboard(): - user_id = session['user_id'] - username = uuid2username[user_id] - if (user_id not in user_id2UserClass): - user_id2UserClass[user_id] = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - user_course_data = [] - for course_id in user_id2UserClass[user_id].select_course: - course_brief_info = course_list.get_course_brief_info(course_id, load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR)) - user_course_data.append(course_brief_info) - return render_template('dashboard.html',user_data = user_id2UserClass[user_id].to_json_without_dialog(), user_course_data = json.dumps(user_course_data)) - -''' -Course -''' - -@app.route('/course/') -@require_role -def course(course_id): - c = load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR) - return render_template('course.html', course_id=course_id, course_data=c) - -@app.route('/select_course', methods=['POST']) -@require_role -def select_course(): - user = user_id2UserClass[session['user_id']] - data = request.get_json() - course_id = data.get('course_id') - if course_id: - user.select_new_course(course_id, load_course_from_json(course_id, COURSE_DATA_DIR)) - return jsonify({'success': True, 'message': '课程选择成功'}) - - -@app.route('/') -@require_role -def home_index(): - selected_courses=[] - if ('user_id' in session): - if (session['user_id'] not in user_id2UserClass): return redirect(url_for('login')) - user = user_id2UserClass[session['user_id']] - for course_id in user.select_course: - selected_courses.append(course_id) - - return render_template('index.html', courses_data = course_list, selected_courses =selected_courses) - -# 一些app辅助函数,主要提供给Agent与数据库的交互能力 - -class MyFunction: - def save_chapter_memory(self, id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal): - print("-=-=-=-=-=-=-=-") - print(id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - username = uuid2username[id] - u = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - u.save_chapter_memory(course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - -app.my_function = MyFunction() -if __name__ == '__main__': - socketio.on_namespace(VSCodeNamespace('/vscode')) - socketio.on_namespace(AgentNamespace('/agent')) - socketio.run(app, host='0.0.0.0', port=5551, debug=False,allow_unsafe_werkzeug=True) - diff --git a/Html/runs/run_20250906-141216_d08zym/code/backboardManager.py b/Html/runs/run_20250906-141216_d08zym/code/backboardManager.py deleted file mode 100644 index 1777f8d..0000000 --- a/Html/runs/run_20250906-141216_d08zym/code/backboardManager.py +++ /dev/null @@ -1,80 +0,0 @@ - - - -import time -import os - -class Backboard: - def __init__(self, user_id, username, course_id, lesson_id, root_path): - self.user_id = user_id - self.username = username - self.course_id = course_id - self.lesson_id = lesson_id - self.root_path = root_path - self.create_time = time.time() - self.enter_chapter_time = time.time() - self.history = [] - self.file_tree = "[]" - self.active_file_path = "" - self.active_file_content = "" - self.pasted_file_path = "" - self.pasted_content = "" - - - def next_chapter(self): - self.enter_chapter_time = time.time() - - def get_info_prompt(self): - - five_history = "" - for h in self.history[-5:]: - five_history += h['type'] + "\n" + h.get('filePath', '') + "\n\n" - - endl = "\n" - return (f"###Global Info:###{endl}" - f"Here are some info about now user's IDE, refer to it when you need to handle some code.{endl}" - f"- User's total study time is {self.get_deltatime_mmss(self.create_time, time.time())}{endl}" - f"- User's current chapter study time is {self.get_deltatime_mmss(self.enter_chapter_time, time.time())}{endl}" - f"- Activated file path: {self.active_file_path}{endl}" - f"```{endl}" - f"{self.active_file_content[-10:]}{endl}" - f"```{endl}" - f"- Last five action:{five_history}{endl}" - f"- File tree: {self.file_tree}{endl}") - # f"- Activated file content (current editing 10 lines): {endl}" - def add_history(self, realtime_action): - if(realtime_action['type']=='config'):return - if len(self.history)!=0: - if (self.history[-1]['type']=='fileEdit'): - if(self.history[-1]['filePath'] == realtime_action['filePath']): - self.history[-1]['content'] = realtime_action['content'] - return - self.history.append(realtime_action) - - - def get_deltatime_mmss(self, start_time, end_time): - elapsed_time = end_time - start_time - hours = int(elapsed_time // 3600) - minutes = int((elapsed_time % 3600) // 60) - seconds = int(elapsed_time % 60) - return f"{hours:02d}:{minutes:02d}:{seconds:02d}" - - - def get_active_file_reletive_path(self): - relative_path = os.path.relpath(self.active_file_path, self.root_path) - return relative_path - - - -class BackBoardManager: - def __init__(self): - self.backboards = {} # user_id: Backboard - - def add_backboard(self, user_id, username, course_id, lesson_id, root_path): - self.backboards[user_id] = Backboard(user_id,username, course_id, lesson_id, root_path) - - def get_backboard(self, user_id) -> Backboard: - return self.backboards[user_id] - - - diff --git a/Html/runs/run_20250906-141216_d08zym/code/bootstrap.py b/Html/runs/run_20250906-141216_d08zym/code/bootstrap.py deleted file mode 100644 index bcb15ce..0000000 --- a/Html/runs/run_20250906-141216_d08zym/code/bootstrap.py +++ /dev/null @@ -1,31 +0,0 @@ -from pathlib import Path -import sys, os - -def bootstrap_paths(): - """ - 让 'AlgoriAgent'(位于 repo_root/AlgoriAgent)可被 import; - 并提供 STUDENT_WORKSPACE_ROOT 的默认值(repo_root/study)。 - 适配当前工厂位置:repo_root/Html/apps/__init__.py - """ - here = Path(__file__).resolve() - # repo_root = .../Html/apps/../../ => parents[2] - repo_root = here.parents[2] - - # 兜底:如果目录结构变化,尝试向上搜索包含 AlgoriAgent 的目录作为 repo_root - if not (repo_root / "AlgoriAgent").exists(): - for p in here.parents: - if (p / "AlgoriAgent").is_dir(): - repo_root = p - break - - # 确保仓库根在 sys.path(这样 'AlgoriAgent' 顶层包可被发现) - repo_root_str = str(repo_root) - if repo_root_str not in sys.path: - sys.path.insert(0, repo_root_str) - - # 可选:如果你还有其它顶层包,也可在此处继续插入 - - # 默认学习工作区目录(也可放到 config.ini / 环境变量覆盖) - os.environ.setdefault("STUDENT_WORKSPACE_ROOT", str(repo_root / "study")) - - return repo_root # 方便调试/日志 \ No newline at end of file diff --git a/Html/runs/run_20250906-141216_d08zym/code/wsgi.py b/Html/runs/run_20250906-141216_d08zym/code/wsgi.py deleted file mode 100644 index bbcbe5f..0000000 --- a/Html/runs/run_20250906-141216_d08zym/code/wsgi.py +++ /dev/null @@ -1,6 +0,0 @@ -# wsgi.py -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -# 提供一个可被 WSGI/进程管理器导入的 app 对象 -app = create_app() diff --git a/Html/runs/run_20250906-141216_d08zym/logging.chat b/Html/runs/run_20250906-141216_d08zym/logging.chat deleted file mode 100644 index e69de29..0000000 diff --git a/Html/runs/run_20250906-141216_d08zym/logging.log b/Html/runs/run_20250906-141216_d08zym/logging.log deleted file mode 100644 index 5c73618..0000000 --- a/Html/runs/run_20250906-141216_d08zym/logging.log +++ /dev/null @@ -1,13 +0,0 @@ -2025-09-06 14:12:22.413 | INFO | agentscope.models:read_model_configs:186 - Load configs for model wrapper: openai_cfg -2025-09-06 14:13:57.943 | INFO | agentscope.models.model:__init__:201 - Initialize model by configuration [openai_cfg] -2025-09-06 14:13:57.979 | WARNING | agentscope.models.openai_model:__init__:83 - fail to get max_length for gpt-4.1-nano: 'Model [gpt-4.1-nano] not found in OPENAI_MAX_LENGTH. The last updated date is 20231212' -2025-09-06 14:13:57.980 | INFO | agentscope.utils.monitor:register_budget:609 - set budget None to gpt-4.1-nano -2025-09-06 14:13:57.980 | WARNING | agentscope.utils.monitor:register_budget:639 - Calculate budgets for model [gpt-4.1-nano] is not supported -2025-09-06 14:13:57.981 | INFO | agentscope.utils.monitor:register:417 - Register metric [gpt-4.1-nano.call_counter] to SqliteMonitor with unit [times] and quota [None] -2025-09-06 14:13:57.988 | INFO | agentscope.utils.monitor:register:417 - Register metric [gpt-4.1-nano.prompt_tokens] to SqliteMonitor with unit [token] and quota [None] -2025-09-06 14:13:57.994 | INFO | agentscope.utils.monitor:register:417 - Register metric [gpt-4.1-nano.completion_tokens] to SqliteMonitor with unit [token] and quota [None] -2025-09-06 14:13:58.000 | INFO | agentscope.utils.monitor:register:417 - Register metric [gpt-4.1-nano.total_tokens] to SqliteMonitor with unit [token] and quota [None] -2025-09-06 14:14:12.146 | INFO | agentscope.models.model:__init__:201 - Initialize model by configuration [openai_cfg] -2025-09-06 14:14:12.183 | WARNING | agentscope.models.openai_model:__init__:83 - fail to get max_length for gpt-4.1-nano: 'Model [gpt-4.1-nano] not found in OPENAI_MAX_LENGTH. The last updated date is 20231212' -2025-09-06 14:14:12.184 | INFO | agentscope.utils.monitor:register_budget:609 - set budget None to gpt-4.1-nano -2025-09-06 14:14:12.185 | WARNING | agentscope.utils.monitor:register_budget:639 - Calculate budgets for model [gpt-4.1-nano] is not supported diff --git a/Html/runs/run_20250906-141430_i7aihi/.config b/Html/runs/run_20250906-141430_i7aihi/.config deleted file mode 100644 index 5ef14bb..0000000 --- a/Html/runs/run_20250906-141430_i7aihi/.config +++ /dev/null @@ -1,7 +0,0 @@ -{ - "project": "OKkTxC", - "name": "i7aihi", - "run_id": "run_20250906-141430_i7aihi", - "timestamp": "2025-09-06 14:14:30", - "pid": 17047 -} \ No newline at end of file diff --git a/Html/runs/run_20250906-141430_i7aihi/agentscope.db b/Html/runs/run_20250906-141430_i7aihi/agentscope.db deleted file mode 100644 index 417dfe775a0a6a8d3ad21bcb5915a2e71e0be111..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI(&u-H&90zcx$+|JI1&PBB{E>x*wyImD2`&i1$X0KQ$kH`UHFhD&S~EqY$=15l z&SM7Aw?In-4fbte*>zDT>BP|$ni z8qqZJgi=Dtgxn0dU6z8Z4DV}~4ZrxDAeG}cGv+s9T>V65-U)mj_zC;HaO9FyJRG&fC1Lw61&1 z@)`9#dvlX{RB2WEPE)0aKCgX{|YoDzS@6*x^gEXX&)8 zO=c<2W(GMGbY-_Nl2d7DO#m=G$hjzcjXI zHb&~RXFhGZcD>1{Tk{7~Fh2ZzKIA>*{3h^xO0&T6iTd)M9h^5es?wuEajst0NR+hs z$%Sdy7wKR>P(Xqe<$x|9wW;iJn~|Gg?i2H~`QCgjD<}|v00bZa0SG_<0uX=z1Rwwb z2>gM-yip{pQ)KSoP%PiCtSl#Cl2(LVV2J~fzT`=7@Ltl3#8#tPY3DHJB1)6t(7S~q zvDDDRu8bAKVe{IU^R~h`4q9nH5xgs+4)0CND>BSi#Qb8uGe61-3Irek0SG_<0uX=z z1Rwwb2tWV=|3cuFzN-Cnalp8v+oP?yMFIV`ZjFYFECv*A>Z?~q@((WpWWWDw=2s$L kC=h@E1Rwwb2tWV=5P$##AOHaf{Qm;iHNC7U{{t|-1M%Eaxc~qF diff --git a/Html/runs/run_20250906-141430_i7aihi/code/app.py b/Html/runs/run_20250906-141430_i7aihi/code/app.py deleted file mode 100644 index b761bd2..0000000 --- a/Html/runs/run_20250906-141430_i7aihi/code/app.py +++ /dev/null @@ -1,20 +0,0 @@ -# app.py 0.1.1 rise to factory mode -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -from apps.extensions import socketio - -# 工厂创建 app,工厂里已经做了:加载配置/注册蓝图/注册 namespaces -app = create_app() - -if __name__ == "__main__": - # 仅本地开发用;生产不要用 werkzeug 自带的开发服务器 - socketio.run( - app, - host="0.0.0.0", - port=5551, - debug=False, # 开发期打开 - allow_unsafe_werkzeug=True # 避免 dev server 的安全限制提示 - ) - - diff --git a/Html/runs/run_20250906-141430_i7aihi/code/app_back.py b/Html/runs/run_20250906-141430_i7aihi/code/app_back.py deleted file mode 100644 index 246853c..0000000 --- a/Html/runs/run_20250906-141430_i7aihi/code/app_back.py +++ /dev/null @@ -1,480 +0,0 @@ -from bootstrap import bootstrap_paths -bootstrap_paths() -from functools import wraps -from flask import Flask, redirect, session, request, jsonify, render_template, send_from_directory, url_for -from flask_cors import CORS -from flask_socketio import SocketIO, join_room, emit, Namespace -import markdown -import os -import uuid -import shutil -import sys -import json -from apps.auth.decorators import require_role -parent_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) -sys.path.insert(0, parent_dir) -student_workspace_root_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../study')) -current_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '.')) -sys.path.insert(0, current_dir) -from AlgoriAgent.projects.algoriAgent.agent_manager import AgentManager - - -import configparser - -from db.user_list import UserList -from db.user import User, load_user_from_json, create_user_json -from db.course_list import CourseList -from db.course import Course, load_course_from_json -GLOBAL_CONFIG = configparser.ConfigParser() -GLOBAL_CONFIG.read('config.ini') -VSCODE_WEB_URL = GLOBAL_CONFIG['VSCODE_WEB']['url'] -USER_DATA_DIR = GLOBAL_CONFIG['USER_DATA']['dir'] -COURSE_DATA_DIR = GLOBAL_CONFIG['COURSE_DATA']['dir'] - -app = Flask(__name__) -socketio = SocketIO(app, cors_allowed_origins="*",ping_timeout=60, ping_interval=5) -# socketio = SocketIO(app, cors_allowed_origins="http://localhost:9888") # 设置跨域支持 -import logging -app.secret_key = 'cakebaker' -app.logger.setLevel(logging.DEBUG) -# 配置 CORS -CORS(app, resources={r"/*": {"origins": VSCODE_WEB_URL},}, supports_credentials=True) - - -userid_recorder = {} # user_id&path -> session['user_id'] - -''' -Backboard -''' -from backboardManager import BackBoardManager, Backboard - -backboard_manager = BackBoardManager() -uuid2username = {} -username2uuid = {} - - - -# 定义命名空间:用于和 VSCode 插件交流 -class VSCodeNamespace(Namespace): - def on_login(self,data): - print("VSCode client connected") - print(data) - dataconfig = data['config'] - user_id = dataconfig.get('user_id') - path = dataconfig.get('path') - course_id = dataconfig.get('course_id') - lesson_id = dataconfig.get('chapter_id') - print(f"User {user_id} connected with path: {path}") - useruuid = username2uuid[user_id] - join_room(useruuid, namespace='/vscode') - if backboard_manager.get_backboard(useruuid) == None: - backboard_manager.add_backboard(useruuid,user_id, course_id, lesson_id, path) - - - def on_message(self, data): - print(f"Received from VSCode client: {data}") - dataconfig = data['config'] - realtime_response(dataconfig, data) - # emit('response', {'message': 'Config data received and connection established'}) - def on_disconnect(self, data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - -def realtime_response(config, realtime_action): - user_id = config['user_id'] - folder_path = config['path'] - useruuid = username2uuid[user_id] - bb = backboard_manager.get_backboard(useruuid) - assert type(bb) == Backboard - - bb.add_history(realtime_action) - - if realtime_action['type'] == 'workspaceFolders': - bb.file_tree = realtime_action['fileTree'] - - if realtime_action['type'] == 'activeFile': - file_path = realtime_action['filePath'] - assert type(file_path) == str - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - if realtime_action['type'] == 'paste': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.pasted_file_path = file_path - bb.pasted_content = realtime_action['content'] - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - if realtime_action['type'] == 'fileEdit': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - - - print("config"+str(config)) - print("realtime_action"+str(realtime_action)) - pass - - -''' -Agent and Chat -''' -agent_manager = AgentManager(app = app, socketio = socketio) -user_threads = {} -import threading -from concurrent.futures import ThreadPoolExecutor, as_completed - -# 初始化线程池 -executor = ThreadPoolExecutor(max_workers=10) -class AgentNamespace(Namespace): - def on_login(self, data): - data = json.loads(data) - user = data['username'] - course_id = data['course_id'] - chapter_id = data['chapter_id'] - user_uuid = username2uuid[user] - session['user_id'] = user_uuid - print(f'User connected with session user_id: {user_uuid}') - # 从markdown、markdown_prompts、score_prompts中各读取数据folder.md并进行new_agent - with open(f'books/markdown/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fmd,\ - open(f'books/markdown_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8')as fmdp,\ - open(f'books/score_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fsp: - markdown = fmd.read() - markdown_prompts = fmdp.read() - score_prompts = fsp.read() - user_uuid, agent = agent_manager.new_agent(course_id, chapter_id, markdown, markdown_prompts, score_prompts, id=user_uuid, - root_path=f'../../study/{user}/{course_id}/{chapter_id}') - print(user_uuid) - join_room(user_uuid, namespace='/agent') # 将该用户加入以user_id为名的room - backboard_manager.add_backboard(user_uuid, user, course_id, chapter_id, root_path=f'../../study/{user}/{course_id}/{chapter_id}') - - def on_language(self, language): - id = session.get('user_id') - agent_manager.change_language(id, language) - - def on_message(self, data): - print(f"Message from client: {data}") - id = session.get('user_id') - if (type(data)==str): - data = json.loads(data) - print(id) - if data['type'] == 'text': - res = agent_manager.invoke(id, data['data'], backboard_manager.get_backboard(id).get_info_prompt()) - print('=*='*20) - print(res.content) - reply = f"{res.content['speak']}" - with app.app_context(): - emit('message',reply, room=id, namespace='/agent') - emit('request_function',res.content['function'], room=id, namespace='/agent') - - if data['type'] == 'function': - agent_manager.function_call(id, data['data']) - - def on_initiative(self,data): - print("User active function call") - user_id = session['user_id'] - if data['name'] == 'sample_judge': - agent_manager.sample_judge(user_id, backboard_manager.get_backboard(user_id)) - if data['name'] == 'judge': - agent_manager.judge(user_id, backboard_manager.get_backboard(user_id)) - - - - def on_disconnect(self,data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - - -''' -Markdown to HTML -''' -# 配置文件路径 -MARKDOWN_DIR = 'books/markdown' # 存放 markdown 文件的文件夹 -STATIC_DIR = 'static' # 存放生成的 HTML 和图片资源的文件夹 -IMAGE_DIR = 'image' # 图片资源相对于 markdown 的位置 - - - -@app.route('/--markdown', methods=['GET']) -def convert_md(course_id, filename): - md_file_path = os.path.join(MARKDOWN_DIR,course_id, f'{filename}.md') - - if not os.path.exists(md_file_path): - return jsonify({'error': 'Markdown file not found'}), 404 - - # 读取 markdown 文件内容 - with open(md_file_path, 'r', encoding='utf-8') as file: - md_content = file.read() - - # 将 markdown 转换为 HTML - html_content = markdown.markdown(md_content) - # 插入 CSS 样式,限制图片最大宽度为 100%,高度自动调整 - html_with_styles = f""" - - - - - - - {html_content} - - - """ - # 保存 HTML 文件到 static 文件夹 - html_output_path = os.path.join(STATIC_DIR, f'{filename}.html') - with open(html_output_path, 'w', encoding='utf-8') as html_file: - html_file.write(html_with_styles) - - # 处理图片资源,将 image/xxx 文件夹拷贝到 static/image/xxx - image_source_dir = os.path.join(MARKDOWN_DIR,course_id, IMAGE_DIR, filename) - image_target_dir = os.path.join(STATIC_DIR, IMAGE_DIR, filename) - print(f"Copying image resources from {image_source_dir} to {image_target_dir}") - if os.path.exists(image_source_dir): - # 确保 static/image/xxx 目录存在 - if not os.path.exists(image_target_dir): - os.makedirs(image_target_dir) - - # 拷贝图片资源 - for image_file in os.listdir(image_source_dir): - full_image_file_path = os.path.join(image_source_dir, image_file) - if os.path.isfile(full_image_file_path): - shutil.copy(full_image_file_path, image_target_dir) - - return jsonify({'html_url': f'/static/{filename}.html'}) - -# 静态文件(HTML 和图片资源)的访问 -@app.route('/static/') -def serve_static(filename): - return send_from_directory(STATIC_DIR, filename) - - -''' -Vscode -''' -@app.route('/desktop///') -def desktop(user_id, course_id, chapter_id): - if 'user_id' not in session: - # return redirect(url_for('login')) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ user_id + "uuid is"+ session['user_id']) - username2uuid[user_id] = session['user_id'] - uuid2username[session['user_id']] = user_id - userid_recorder[user_id+'&'+course_id] = session['user_id'] - - # 在学习目录下创建一个名为 user_id_path 的文件夹 - path_dir = os.path.join(student_workspace_root_path, user_id, course_id,chapter_id) - os.makedirs(path_dir, exist_ok=True) - # 在此文件夹内部创建一个.config文件,并写入 user_id=user_id\n path=path - config_path = os.path.join(path_dir, '.config') - if GLOBAL_CONFIG['VSCODE_WEB_PATH']['is_wsl']: # 如果是在 WSL 中运行,则将路径转换为 WSL 路径 - path_dir = path_dir.replace('\\', '/') - path_dir = path_dir.replace(GLOBAL_CONFIG['VSCODE_WEB_PATH']['windows_path'] , GLOBAL_CONFIG['VSCODE_WEB_PATH']['wsl_path']) - with open(config_path, 'w', encoding='utf-8') as f: - tmpd = {'user_id': user_id, 'course_id': course_id, 'chapter_id': chapter_id, 'path': path_dir} - json.dump(tmpd, f) - print('---------------------') - print(config_path) - return render_template('desktop.html', vscode_web_url=VSCODE_WEB_URL, user_id=user_id, course_id=course_id, chapter_id=chapter_id, workspace_path=path_dir) - -@app.route('/desktop_nouser//') -def desktop_nouser(course_id, chapter_id): - if 'user_id' not in session: - return redirect(url_for('login')) - user_id = session['user_id'] - username = uuid2username[user_id] - return redirect(url_for('desktop', user_id=username, course_id=course_id, chapter_id=chapter_id)) - -@app.route('/vscode_data', methods=['POST']) -def vscode_data(): - data = request.json - config = data['config'] - realtime_response(config,data) - print(f"Received data from VSCode: {data}") - return jsonify({"status": "success", "received": data}) - - - -''' -Login - -''' -users_list = UserList() -course_list = CourseList() - - -@app.route('/register') -def register(): - return render_template('register.html') - -@app.route('/register_teacher') -def register_teacher(): - return render_template('register_teacher.html') - -@app.route('/register_teacher_post', methods=['POST']) -def register_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password, teacher=True) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - -@app.route('/register_post', methods=['POST']) -def register_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - - -@app.route('/login') -def login(): - return render_template('login.html') - if 'user_id' not in session: - return render_template('login.html') - else: - return redirect(url_for('/')) - -@app.route('/login_post', methods=['POST']) -def login_post(): - # 获取请求的 JSON 数据 - data = request.get_json() - - username = data.get('username') - password = data.get('password') - - pswd = users_list.get_user_pswd(username) - - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/login_teacher_post', methods=['POST']) -def login_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - pswd = users_list.get_user_pswd(username) - is_teacher = users_list.get_user_is_teacher(username) - if is_teacher is None or is_teacher == False: - return jsonify({'success': False, 'message': '用户名不存在或非教师账号'}) - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/teacherboard') -@require_role(roles="teacher") -def teacherboard(): - return render_template('teacherboard.html') - - -@app.route('/logout') -def logout(): - session.pop('user_id', None) - return redirect(url_for('login')) - -@app.route('/get_session') -def get_session(): - user_session = session.get('user_id', 'default_session') - return jsonify({"session": user_session}) - - -''' -DashBoard -''' -user_id2UserClass = {} -@app.route('/dashboard') -@require_role -def dashboard(): - user_id = session['user_id'] - username = uuid2username[user_id] - if (user_id not in user_id2UserClass): - user_id2UserClass[user_id] = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - user_course_data = [] - for course_id in user_id2UserClass[user_id].select_course: - course_brief_info = course_list.get_course_brief_info(course_id, load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR)) - user_course_data.append(course_brief_info) - return render_template('dashboard.html',user_data = user_id2UserClass[user_id].to_json_without_dialog(), user_course_data = json.dumps(user_course_data)) - -''' -Course -''' - -@app.route('/course/') -@require_role -def course(course_id): - c = load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR) - return render_template('course.html', course_id=course_id, course_data=c) - -@app.route('/select_course', methods=['POST']) -@require_role -def select_course(): - user = user_id2UserClass[session['user_id']] - data = request.get_json() - course_id = data.get('course_id') - if course_id: - user.select_new_course(course_id, load_course_from_json(course_id, COURSE_DATA_DIR)) - return jsonify({'success': True, 'message': '课程选择成功'}) - - -@app.route('/') -@require_role -def home_index(): - selected_courses=[] - if ('user_id' in session): - if (session['user_id'] not in user_id2UserClass): return redirect(url_for('login')) - user = user_id2UserClass[session['user_id']] - for course_id in user.select_course: - selected_courses.append(course_id) - - return render_template('index.html', courses_data = course_list, selected_courses =selected_courses) - -# 一些app辅助函数,主要提供给Agent与数据库的交互能力 - -class MyFunction: - def save_chapter_memory(self, id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal): - print("-=-=-=-=-=-=-=-") - print(id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - username = uuid2username[id] - u = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - u.save_chapter_memory(course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - -app.my_function = MyFunction() -if __name__ == '__main__': - socketio.on_namespace(VSCodeNamespace('/vscode')) - socketio.on_namespace(AgentNamespace('/agent')) - socketio.run(app, host='0.0.0.0', port=5551, debug=False,allow_unsafe_werkzeug=True) - diff --git a/Html/runs/run_20250906-141430_i7aihi/code/backboardManager.py b/Html/runs/run_20250906-141430_i7aihi/code/backboardManager.py deleted file mode 100644 index 1777f8d..0000000 --- a/Html/runs/run_20250906-141430_i7aihi/code/backboardManager.py +++ /dev/null @@ -1,80 +0,0 @@ - - - -import time -import os - -class Backboard: - def __init__(self, user_id, username, course_id, lesson_id, root_path): - self.user_id = user_id - self.username = username - self.course_id = course_id - self.lesson_id = lesson_id - self.root_path = root_path - self.create_time = time.time() - self.enter_chapter_time = time.time() - self.history = [] - self.file_tree = "[]" - self.active_file_path = "" - self.active_file_content = "" - self.pasted_file_path = "" - self.pasted_content = "" - - - def next_chapter(self): - self.enter_chapter_time = time.time() - - def get_info_prompt(self): - - five_history = "" - for h in self.history[-5:]: - five_history += h['type'] + "\n" + h.get('filePath', '') + "\n\n" - - endl = "\n" - return (f"###Global Info:###{endl}" - f"Here are some info about now user's IDE, refer to it when you need to handle some code.{endl}" - f"- User's total study time is {self.get_deltatime_mmss(self.create_time, time.time())}{endl}" - f"- User's current chapter study time is {self.get_deltatime_mmss(self.enter_chapter_time, time.time())}{endl}" - f"- Activated file path: {self.active_file_path}{endl}" - f"```{endl}" - f"{self.active_file_content[-10:]}{endl}" - f"```{endl}" - f"- Last five action:{five_history}{endl}" - f"- File tree: {self.file_tree}{endl}") - # f"- Activated file content (current editing 10 lines): {endl}" - def add_history(self, realtime_action): - if(realtime_action['type']=='config'):return - if len(self.history)!=0: - if (self.history[-1]['type']=='fileEdit'): - if(self.history[-1]['filePath'] == realtime_action['filePath']): - self.history[-1]['content'] = realtime_action['content'] - return - self.history.append(realtime_action) - - - def get_deltatime_mmss(self, start_time, end_time): - elapsed_time = end_time - start_time - hours = int(elapsed_time // 3600) - minutes = int((elapsed_time % 3600) // 60) - seconds = int(elapsed_time % 60) - return f"{hours:02d}:{minutes:02d}:{seconds:02d}" - - - def get_active_file_reletive_path(self): - relative_path = os.path.relpath(self.active_file_path, self.root_path) - return relative_path - - - -class BackBoardManager: - def __init__(self): - self.backboards = {} # user_id: Backboard - - def add_backboard(self, user_id, username, course_id, lesson_id, root_path): - self.backboards[user_id] = Backboard(user_id,username, course_id, lesson_id, root_path) - - def get_backboard(self, user_id) -> Backboard: - return self.backboards[user_id] - - - diff --git a/Html/runs/run_20250906-141430_i7aihi/code/bootstrap.py b/Html/runs/run_20250906-141430_i7aihi/code/bootstrap.py deleted file mode 100644 index bcb15ce..0000000 --- a/Html/runs/run_20250906-141430_i7aihi/code/bootstrap.py +++ /dev/null @@ -1,31 +0,0 @@ -from pathlib import Path -import sys, os - -def bootstrap_paths(): - """ - 让 'AlgoriAgent'(位于 repo_root/AlgoriAgent)可被 import; - 并提供 STUDENT_WORKSPACE_ROOT 的默认值(repo_root/study)。 - 适配当前工厂位置:repo_root/Html/apps/__init__.py - """ - here = Path(__file__).resolve() - # repo_root = .../Html/apps/../../ => parents[2] - repo_root = here.parents[2] - - # 兜底:如果目录结构变化,尝试向上搜索包含 AlgoriAgent 的目录作为 repo_root - if not (repo_root / "AlgoriAgent").exists(): - for p in here.parents: - if (p / "AlgoriAgent").is_dir(): - repo_root = p - break - - # 确保仓库根在 sys.path(这样 'AlgoriAgent' 顶层包可被发现) - repo_root_str = str(repo_root) - if repo_root_str not in sys.path: - sys.path.insert(0, repo_root_str) - - # 可选:如果你还有其它顶层包,也可在此处继续插入 - - # 默认学习工作区目录(也可放到 config.ini / 环境变量覆盖) - os.environ.setdefault("STUDENT_WORKSPACE_ROOT", str(repo_root / "study")) - - return repo_root # 方便调试/日志 \ No newline at end of file diff --git a/Html/runs/run_20250906-141430_i7aihi/code/wsgi.py b/Html/runs/run_20250906-141430_i7aihi/code/wsgi.py deleted file mode 100644 index bbcbe5f..0000000 --- a/Html/runs/run_20250906-141430_i7aihi/code/wsgi.py +++ /dev/null @@ -1,6 +0,0 @@ -# wsgi.py -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -# 提供一个可被 WSGI/进程管理器导入的 app 对象 -app = create_app() diff --git a/Html/runs/run_20250906-141430_i7aihi/logging.chat b/Html/runs/run_20250906-141430_i7aihi/logging.chat deleted file mode 100644 index e69de29..0000000 diff --git a/Html/runs/run_20250906-141430_i7aihi/logging.log b/Html/runs/run_20250906-141430_i7aihi/logging.log deleted file mode 100644 index 1f1ad04..0000000 --- a/Html/runs/run_20250906-141430_i7aihi/logging.log +++ /dev/null @@ -1,9 +0,0 @@ -2025-09-06 14:14:37.599 | INFO | agentscope.models:read_model_configs:186 - Load configs for model wrapper: openai_cfg -2025-09-06 14:15:06.614 | INFO | agentscope.models.model:__init__:201 - Initialize model by configuration [openai_cfg] -2025-09-06 14:15:06.704 | WARNING | agentscope.models.openai_model:__init__:83 - fail to get max_length for gpt-4.1-nano: 'Model [gpt-4.1-nano] not found in OPENAI_MAX_LENGTH. The last updated date is 20231212' -2025-09-06 14:15:06.705 | INFO | agentscope.utils.monitor:register_budget:609 - set budget None to gpt-4.1-nano -2025-09-06 14:15:06.705 | WARNING | agentscope.utils.monitor:register_budget:639 - Calculate budgets for model [gpt-4.1-nano] is not supported -2025-09-06 14:15:06.707 | INFO | agentscope.utils.monitor:register:417 - Register metric [gpt-4.1-nano.call_counter] to SqliteMonitor with unit [times] and quota [None] -2025-09-06 14:15:06.715 | INFO | agentscope.utils.monitor:register:417 - Register metric [gpt-4.1-nano.prompt_tokens] to SqliteMonitor with unit [token] and quota [None] -2025-09-06 14:15:06.722 | INFO | agentscope.utils.monitor:register:417 - Register metric [gpt-4.1-nano.completion_tokens] to SqliteMonitor with unit [token] and quota [None] -2025-09-06 14:15:06.729 | INFO | agentscope.utils.monitor:register:417 - Register metric [gpt-4.1-nano.total_tokens] to SqliteMonitor with unit [token] and quota [None] diff --git a/Html/runs/run_20250906-141607_ym9kvd/.config b/Html/runs/run_20250906-141607_ym9kvd/.config deleted file mode 100644 index cdae12a..0000000 --- a/Html/runs/run_20250906-141607_ym9kvd/.config +++ /dev/null @@ -1,7 +0,0 @@ -{ - "project": "pcYHwo", - "name": "ym9kvd", - "run_id": "run_20250906-141607_ym9kvd", - "timestamp": "2025-09-06 14:16:07", - "pid": 19154 -} \ No newline at end of file diff --git a/Html/runs/run_20250906-141607_ym9kvd/agentscope.db b/Html/runs/run_20250906-141607_ym9kvd/agentscope.db deleted file mode 100644 index 666055b77679cda29c14fcf23b4ef1d039c5b52a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI%L2KJE6bEoS4Q(k)+glI2yjv3-0%NB!Hs&O1YUav`W0U1F<0V=#BsNLx(sSu$ z>=W&q?4#^B$!*yt2YT5l`~^0a^z(#~{ zkyg6w!t)u0!@f%5aeaJcfD9*Q_b$ozCY8>~CFA6|{Z2V!N;Z^cIq}eS$>x3HY|^=j z7lokrf1)Z$x@_R^N~@apn7OPMkZ(I<*1WJCw@v3GWy2n6&RcIQ0~zlR_x8^$%be!% zmxb7@7V;}H+K5#l(wSbZKXKY!mys6ROyi|!%aN@+%REpi?;B-K4PC3&{>iCzQnNB+ zwbW!z4iA{x(V_2L+5VJ1vMJeN;5l68yJ9?OZyl-TNCEp4P{^H8$cTGExdq$9ANE6@ zA@`ZUhb>is+Y=S?%$C1fnN{muZU1a!nMRV%#qFbMT;y3hf|KlJ)00Izz00bZa0SG_<0uX=z1a@EGHy1PL*Z=?k diff --git a/Html/runs/run_20250906-141607_ym9kvd/code/app.py b/Html/runs/run_20250906-141607_ym9kvd/code/app.py deleted file mode 100644 index b761bd2..0000000 --- a/Html/runs/run_20250906-141607_ym9kvd/code/app.py +++ /dev/null @@ -1,20 +0,0 @@ -# app.py 0.1.1 rise to factory mode -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -from apps.extensions import socketio - -# 工厂创建 app,工厂里已经做了:加载配置/注册蓝图/注册 namespaces -app = create_app() - -if __name__ == "__main__": - # 仅本地开发用;生产不要用 werkzeug 自带的开发服务器 - socketio.run( - app, - host="0.0.0.0", - port=5551, - debug=False, # 开发期打开 - allow_unsafe_werkzeug=True # 避免 dev server 的安全限制提示 - ) - - diff --git a/Html/runs/run_20250906-141607_ym9kvd/code/app_back.py b/Html/runs/run_20250906-141607_ym9kvd/code/app_back.py deleted file mode 100644 index 246853c..0000000 --- a/Html/runs/run_20250906-141607_ym9kvd/code/app_back.py +++ /dev/null @@ -1,480 +0,0 @@ -from bootstrap import bootstrap_paths -bootstrap_paths() -from functools import wraps -from flask import Flask, redirect, session, request, jsonify, render_template, send_from_directory, url_for -from flask_cors import CORS -from flask_socketio import SocketIO, join_room, emit, Namespace -import markdown -import os -import uuid -import shutil -import sys -import json -from apps.auth.decorators import require_role -parent_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) -sys.path.insert(0, parent_dir) -student_workspace_root_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../study')) -current_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '.')) -sys.path.insert(0, current_dir) -from AlgoriAgent.projects.algoriAgent.agent_manager import AgentManager - - -import configparser - -from db.user_list import UserList -from db.user import User, load_user_from_json, create_user_json -from db.course_list import CourseList -from db.course import Course, load_course_from_json -GLOBAL_CONFIG = configparser.ConfigParser() -GLOBAL_CONFIG.read('config.ini') -VSCODE_WEB_URL = GLOBAL_CONFIG['VSCODE_WEB']['url'] -USER_DATA_DIR = GLOBAL_CONFIG['USER_DATA']['dir'] -COURSE_DATA_DIR = GLOBAL_CONFIG['COURSE_DATA']['dir'] - -app = Flask(__name__) -socketio = SocketIO(app, cors_allowed_origins="*",ping_timeout=60, ping_interval=5) -# socketio = SocketIO(app, cors_allowed_origins="http://localhost:9888") # 设置跨域支持 -import logging -app.secret_key = 'cakebaker' -app.logger.setLevel(logging.DEBUG) -# 配置 CORS -CORS(app, resources={r"/*": {"origins": VSCODE_WEB_URL},}, supports_credentials=True) - - -userid_recorder = {} # user_id&path -> session['user_id'] - -''' -Backboard -''' -from backboardManager import BackBoardManager, Backboard - -backboard_manager = BackBoardManager() -uuid2username = {} -username2uuid = {} - - - -# 定义命名空间:用于和 VSCode 插件交流 -class VSCodeNamespace(Namespace): - def on_login(self,data): - print("VSCode client connected") - print(data) - dataconfig = data['config'] - user_id = dataconfig.get('user_id') - path = dataconfig.get('path') - course_id = dataconfig.get('course_id') - lesson_id = dataconfig.get('chapter_id') - print(f"User {user_id} connected with path: {path}") - useruuid = username2uuid[user_id] - join_room(useruuid, namespace='/vscode') - if backboard_manager.get_backboard(useruuid) == None: - backboard_manager.add_backboard(useruuid,user_id, course_id, lesson_id, path) - - - def on_message(self, data): - print(f"Received from VSCode client: {data}") - dataconfig = data['config'] - realtime_response(dataconfig, data) - # emit('response', {'message': 'Config data received and connection established'}) - def on_disconnect(self, data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - -def realtime_response(config, realtime_action): - user_id = config['user_id'] - folder_path = config['path'] - useruuid = username2uuid[user_id] - bb = backboard_manager.get_backboard(useruuid) - assert type(bb) == Backboard - - bb.add_history(realtime_action) - - if realtime_action['type'] == 'workspaceFolders': - bb.file_tree = realtime_action['fileTree'] - - if realtime_action['type'] == 'activeFile': - file_path = realtime_action['filePath'] - assert type(file_path) == str - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - if realtime_action['type'] == 'paste': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.pasted_file_path = file_path - bb.pasted_content = realtime_action['content'] - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - if realtime_action['type'] == 'fileEdit': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - - - print("config"+str(config)) - print("realtime_action"+str(realtime_action)) - pass - - -''' -Agent and Chat -''' -agent_manager = AgentManager(app = app, socketio = socketio) -user_threads = {} -import threading -from concurrent.futures import ThreadPoolExecutor, as_completed - -# 初始化线程池 -executor = ThreadPoolExecutor(max_workers=10) -class AgentNamespace(Namespace): - def on_login(self, data): - data = json.loads(data) - user = data['username'] - course_id = data['course_id'] - chapter_id = data['chapter_id'] - user_uuid = username2uuid[user] - session['user_id'] = user_uuid - print(f'User connected with session user_id: {user_uuid}') - # 从markdown、markdown_prompts、score_prompts中各读取数据folder.md并进行new_agent - with open(f'books/markdown/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fmd,\ - open(f'books/markdown_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8')as fmdp,\ - open(f'books/score_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fsp: - markdown = fmd.read() - markdown_prompts = fmdp.read() - score_prompts = fsp.read() - user_uuid, agent = agent_manager.new_agent(course_id, chapter_id, markdown, markdown_prompts, score_prompts, id=user_uuid, - root_path=f'../../study/{user}/{course_id}/{chapter_id}') - print(user_uuid) - join_room(user_uuid, namespace='/agent') # 将该用户加入以user_id为名的room - backboard_manager.add_backboard(user_uuid, user, course_id, chapter_id, root_path=f'../../study/{user}/{course_id}/{chapter_id}') - - def on_language(self, language): - id = session.get('user_id') - agent_manager.change_language(id, language) - - def on_message(self, data): - print(f"Message from client: {data}") - id = session.get('user_id') - if (type(data)==str): - data = json.loads(data) - print(id) - if data['type'] == 'text': - res = agent_manager.invoke(id, data['data'], backboard_manager.get_backboard(id).get_info_prompt()) - print('=*='*20) - print(res.content) - reply = f"{res.content['speak']}" - with app.app_context(): - emit('message',reply, room=id, namespace='/agent') - emit('request_function',res.content['function'], room=id, namespace='/agent') - - if data['type'] == 'function': - agent_manager.function_call(id, data['data']) - - def on_initiative(self,data): - print("User active function call") - user_id = session['user_id'] - if data['name'] == 'sample_judge': - agent_manager.sample_judge(user_id, backboard_manager.get_backboard(user_id)) - if data['name'] == 'judge': - agent_manager.judge(user_id, backboard_manager.get_backboard(user_id)) - - - - def on_disconnect(self,data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - - -''' -Markdown to HTML -''' -# 配置文件路径 -MARKDOWN_DIR = 'books/markdown' # 存放 markdown 文件的文件夹 -STATIC_DIR = 'static' # 存放生成的 HTML 和图片资源的文件夹 -IMAGE_DIR = 'image' # 图片资源相对于 markdown 的位置 - - - -@app.route('/--markdown', methods=['GET']) -def convert_md(course_id, filename): - md_file_path = os.path.join(MARKDOWN_DIR,course_id, f'{filename}.md') - - if not os.path.exists(md_file_path): - return jsonify({'error': 'Markdown file not found'}), 404 - - # 读取 markdown 文件内容 - with open(md_file_path, 'r', encoding='utf-8') as file: - md_content = file.read() - - # 将 markdown 转换为 HTML - html_content = markdown.markdown(md_content) - # 插入 CSS 样式,限制图片最大宽度为 100%,高度自动调整 - html_with_styles = f""" - - - - - - - {html_content} - - - """ - # 保存 HTML 文件到 static 文件夹 - html_output_path = os.path.join(STATIC_DIR, f'{filename}.html') - with open(html_output_path, 'w', encoding='utf-8') as html_file: - html_file.write(html_with_styles) - - # 处理图片资源,将 image/xxx 文件夹拷贝到 static/image/xxx - image_source_dir = os.path.join(MARKDOWN_DIR,course_id, IMAGE_DIR, filename) - image_target_dir = os.path.join(STATIC_DIR, IMAGE_DIR, filename) - print(f"Copying image resources from {image_source_dir} to {image_target_dir}") - if os.path.exists(image_source_dir): - # 确保 static/image/xxx 目录存在 - if not os.path.exists(image_target_dir): - os.makedirs(image_target_dir) - - # 拷贝图片资源 - for image_file in os.listdir(image_source_dir): - full_image_file_path = os.path.join(image_source_dir, image_file) - if os.path.isfile(full_image_file_path): - shutil.copy(full_image_file_path, image_target_dir) - - return jsonify({'html_url': f'/static/{filename}.html'}) - -# 静态文件(HTML 和图片资源)的访问 -@app.route('/static/') -def serve_static(filename): - return send_from_directory(STATIC_DIR, filename) - - -''' -Vscode -''' -@app.route('/desktop///') -def desktop(user_id, course_id, chapter_id): - if 'user_id' not in session: - # return redirect(url_for('login')) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ user_id + "uuid is"+ session['user_id']) - username2uuid[user_id] = session['user_id'] - uuid2username[session['user_id']] = user_id - userid_recorder[user_id+'&'+course_id] = session['user_id'] - - # 在学习目录下创建一个名为 user_id_path 的文件夹 - path_dir = os.path.join(student_workspace_root_path, user_id, course_id,chapter_id) - os.makedirs(path_dir, exist_ok=True) - # 在此文件夹内部创建一个.config文件,并写入 user_id=user_id\n path=path - config_path = os.path.join(path_dir, '.config') - if GLOBAL_CONFIG['VSCODE_WEB_PATH']['is_wsl']: # 如果是在 WSL 中运行,则将路径转换为 WSL 路径 - path_dir = path_dir.replace('\\', '/') - path_dir = path_dir.replace(GLOBAL_CONFIG['VSCODE_WEB_PATH']['windows_path'] , GLOBAL_CONFIG['VSCODE_WEB_PATH']['wsl_path']) - with open(config_path, 'w', encoding='utf-8') as f: - tmpd = {'user_id': user_id, 'course_id': course_id, 'chapter_id': chapter_id, 'path': path_dir} - json.dump(tmpd, f) - print('---------------------') - print(config_path) - return render_template('desktop.html', vscode_web_url=VSCODE_WEB_URL, user_id=user_id, course_id=course_id, chapter_id=chapter_id, workspace_path=path_dir) - -@app.route('/desktop_nouser//') -def desktop_nouser(course_id, chapter_id): - if 'user_id' not in session: - return redirect(url_for('login')) - user_id = session['user_id'] - username = uuid2username[user_id] - return redirect(url_for('desktop', user_id=username, course_id=course_id, chapter_id=chapter_id)) - -@app.route('/vscode_data', methods=['POST']) -def vscode_data(): - data = request.json - config = data['config'] - realtime_response(config,data) - print(f"Received data from VSCode: {data}") - return jsonify({"status": "success", "received": data}) - - - -''' -Login - -''' -users_list = UserList() -course_list = CourseList() - - -@app.route('/register') -def register(): - return render_template('register.html') - -@app.route('/register_teacher') -def register_teacher(): - return render_template('register_teacher.html') - -@app.route('/register_teacher_post', methods=['POST']) -def register_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password, teacher=True) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - -@app.route('/register_post', methods=['POST']) -def register_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - - -@app.route('/login') -def login(): - return render_template('login.html') - if 'user_id' not in session: - return render_template('login.html') - else: - return redirect(url_for('/')) - -@app.route('/login_post', methods=['POST']) -def login_post(): - # 获取请求的 JSON 数据 - data = request.get_json() - - username = data.get('username') - password = data.get('password') - - pswd = users_list.get_user_pswd(username) - - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/login_teacher_post', methods=['POST']) -def login_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - pswd = users_list.get_user_pswd(username) - is_teacher = users_list.get_user_is_teacher(username) - if is_teacher is None or is_teacher == False: - return jsonify({'success': False, 'message': '用户名不存在或非教师账号'}) - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/teacherboard') -@require_role(roles="teacher") -def teacherboard(): - return render_template('teacherboard.html') - - -@app.route('/logout') -def logout(): - session.pop('user_id', None) - return redirect(url_for('login')) - -@app.route('/get_session') -def get_session(): - user_session = session.get('user_id', 'default_session') - return jsonify({"session": user_session}) - - -''' -DashBoard -''' -user_id2UserClass = {} -@app.route('/dashboard') -@require_role -def dashboard(): - user_id = session['user_id'] - username = uuid2username[user_id] - if (user_id not in user_id2UserClass): - user_id2UserClass[user_id] = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - user_course_data = [] - for course_id in user_id2UserClass[user_id].select_course: - course_brief_info = course_list.get_course_brief_info(course_id, load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR)) - user_course_data.append(course_brief_info) - return render_template('dashboard.html',user_data = user_id2UserClass[user_id].to_json_without_dialog(), user_course_data = json.dumps(user_course_data)) - -''' -Course -''' - -@app.route('/course/') -@require_role -def course(course_id): - c = load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR) - return render_template('course.html', course_id=course_id, course_data=c) - -@app.route('/select_course', methods=['POST']) -@require_role -def select_course(): - user = user_id2UserClass[session['user_id']] - data = request.get_json() - course_id = data.get('course_id') - if course_id: - user.select_new_course(course_id, load_course_from_json(course_id, COURSE_DATA_DIR)) - return jsonify({'success': True, 'message': '课程选择成功'}) - - -@app.route('/') -@require_role -def home_index(): - selected_courses=[] - if ('user_id' in session): - if (session['user_id'] not in user_id2UserClass): return redirect(url_for('login')) - user = user_id2UserClass[session['user_id']] - for course_id in user.select_course: - selected_courses.append(course_id) - - return render_template('index.html', courses_data = course_list, selected_courses =selected_courses) - -# 一些app辅助函数,主要提供给Agent与数据库的交互能力 - -class MyFunction: - def save_chapter_memory(self, id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal): - print("-=-=-=-=-=-=-=-") - print(id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - username = uuid2username[id] - u = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - u.save_chapter_memory(course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - -app.my_function = MyFunction() -if __name__ == '__main__': - socketio.on_namespace(VSCodeNamespace('/vscode')) - socketio.on_namespace(AgentNamespace('/agent')) - socketio.run(app, host='0.0.0.0', port=5551, debug=False,allow_unsafe_werkzeug=True) - diff --git a/Html/runs/run_20250906-141607_ym9kvd/code/backboardManager.py b/Html/runs/run_20250906-141607_ym9kvd/code/backboardManager.py deleted file mode 100644 index 1777f8d..0000000 --- a/Html/runs/run_20250906-141607_ym9kvd/code/backboardManager.py +++ /dev/null @@ -1,80 +0,0 @@ - - - -import time -import os - -class Backboard: - def __init__(self, user_id, username, course_id, lesson_id, root_path): - self.user_id = user_id - self.username = username - self.course_id = course_id - self.lesson_id = lesson_id - self.root_path = root_path - self.create_time = time.time() - self.enter_chapter_time = time.time() - self.history = [] - self.file_tree = "[]" - self.active_file_path = "" - self.active_file_content = "" - self.pasted_file_path = "" - self.pasted_content = "" - - - def next_chapter(self): - self.enter_chapter_time = time.time() - - def get_info_prompt(self): - - five_history = "" - for h in self.history[-5:]: - five_history += h['type'] + "\n" + h.get('filePath', '') + "\n\n" - - endl = "\n" - return (f"###Global Info:###{endl}" - f"Here are some info about now user's IDE, refer to it when you need to handle some code.{endl}" - f"- User's total study time is {self.get_deltatime_mmss(self.create_time, time.time())}{endl}" - f"- User's current chapter study time is {self.get_deltatime_mmss(self.enter_chapter_time, time.time())}{endl}" - f"- Activated file path: {self.active_file_path}{endl}" - f"```{endl}" - f"{self.active_file_content[-10:]}{endl}" - f"```{endl}" - f"- Last five action:{five_history}{endl}" - f"- File tree: {self.file_tree}{endl}") - # f"- Activated file content (current editing 10 lines): {endl}" - def add_history(self, realtime_action): - if(realtime_action['type']=='config'):return - if len(self.history)!=0: - if (self.history[-1]['type']=='fileEdit'): - if(self.history[-1]['filePath'] == realtime_action['filePath']): - self.history[-1]['content'] = realtime_action['content'] - return - self.history.append(realtime_action) - - - def get_deltatime_mmss(self, start_time, end_time): - elapsed_time = end_time - start_time - hours = int(elapsed_time // 3600) - minutes = int((elapsed_time % 3600) // 60) - seconds = int(elapsed_time % 60) - return f"{hours:02d}:{minutes:02d}:{seconds:02d}" - - - def get_active_file_reletive_path(self): - relative_path = os.path.relpath(self.active_file_path, self.root_path) - return relative_path - - - -class BackBoardManager: - def __init__(self): - self.backboards = {} # user_id: Backboard - - def add_backboard(self, user_id, username, course_id, lesson_id, root_path): - self.backboards[user_id] = Backboard(user_id,username, course_id, lesson_id, root_path) - - def get_backboard(self, user_id) -> Backboard: - return self.backboards[user_id] - - - diff --git a/Html/runs/run_20250906-141607_ym9kvd/code/bootstrap.py b/Html/runs/run_20250906-141607_ym9kvd/code/bootstrap.py deleted file mode 100644 index bcb15ce..0000000 --- a/Html/runs/run_20250906-141607_ym9kvd/code/bootstrap.py +++ /dev/null @@ -1,31 +0,0 @@ -from pathlib import Path -import sys, os - -def bootstrap_paths(): - """ - 让 'AlgoriAgent'(位于 repo_root/AlgoriAgent)可被 import; - 并提供 STUDENT_WORKSPACE_ROOT 的默认值(repo_root/study)。 - 适配当前工厂位置:repo_root/Html/apps/__init__.py - """ - here = Path(__file__).resolve() - # repo_root = .../Html/apps/../../ => parents[2] - repo_root = here.parents[2] - - # 兜底:如果目录结构变化,尝试向上搜索包含 AlgoriAgent 的目录作为 repo_root - if not (repo_root / "AlgoriAgent").exists(): - for p in here.parents: - if (p / "AlgoriAgent").is_dir(): - repo_root = p - break - - # 确保仓库根在 sys.path(这样 'AlgoriAgent' 顶层包可被发现) - repo_root_str = str(repo_root) - if repo_root_str not in sys.path: - sys.path.insert(0, repo_root_str) - - # 可选:如果你还有其它顶层包,也可在此处继续插入 - - # 默认学习工作区目录(也可放到 config.ini / 环境变量覆盖) - os.environ.setdefault("STUDENT_WORKSPACE_ROOT", str(repo_root / "study")) - - return repo_root # 方便调试/日志 \ No newline at end of file diff --git a/Html/runs/run_20250906-141607_ym9kvd/code/wsgi.py b/Html/runs/run_20250906-141607_ym9kvd/code/wsgi.py deleted file mode 100644 index bbcbe5f..0000000 --- a/Html/runs/run_20250906-141607_ym9kvd/code/wsgi.py +++ /dev/null @@ -1,6 +0,0 @@ -# wsgi.py -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -# 提供一个可被 WSGI/进程管理器导入的 app 对象 -app = create_app() diff --git a/Html/runs/run_20250906-141607_ym9kvd/logging.chat b/Html/runs/run_20250906-141607_ym9kvd/logging.chat deleted file mode 100644 index e69de29..0000000 diff --git a/Html/runs/run_20250906-141607_ym9kvd/logging.log b/Html/runs/run_20250906-141607_ym9kvd/logging.log deleted file mode 100644 index bdd2fa8..0000000 --- a/Html/runs/run_20250906-141607_ym9kvd/logging.log +++ /dev/null @@ -1 +0,0 @@ -2025-09-06 14:16:13.956 | INFO | agentscope.models:read_model_configs:186 - Load configs for model wrapper: openai_cfg diff --git a/Html/runs/run_20250908-144720_kkn0r6/.config b/Html/runs/run_20250908-144720_kkn0r6/.config deleted file mode 100644 index 4236a2b..0000000 --- a/Html/runs/run_20250908-144720_kkn0r6/.config +++ /dev/null @@ -1,7 +0,0 @@ -{ - "project": "0Ya71I", - "name": "kkn0r6", - "run_id": "run_20250908-144720_kkn0r6", - "timestamp": "2025-09-08 14:47:20", - "pid": 3339 -} \ No newline at end of file diff --git a/Html/runs/run_20250908-144720_kkn0r6/agentscope.db b/Html/runs/run_20250908-144720_kkn0r6/agentscope.db deleted file mode 100644 index 666055b77679cda29c14fcf23b4ef1d039c5b52a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI%L2KJE6bEoS4Q(k)+glI2yjv3-0%NB!Hs&O1YUav`W0U1F<0V=#BsNLx(sSu$ z>=W&q?4#^B$!*yt2YT5l`~^0a^z(#~{ zkyg6w!t)u0!@f%5aeaJcfD9*Q_b$ozCY8>~CFA6|{Z2V!N;Z^cIq}eS$>x3HY|^=j z7lokrf1)Z$x@_R^N~@apn7OPMkZ(I<*1WJCw@v3GWy2n6&RcIQ0~zlR_x8^$%be!% zmxb7@7V;}H+K5#l(wSbZKXKY!mys6ROyi|!%aN@+%REpi?;B-K4PC3&{>iCzQnNB+ zwbW!z4iA{x(V_2L+5VJ1vMJeN;5l68yJ9?OZyl-TNCEp4P{^H8$cTGExdq$9ANE6@ zA@`ZUhb>is+Y=S?%$C1fnN{muZU1a!nMRV%#qFbMT;y3hf|KlJ)00Izz00bZa0SG_<0uX=z1a@EGHy1PL*Z=?k diff --git a/Html/runs/run_20250908-144720_kkn0r6/code/app.py b/Html/runs/run_20250908-144720_kkn0r6/code/app.py deleted file mode 100644 index b761bd2..0000000 --- a/Html/runs/run_20250908-144720_kkn0r6/code/app.py +++ /dev/null @@ -1,20 +0,0 @@ -# app.py 0.1.1 rise to factory mode -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -from apps.extensions import socketio - -# 工厂创建 app,工厂里已经做了:加载配置/注册蓝图/注册 namespaces -app = create_app() - -if __name__ == "__main__": - # 仅本地开发用;生产不要用 werkzeug 自带的开发服务器 - socketio.run( - app, - host="0.0.0.0", - port=5551, - debug=False, # 开发期打开 - allow_unsafe_werkzeug=True # 避免 dev server 的安全限制提示 - ) - - diff --git a/Html/runs/run_20250908-144720_kkn0r6/code/app_back.py b/Html/runs/run_20250908-144720_kkn0r6/code/app_back.py deleted file mode 100644 index 246853c..0000000 --- a/Html/runs/run_20250908-144720_kkn0r6/code/app_back.py +++ /dev/null @@ -1,480 +0,0 @@ -from bootstrap import bootstrap_paths -bootstrap_paths() -from functools import wraps -from flask import Flask, redirect, session, request, jsonify, render_template, send_from_directory, url_for -from flask_cors import CORS -from flask_socketio import SocketIO, join_room, emit, Namespace -import markdown -import os -import uuid -import shutil -import sys -import json -from apps.auth.decorators import require_role -parent_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) -sys.path.insert(0, parent_dir) -student_workspace_root_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../study')) -current_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '.')) -sys.path.insert(0, current_dir) -from AlgoriAgent.projects.algoriAgent.agent_manager import AgentManager - - -import configparser - -from db.user_list import UserList -from db.user import User, load_user_from_json, create_user_json -from db.course_list import CourseList -from db.course import Course, load_course_from_json -GLOBAL_CONFIG = configparser.ConfigParser() -GLOBAL_CONFIG.read('config.ini') -VSCODE_WEB_URL = GLOBAL_CONFIG['VSCODE_WEB']['url'] -USER_DATA_DIR = GLOBAL_CONFIG['USER_DATA']['dir'] -COURSE_DATA_DIR = GLOBAL_CONFIG['COURSE_DATA']['dir'] - -app = Flask(__name__) -socketio = SocketIO(app, cors_allowed_origins="*",ping_timeout=60, ping_interval=5) -# socketio = SocketIO(app, cors_allowed_origins="http://localhost:9888") # 设置跨域支持 -import logging -app.secret_key = 'cakebaker' -app.logger.setLevel(logging.DEBUG) -# 配置 CORS -CORS(app, resources={r"/*": {"origins": VSCODE_WEB_URL},}, supports_credentials=True) - - -userid_recorder = {} # user_id&path -> session['user_id'] - -''' -Backboard -''' -from backboardManager import BackBoardManager, Backboard - -backboard_manager = BackBoardManager() -uuid2username = {} -username2uuid = {} - - - -# 定义命名空间:用于和 VSCode 插件交流 -class VSCodeNamespace(Namespace): - def on_login(self,data): - print("VSCode client connected") - print(data) - dataconfig = data['config'] - user_id = dataconfig.get('user_id') - path = dataconfig.get('path') - course_id = dataconfig.get('course_id') - lesson_id = dataconfig.get('chapter_id') - print(f"User {user_id} connected with path: {path}") - useruuid = username2uuid[user_id] - join_room(useruuid, namespace='/vscode') - if backboard_manager.get_backboard(useruuid) == None: - backboard_manager.add_backboard(useruuid,user_id, course_id, lesson_id, path) - - - def on_message(self, data): - print(f"Received from VSCode client: {data}") - dataconfig = data['config'] - realtime_response(dataconfig, data) - # emit('response', {'message': 'Config data received and connection established'}) - def on_disconnect(self, data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - -def realtime_response(config, realtime_action): - user_id = config['user_id'] - folder_path = config['path'] - useruuid = username2uuid[user_id] - bb = backboard_manager.get_backboard(useruuid) - assert type(bb) == Backboard - - bb.add_history(realtime_action) - - if realtime_action['type'] == 'workspaceFolders': - bb.file_tree = realtime_action['fileTree'] - - if realtime_action['type'] == 'activeFile': - file_path = realtime_action['filePath'] - assert type(file_path) == str - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - if realtime_action['type'] == 'paste': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.pasted_file_path = file_path - bb.pasted_content = realtime_action['content'] - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - if realtime_action['type'] == 'fileEdit': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - - - print("config"+str(config)) - print("realtime_action"+str(realtime_action)) - pass - - -''' -Agent and Chat -''' -agent_manager = AgentManager(app = app, socketio = socketio) -user_threads = {} -import threading -from concurrent.futures import ThreadPoolExecutor, as_completed - -# 初始化线程池 -executor = ThreadPoolExecutor(max_workers=10) -class AgentNamespace(Namespace): - def on_login(self, data): - data = json.loads(data) - user = data['username'] - course_id = data['course_id'] - chapter_id = data['chapter_id'] - user_uuid = username2uuid[user] - session['user_id'] = user_uuid - print(f'User connected with session user_id: {user_uuid}') - # 从markdown、markdown_prompts、score_prompts中各读取数据folder.md并进行new_agent - with open(f'books/markdown/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fmd,\ - open(f'books/markdown_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8')as fmdp,\ - open(f'books/score_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fsp: - markdown = fmd.read() - markdown_prompts = fmdp.read() - score_prompts = fsp.read() - user_uuid, agent = agent_manager.new_agent(course_id, chapter_id, markdown, markdown_prompts, score_prompts, id=user_uuid, - root_path=f'../../study/{user}/{course_id}/{chapter_id}') - print(user_uuid) - join_room(user_uuid, namespace='/agent') # 将该用户加入以user_id为名的room - backboard_manager.add_backboard(user_uuid, user, course_id, chapter_id, root_path=f'../../study/{user}/{course_id}/{chapter_id}') - - def on_language(self, language): - id = session.get('user_id') - agent_manager.change_language(id, language) - - def on_message(self, data): - print(f"Message from client: {data}") - id = session.get('user_id') - if (type(data)==str): - data = json.loads(data) - print(id) - if data['type'] == 'text': - res = agent_manager.invoke(id, data['data'], backboard_manager.get_backboard(id).get_info_prompt()) - print('=*='*20) - print(res.content) - reply = f"{res.content['speak']}" - with app.app_context(): - emit('message',reply, room=id, namespace='/agent') - emit('request_function',res.content['function'], room=id, namespace='/agent') - - if data['type'] == 'function': - agent_manager.function_call(id, data['data']) - - def on_initiative(self,data): - print("User active function call") - user_id = session['user_id'] - if data['name'] == 'sample_judge': - agent_manager.sample_judge(user_id, backboard_manager.get_backboard(user_id)) - if data['name'] == 'judge': - agent_manager.judge(user_id, backboard_manager.get_backboard(user_id)) - - - - def on_disconnect(self,data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - - -''' -Markdown to HTML -''' -# 配置文件路径 -MARKDOWN_DIR = 'books/markdown' # 存放 markdown 文件的文件夹 -STATIC_DIR = 'static' # 存放生成的 HTML 和图片资源的文件夹 -IMAGE_DIR = 'image' # 图片资源相对于 markdown 的位置 - - - -@app.route('/--markdown', methods=['GET']) -def convert_md(course_id, filename): - md_file_path = os.path.join(MARKDOWN_DIR,course_id, f'{filename}.md') - - if not os.path.exists(md_file_path): - return jsonify({'error': 'Markdown file not found'}), 404 - - # 读取 markdown 文件内容 - with open(md_file_path, 'r', encoding='utf-8') as file: - md_content = file.read() - - # 将 markdown 转换为 HTML - html_content = markdown.markdown(md_content) - # 插入 CSS 样式,限制图片最大宽度为 100%,高度自动调整 - html_with_styles = f""" - - - - - - - {html_content} - - - """ - # 保存 HTML 文件到 static 文件夹 - html_output_path = os.path.join(STATIC_DIR, f'{filename}.html') - with open(html_output_path, 'w', encoding='utf-8') as html_file: - html_file.write(html_with_styles) - - # 处理图片资源,将 image/xxx 文件夹拷贝到 static/image/xxx - image_source_dir = os.path.join(MARKDOWN_DIR,course_id, IMAGE_DIR, filename) - image_target_dir = os.path.join(STATIC_DIR, IMAGE_DIR, filename) - print(f"Copying image resources from {image_source_dir} to {image_target_dir}") - if os.path.exists(image_source_dir): - # 确保 static/image/xxx 目录存在 - if not os.path.exists(image_target_dir): - os.makedirs(image_target_dir) - - # 拷贝图片资源 - for image_file in os.listdir(image_source_dir): - full_image_file_path = os.path.join(image_source_dir, image_file) - if os.path.isfile(full_image_file_path): - shutil.copy(full_image_file_path, image_target_dir) - - return jsonify({'html_url': f'/static/{filename}.html'}) - -# 静态文件(HTML 和图片资源)的访问 -@app.route('/static/') -def serve_static(filename): - return send_from_directory(STATIC_DIR, filename) - - -''' -Vscode -''' -@app.route('/desktop///') -def desktop(user_id, course_id, chapter_id): - if 'user_id' not in session: - # return redirect(url_for('login')) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ user_id + "uuid is"+ session['user_id']) - username2uuid[user_id] = session['user_id'] - uuid2username[session['user_id']] = user_id - userid_recorder[user_id+'&'+course_id] = session['user_id'] - - # 在学习目录下创建一个名为 user_id_path 的文件夹 - path_dir = os.path.join(student_workspace_root_path, user_id, course_id,chapter_id) - os.makedirs(path_dir, exist_ok=True) - # 在此文件夹内部创建一个.config文件,并写入 user_id=user_id\n path=path - config_path = os.path.join(path_dir, '.config') - if GLOBAL_CONFIG['VSCODE_WEB_PATH']['is_wsl']: # 如果是在 WSL 中运行,则将路径转换为 WSL 路径 - path_dir = path_dir.replace('\\', '/') - path_dir = path_dir.replace(GLOBAL_CONFIG['VSCODE_WEB_PATH']['windows_path'] , GLOBAL_CONFIG['VSCODE_WEB_PATH']['wsl_path']) - with open(config_path, 'w', encoding='utf-8') as f: - tmpd = {'user_id': user_id, 'course_id': course_id, 'chapter_id': chapter_id, 'path': path_dir} - json.dump(tmpd, f) - print('---------------------') - print(config_path) - return render_template('desktop.html', vscode_web_url=VSCODE_WEB_URL, user_id=user_id, course_id=course_id, chapter_id=chapter_id, workspace_path=path_dir) - -@app.route('/desktop_nouser//') -def desktop_nouser(course_id, chapter_id): - if 'user_id' not in session: - return redirect(url_for('login')) - user_id = session['user_id'] - username = uuid2username[user_id] - return redirect(url_for('desktop', user_id=username, course_id=course_id, chapter_id=chapter_id)) - -@app.route('/vscode_data', methods=['POST']) -def vscode_data(): - data = request.json - config = data['config'] - realtime_response(config,data) - print(f"Received data from VSCode: {data}") - return jsonify({"status": "success", "received": data}) - - - -''' -Login - -''' -users_list = UserList() -course_list = CourseList() - - -@app.route('/register') -def register(): - return render_template('register.html') - -@app.route('/register_teacher') -def register_teacher(): - return render_template('register_teacher.html') - -@app.route('/register_teacher_post', methods=['POST']) -def register_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password, teacher=True) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - -@app.route('/register_post', methods=['POST']) -def register_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - - -@app.route('/login') -def login(): - return render_template('login.html') - if 'user_id' not in session: - return render_template('login.html') - else: - return redirect(url_for('/')) - -@app.route('/login_post', methods=['POST']) -def login_post(): - # 获取请求的 JSON 数据 - data = request.get_json() - - username = data.get('username') - password = data.get('password') - - pswd = users_list.get_user_pswd(username) - - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/login_teacher_post', methods=['POST']) -def login_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - pswd = users_list.get_user_pswd(username) - is_teacher = users_list.get_user_is_teacher(username) - if is_teacher is None or is_teacher == False: - return jsonify({'success': False, 'message': '用户名不存在或非教师账号'}) - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/teacherboard') -@require_role(roles="teacher") -def teacherboard(): - return render_template('teacherboard.html') - - -@app.route('/logout') -def logout(): - session.pop('user_id', None) - return redirect(url_for('login')) - -@app.route('/get_session') -def get_session(): - user_session = session.get('user_id', 'default_session') - return jsonify({"session": user_session}) - - -''' -DashBoard -''' -user_id2UserClass = {} -@app.route('/dashboard') -@require_role -def dashboard(): - user_id = session['user_id'] - username = uuid2username[user_id] - if (user_id not in user_id2UserClass): - user_id2UserClass[user_id] = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - user_course_data = [] - for course_id in user_id2UserClass[user_id].select_course: - course_brief_info = course_list.get_course_brief_info(course_id, load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR)) - user_course_data.append(course_brief_info) - return render_template('dashboard.html',user_data = user_id2UserClass[user_id].to_json_without_dialog(), user_course_data = json.dumps(user_course_data)) - -''' -Course -''' - -@app.route('/course/') -@require_role -def course(course_id): - c = load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR) - return render_template('course.html', course_id=course_id, course_data=c) - -@app.route('/select_course', methods=['POST']) -@require_role -def select_course(): - user = user_id2UserClass[session['user_id']] - data = request.get_json() - course_id = data.get('course_id') - if course_id: - user.select_new_course(course_id, load_course_from_json(course_id, COURSE_DATA_DIR)) - return jsonify({'success': True, 'message': '课程选择成功'}) - - -@app.route('/') -@require_role -def home_index(): - selected_courses=[] - if ('user_id' in session): - if (session['user_id'] not in user_id2UserClass): return redirect(url_for('login')) - user = user_id2UserClass[session['user_id']] - for course_id in user.select_course: - selected_courses.append(course_id) - - return render_template('index.html', courses_data = course_list, selected_courses =selected_courses) - -# 一些app辅助函数,主要提供给Agent与数据库的交互能力 - -class MyFunction: - def save_chapter_memory(self, id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal): - print("-=-=-=-=-=-=-=-") - print(id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - username = uuid2username[id] - u = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - u.save_chapter_memory(course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - -app.my_function = MyFunction() -if __name__ == '__main__': - socketio.on_namespace(VSCodeNamespace('/vscode')) - socketio.on_namespace(AgentNamespace('/agent')) - socketio.run(app, host='0.0.0.0', port=5551, debug=False,allow_unsafe_werkzeug=True) - diff --git a/Html/runs/run_20250908-144720_kkn0r6/code/backboardManager.py b/Html/runs/run_20250908-144720_kkn0r6/code/backboardManager.py deleted file mode 100644 index 1777f8d..0000000 --- a/Html/runs/run_20250908-144720_kkn0r6/code/backboardManager.py +++ /dev/null @@ -1,80 +0,0 @@ - - - -import time -import os - -class Backboard: - def __init__(self, user_id, username, course_id, lesson_id, root_path): - self.user_id = user_id - self.username = username - self.course_id = course_id - self.lesson_id = lesson_id - self.root_path = root_path - self.create_time = time.time() - self.enter_chapter_time = time.time() - self.history = [] - self.file_tree = "[]" - self.active_file_path = "" - self.active_file_content = "" - self.pasted_file_path = "" - self.pasted_content = "" - - - def next_chapter(self): - self.enter_chapter_time = time.time() - - def get_info_prompt(self): - - five_history = "" - for h in self.history[-5:]: - five_history += h['type'] + "\n" + h.get('filePath', '') + "\n\n" - - endl = "\n" - return (f"###Global Info:###{endl}" - f"Here are some info about now user's IDE, refer to it when you need to handle some code.{endl}" - f"- User's total study time is {self.get_deltatime_mmss(self.create_time, time.time())}{endl}" - f"- User's current chapter study time is {self.get_deltatime_mmss(self.enter_chapter_time, time.time())}{endl}" - f"- Activated file path: {self.active_file_path}{endl}" - f"```{endl}" - f"{self.active_file_content[-10:]}{endl}" - f"```{endl}" - f"- Last five action:{five_history}{endl}" - f"- File tree: {self.file_tree}{endl}") - # f"- Activated file content (current editing 10 lines): {endl}" - def add_history(self, realtime_action): - if(realtime_action['type']=='config'):return - if len(self.history)!=0: - if (self.history[-1]['type']=='fileEdit'): - if(self.history[-1]['filePath'] == realtime_action['filePath']): - self.history[-1]['content'] = realtime_action['content'] - return - self.history.append(realtime_action) - - - def get_deltatime_mmss(self, start_time, end_time): - elapsed_time = end_time - start_time - hours = int(elapsed_time // 3600) - minutes = int((elapsed_time % 3600) // 60) - seconds = int(elapsed_time % 60) - return f"{hours:02d}:{minutes:02d}:{seconds:02d}" - - - def get_active_file_reletive_path(self): - relative_path = os.path.relpath(self.active_file_path, self.root_path) - return relative_path - - - -class BackBoardManager: - def __init__(self): - self.backboards = {} # user_id: Backboard - - def add_backboard(self, user_id, username, course_id, lesson_id, root_path): - self.backboards[user_id] = Backboard(user_id,username, course_id, lesson_id, root_path) - - def get_backboard(self, user_id) -> Backboard: - return self.backboards[user_id] - - - diff --git a/Html/runs/run_20250908-144720_kkn0r6/code/bootstrap.py b/Html/runs/run_20250908-144720_kkn0r6/code/bootstrap.py deleted file mode 100644 index bcb15ce..0000000 --- a/Html/runs/run_20250908-144720_kkn0r6/code/bootstrap.py +++ /dev/null @@ -1,31 +0,0 @@ -from pathlib import Path -import sys, os - -def bootstrap_paths(): - """ - 让 'AlgoriAgent'(位于 repo_root/AlgoriAgent)可被 import; - 并提供 STUDENT_WORKSPACE_ROOT 的默认值(repo_root/study)。 - 适配当前工厂位置:repo_root/Html/apps/__init__.py - """ - here = Path(__file__).resolve() - # repo_root = .../Html/apps/../../ => parents[2] - repo_root = here.parents[2] - - # 兜底:如果目录结构变化,尝试向上搜索包含 AlgoriAgent 的目录作为 repo_root - if not (repo_root / "AlgoriAgent").exists(): - for p in here.parents: - if (p / "AlgoriAgent").is_dir(): - repo_root = p - break - - # 确保仓库根在 sys.path(这样 'AlgoriAgent' 顶层包可被发现) - repo_root_str = str(repo_root) - if repo_root_str not in sys.path: - sys.path.insert(0, repo_root_str) - - # 可选:如果你还有其它顶层包,也可在此处继续插入 - - # 默认学习工作区目录(也可放到 config.ini / 环境变量覆盖) - os.environ.setdefault("STUDENT_WORKSPACE_ROOT", str(repo_root / "study")) - - return repo_root # 方便调试/日志 \ No newline at end of file diff --git a/Html/runs/run_20250908-144720_kkn0r6/code/wsgi.py b/Html/runs/run_20250908-144720_kkn0r6/code/wsgi.py deleted file mode 100644 index bbcbe5f..0000000 --- a/Html/runs/run_20250908-144720_kkn0r6/code/wsgi.py +++ /dev/null @@ -1,6 +0,0 @@ -# wsgi.py -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -# 提供一个可被 WSGI/进程管理器导入的 app 对象 -app = create_app() diff --git a/Html/runs/run_20250908-144720_kkn0r6/logging.chat b/Html/runs/run_20250908-144720_kkn0r6/logging.chat deleted file mode 100644 index e69de29..0000000 diff --git a/Html/runs/run_20250908-144720_kkn0r6/logging.log b/Html/runs/run_20250908-144720_kkn0r6/logging.log deleted file mode 100644 index 70b0462..0000000 --- a/Html/runs/run_20250908-144720_kkn0r6/logging.log +++ /dev/null @@ -1 +0,0 @@ -2025-09-08 14:47:28.122 | INFO | agentscope.models:read_model_configs:186 - Load configs for model wrapper: openai_cfg diff --git a/Html/runs/run_20250908-145013_ycavxx/.config b/Html/runs/run_20250908-145013_ycavxx/.config deleted file mode 100644 index 7c7b3c4..0000000 --- a/Html/runs/run_20250908-145013_ycavxx/.config +++ /dev/null @@ -1,7 +0,0 @@ -{ - "project": "Pke2On", - "name": "ycavxx", - "run_id": "run_20250908-145013_ycavxx", - "timestamp": "2025-09-08 14:50:13", - "pid": 3790 -} \ No newline at end of file diff --git a/Html/runs/run_20250908-145013_ycavxx/agentscope.db b/Html/runs/run_20250908-145013_ycavxx/agentscope.db deleted file mode 100644 index 666055b77679cda29c14fcf23b4ef1d039c5b52a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI%L2KJE6bEoS4Q(k)+glI2yjv3-0%NB!Hs&O1YUav`W0U1F<0V=#BsNLx(sSu$ z>=W&q?4#^B$!*yt2YT5l`~^0a^z(#~{ zkyg6w!t)u0!@f%5aeaJcfD9*Q_b$ozCY8>~CFA6|{Z2V!N;Z^cIq}eS$>x3HY|^=j z7lokrf1)Z$x@_R^N~@apn7OPMkZ(I<*1WJCw@v3GWy2n6&RcIQ0~zlR_x8^$%be!% zmxb7@7V;}H+K5#l(wSbZKXKY!mys6ROyi|!%aN@+%REpi?;B-K4PC3&{>iCzQnNB+ zwbW!z4iA{x(V_2L+5VJ1vMJeN;5l68yJ9?OZyl-TNCEp4P{^H8$cTGExdq$9ANE6@ zA@`ZUhb>is+Y=S?%$C1fnN{muZU1a!nMRV%#qFbMT;y3hf|KlJ)00Izz00bZa0SG_<0uX=z1a@EGHy1PL*Z=?k diff --git a/Html/runs/run_20250908-145013_ycavxx/code/app.py b/Html/runs/run_20250908-145013_ycavxx/code/app.py deleted file mode 100644 index b761bd2..0000000 --- a/Html/runs/run_20250908-145013_ycavxx/code/app.py +++ /dev/null @@ -1,20 +0,0 @@ -# app.py 0.1.1 rise to factory mode -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -from apps.extensions import socketio - -# 工厂创建 app,工厂里已经做了:加载配置/注册蓝图/注册 namespaces -app = create_app() - -if __name__ == "__main__": - # 仅本地开发用;生产不要用 werkzeug 自带的开发服务器 - socketio.run( - app, - host="0.0.0.0", - port=5551, - debug=False, # 开发期打开 - allow_unsafe_werkzeug=True # 避免 dev server 的安全限制提示 - ) - - diff --git a/Html/runs/run_20250908-145013_ycavxx/code/app_back.py b/Html/runs/run_20250908-145013_ycavxx/code/app_back.py deleted file mode 100644 index 246853c..0000000 --- a/Html/runs/run_20250908-145013_ycavxx/code/app_back.py +++ /dev/null @@ -1,480 +0,0 @@ -from bootstrap import bootstrap_paths -bootstrap_paths() -from functools import wraps -from flask import Flask, redirect, session, request, jsonify, render_template, send_from_directory, url_for -from flask_cors import CORS -from flask_socketio import SocketIO, join_room, emit, Namespace -import markdown -import os -import uuid -import shutil -import sys -import json -from apps.auth.decorators import require_role -parent_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) -sys.path.insert(0, parent_dir) -student_workspace_root_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../study')) -current_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '.')) -sys.path.insert(0, current_dir) -from AlgoriAgent.projects.algoriAgent.agent_manager import AgentManager - - -import configparser - -from db.user_list import UserList -from db.user import User, load_user_from_json, create_user_json -from db.course_list import CourseList -from db.course import Course, load_course_from_json -GLOBAL_CONFIG = configparser.ConfigParser() -GLOBAL_CONFIG.read('config.ini') -VSCODE_WEB_URL = GLOBAL_CONFIG['VSCODE_WEB']['url'] -USER_DATA_DIR = GLOBAL_CONFIG['USER_DATA']['dir'] -COURSE_DATA_DIR = GLOBAL_CONFIG['COURSE_DATA']['dir'] - -app = Flask(__name__) -socketio = SocketIO(app, cors_allowed_origins="*",ping_timeout=60, ping_interval=5) -# socketio = SocketIO(app, cors_allowed_origins="http://localhost:9888") # 设置跨域支持 -import logging -app.secret_key = 'cakebaker' -app.logger.setLevel(logging.DEBUG) -# 配置 CORS -CORS(app, resources={r"/*": {"origins": VSCODE_WEB_URL},}, supports_credentials=True) - - -userid_recorder = {} # user_id&path -> session['user_id'] - -''' -Backboard -''' -from backboardManager import BackBoardManager, Backboard - -backboard_manager = BackBoardManager() -uuid2username = {} -username2uuid = {} - - - -# 定义命名空间:用于和 VSCode 插件交流 -class VSCodeNamespace(Namespace): - def on_login(self,data): - print("VSCode client connected") - print(data) - dataconfig = data['config'] - user_id = dataconfig.get('user_id') - path = dataconfig.get('path') - course_id = dataconfig.get('course_id') - lesson_id = dataconfig.get('chapter_id') - print(f"User {user_id} connected with path: {path}") - useruuid = username2uuid[user_id] - join_room(useruuid, namespace='/vscode') - if backboard_manager.get_backboard(useruuid) == None: - backboard_manager.add_backboard(useruuid,user_id, course_id, lesson_id, path) - - - def on_message(self, data): - print(f"Received from VSCode client: {data}") - dataconfig = data['config'] - realtime_response(dataconfig, data) - # emit('response', {'message': 'Config data received and connection established'}) - def on_disconnect(self, data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - -def realtime_response(config, realtime_action): - user_id = config['user_id'] - folder_path = config['path'] - useruuid = username2uuid[user_id] - bb = backboard_manager.get_backboard(useruuid) - assert type(bb) == Backboard - - bb.add_history(realtime_action) - - if realtime_action['type'] == 'workspaceFolders': - bb.file_tree = realtime_action['fileTree'] - - if realtime_action['type'] == 'activeFile': - file_path = realtime_action['filePath'] - assert type(file_path) == str - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - if realtime_action['type'] == 'paste': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.pasted_file_path = file_path - bb.pasted_content = realtime_action['content'] - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - if realtime_action['type'] == 'fileEdit': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - - - print("config"+str(config)) - print("realtime_action"+str(realtime_action)) - pass - - -''' -Agent and Chat -''' -agent_manager = AgentManager(app = app, socketio = socketio) -user_threads = {} -import threading -from concurrent.futures import ThreadPoolExecutor, as_completed - -# 初始化线程池 -executor = ThreadPoolExecutor(max_workers=10) -class AgentNamespace(Namespace): - def on_login(self, data): - data = json.loads(data) - user = data['username'] - course_id = data['course_id'] - chapter_id = data['chapter_id'] - user_uuid = username2uuid[user] - session['user_id'] = user_uuid - print(f'User connected with session user_id: {user_uuid}') - # 从markdown、markdown_prompts、score_prompts中各读取数据folder.md并进行new_agent - with open(f'books/markdown/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fmd,\ - open(f'books/markdown_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8')as fmdp,\ - open(f'books/score_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fsp: - markdown = fmd.read() - markdown_prompts = fmdp.read() - score_prompts = fsp.read() - user_uuid, agent = agent_manager.new_agent(course_id, chapter_id, markdown, markdown_prompts, score_prompts, id=user_uuid, - root_path=f'../../study/{user}/{course_id}/{chapter_id}') - print(user_uuid) - join_room(user_uuid, namespace='/agent') # 将该用户加入以user_id为名的room - backboard_manager.add_backboard(user_uuid, user, course_id, chapter_id, root_path=f'../../study/{user}/{course_id}/{chapter_id}') - - def on_language(self, language): - id = session.get('user_id') - agent_manager.change_language(id, language) - - def on_message(self, data): - print(f"Message from client: {data}") - id = session.get('user_id') - if (type(data)==str): - data = json.loads(data) - print(id) - if data['type'] == 'text': - res = agent_manager.invoke(id, data['data'], backboard_manager.get_backboard(id).get_info_prompt()) - print('=*='*20) - print(res.content) - reply = f"{res.content['speak']}" - with app.app_context(): - emit('message',reply, room=id, namespace='/agent') - emit('request_function',res.content['function'], room=id, namespace='/agent') - - if data['type'] == 'function': - agent_manager.function_call(id, data['data']) - - def on_initiative(self,data): - print("User active function call") - user_id = session['user_id'] - if data['name'] == 'sample_judge': - agent_manager.sample_judge(user_id, backboard_manager.get_backboard(user_id)) - if data['name'] == 'judge': - agent_manager.judge(user_id, backboard_manager.get_backboard(user_id)) - - - - def on_disconnect(self,data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - - -''' -Markdown to HTML -''' -# 配置文件路径 -MARKDOWN_DIR = 'books/markdown' # 存放 markdown 文件的文件夹 -STATIC_DIR = 'static' # 存放生成的 HTML 和图片资源的文件夹 -IMAGE_DIR = 'image' # 图片资源相对于 markdown 的位置 - - - -@app.route('/--markdown', methods=['GET']) -def convert_md(course_id, filename): - md_file_path = os.path.join(MARKDOWN_DIR,course_id, f'{filename}.md') - - if not os.path.exists(md_file_path): - return jsonify({'error': 'Markdown file not found'}), 404 - - # 读取 markdown 文件内容 - with open(md_file_path, 'r', encoding='utf-8') as file: - md_content = file.read() - - # 将 markdown 转换为 HTML - html_content = markdown.markdown(md_content) - # 插入 CSS 样式,限制图片最大宽度为 100%,高度自动调整 - html_with_styles = f""" - - - - - - - {html_content} - - - """ - # 保存 HTML 文件到 static 文件夹 - html_output_path = os.path.join(STATIC_DIR, f'{filename}.html') - with open(html_output_path, 'w', encoding='utf-8') as html_file: - html_file.write(html_with_styles) - - # 处理图片资源,将 image/xxx 文件夹拷贝到 static/image/xxx - image_source_dir = os.path.join(MARKDOWN_DIR,course_id, IMAGE_DIR, filename) - image_target_dir = os.path.join(STATIC_DIR, IMAGE_DIR, filename) - print(f"Copying image resources from {image_source_dir} to {image_target_dir}") - if os.path.exists(image_source_dir): - # 确保 static/image/xxx 目录存在 - if not os.path.exists(image_target_dir): - os.makedirs(image_target_dir) - - # 拷贝图片资源 - for image_file in os.listdir(image_source_dir): - full_image_file_path = os.path.join(image_source_dir, image_file) - if os.path.isfile(full_image_file_path): - shutil.copy(full_image_file_path, image_target_dir) - - return jsonify({'html_url': f'/static/{filename}.html'}) - -# 静态文件(HTML 和图片资源)的访问 -@app.route('/static/') -def serve_static(filename): - return send_from_directory(STATIC_DIR, filename) - - -''' -Vscode -''' -@app.route('/desktop///') -def desktop(user_id, course_id, chapter_id): - if 'user_id' not in session: - # return redirect(url_for('login')) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ user_id + "uuid is"+ session['user_id']) - username2uuid[user_id] = session['user_id'] - uuid2username[session['user_id']] = user_id - userid_recorder[user_id+'&'+course_id] = session['user_id'] - - # 在学习目录下创建一个名为 user_id_path 的文件夹 - path_dir = os.path.join(student_workspace_root_path, user_id, course_id,chapter_id) - os.makedirs(path_dir, exist_ok=True) - # 在此文件夹内部创建一个.config文件,并写入 user_id=user_id\n path=path - config_path = os.path.join(path_dir, '.config') - if GLOBAL_CONFIG['VSCODE_WEB_PATH']['is_wsl']: # 如果是在 WSL 中运行,则将路径转换为 WSL 路径 - path_dir = path_dir.replace('\\', '/') - path_dir = path_dir.replace(GLOBAL_CONFIG['VSCODE_WEB_PATH']['windows_path'] , GLOBAL_CONFIG['VSCODE_WEB_PATH']['wsl_path']) - with open(config_path, 'w', encoding='utf-8') as f: - tmpd = {'user_id': user_id, 'course_id': course_id, 'chapter_id': chapter_id, 'path': path_dir} - json.dump(tmpd, f) - print('---------------------') - print(config_path) - return render_template('desktop.html', vscode_web_url=VSCODE_WEB_URL, user_id=user_id, course_id=course_id, chapter_id=chapter_id, workspace_path=path_dir) - -@app.route('/desktop_nouser//') -def desktop_nouser(course_id, chapter_id): - if 'user_id' not in session: - return redirect(url_for('login')) - user_id = session['user_id'] - username = uuid2username[user_id] - return redirect(url_for('desktop', user_id=username, course_id=course_id, chapter_id=chapter_id)) - -@app.route('/vscode_data', methods=['POST']) -def vscode_data(): - data = request.json - config = data['config'] - realtime_response(config,data) - print(f"Received data from VSCode: {data}") - return jsonify({"status": "success", "received": data}) - - - -''' -Login - -''' -users_list = UserList() -course_list = CourseList() - - -@app.route('/register') -def register(): - return render_template('register.html') - -@app.route('/register_teacher') -def register_teacher(): - return render_template('register_teacher.html') - -@app.route('/register_teacher_post', methods=['POST']) -def register_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password, teacher=True) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - -@app.route('/register_post', methods=['POST']) -def register_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - - -@app.route('/login') -def login(): - return render_template('login.html') - if 'user_id' not in session: - return render_template('login.html') - else: - return redirect(url_for('/')) - -@app.route('/login_post', methods=['POST']) -def login_post(): - # 获取请求的 JSON 数据 - data = request.get_json() - - username = data.get('username') - password = data.get('password') - - pswd = users_list.get_user_pswd(username) - - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/login_teacher_post', methods=['POST']) -def login_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - pswd = users_list.get_user_pswd(username) - is_teacher = users_list.get_user_is_teacher(username) - if is_teacher is None or is_teacher == False: - return jsonify({'success': False, 'message': '用户名不存在或非教师账号'}) - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/teacherboard') -@require_role(roles="teacher") -def teacherboard(): - return render_template('teacherboard.html') - - -@app.route('/logout') -def logout(): - session.pop('user_id', None) - return redirect(url_for('login')) - -@app.route('/get_session') -def get_session(): - user_session = session.get('user_id', 'default_session') - return jsonify({"session": user_session}) - - -''' -DashBoard -''' -user_id2UserClass = {} -@app.route('/dashboard') -@require_role -def dashboard(): - user_id = session['user_id'] - username = uuid2username[user_id] - if (user_id not in user_id2UserClass): - user_id2UserClass[user_id] = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - user_course_data = [] - for course_id in user_id2UserClass[user_id].select_course: - course_brief_info = course_list.get_course_brief_info(course_id, load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR)) - user_course_data.append(course_brief_info) - return render_template('dashboard.html',user_data = user_id2UserClass[user_id].to_json_without_dialog(), user_course_data = json.dumps(user_course_data)) - -''' -Course -''' - -@app.route('/course/') -@require_role -def course(course_id): - c = load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR) - return render_template('course.html', course_id=course_id, course_data=c) - -@app.route('/select_course', methods=['POST']) -@require_role -def select_course(): - user = user_id2UserClass[session['user_id']] - data = request.get_json() - course_id = data.get('course_id') - if course_id: - user.select_new_course(course_id, load_course_from_json(course_id, COURSE_DATA_DIR)) - return jsonify({'success': True, 'message': '课程选择成功'}) - - -@app.route('/') -@require_role -def home_index(): - selected_courses=[] - if ('user_id' in session): - if (session['user_id'] not in user_id2UserClass): return redirect(url_for('login')) - user = user_id2UserClass[session['user_id']] - for course_id in user.select_course: - selected_courses.append(course_id) - - return render_template('index.html', courses_data = course_list, selected_courses =selected_courses) - -# 一些app辅助函数,主要提供给Agent与数据库的交互能力 - -class MyFunction: - def save_chapter_memory(self, id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal): - print("-=-=-=-=-=-=-=-") - print(id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - username = uuid2username[id] - u = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - u.save_chapter_memory(course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - -app.my_function = MyFunction() -if __name__ == '__main__': - socketio.on_namespace(VSCodeNamespace('/vscode')) - socketio.on_namespace(AgentNamespace('/agent')) - socketio.run(app, host='0.0.0.0', port=5551, debug=False,allow_unsafe_werkzeug=True) - diff --git a/Html/runs/run_20250908-145013_ycavxx/code/backboardManager.py b/Html/runs/run_20250908-145013_ycavxx/code/backboardManager.py deleted file mode 100644 index 1777f8d..0000000 --- a/Html/runs/run_20250908-145013_ycavxx/code/backboardManager.py +++ /dev/null @@ -1,80 +0,0 @@ - - - -import time -import os - -class Backboard: - def __init__(self, user_id, username, course_id, lesson_id, root_path): - self.user_id = user_id - self.username = username - self.course_id = course_id - self.lesson_id = lesson_id - self.root_path = root_path - self.create_time = time.time() - self.enter_chapter_time = time.time() - self.history = [] - self.file_tree = "[]" - self.active_file_path = "" - self.active_file_content = "" - self.pasted_file_path = "" - self.pasted_content = "" - - - def next_chapter(self): - self.enter_chapter_time = time.time() - - def get_info_prompt(self): - - five_history = "" - for h in self.history[-5:]: - five_history += h['type'] + "\n" + h.get('filePath', '') + "\n\n" - - endl = "\n" - return (f"###Global Info:###{endl}" - f"Here are some info about now user's IDE, refer to it when you need to handle some code.{endl}" - f"- User's total study time is {self.get_deltatime_mmss(self.create_time, time.time())}{endl}" - f"- User's current chapter study time is {self.get_deltatime_mmss(self.enter_chapter_time, time.time())}{endl}" - f"- Activated file path: {self.active_file_path}{endl}" - f"```{endl}" - f"{self.active_file_content[-10:]}{endl}" - f"```{endl}" - f"- Last five action:{five_history}{endl}" - f"- File tree: {self.file_tree}{endl}") - # f"- Activated file content (current editing 10 lines): {endl}" - def add_history(self, realtime_action): - if(realtime_action['type']=='config'):return - if len(self.history)!=0: - if (self.history[-1]['type']=='fileEdit'): - if(self.history[-1]['filePath'] == realtime_action['filePath']): - self.history[-1]['content'] = realtime_action['content'] - return - self.history.append(realtime_action) - - - def get_deltatime_mmss(self, start_time, end_time): - elapsed_time = end_time - start_time - hours = int(elapsed_time // 3600) - minutes = int((elapsed_time % 3600) // 60) - seconds = int(elapsed_time % 60) - return f"{hours:02d}:{minutes:02d}:{seconds:02d}" - - - def get_active_file_reletive_path(self): - relative_path = os.path.relpath(self.active_file_path, self.root_path) - return relative_path - - - -class BackBoardManager: - def __init__(self): - self.backboards = {} # user_id: Backboard - - def add_backboard(self, user_id, username, course_id, lesson_id, root_path): - self.backboards[user_id] = Backboard(user_id,username, course_id, lesson_id, root_path) - - def get_backboard(self, user_id) -> Backboard: - return self.backboards[user_id] - - - diff --git a/Html/runs/run_20250908-145013_ycavxx/code/bootstrap.py b/Html/runs/run_20250908-145013_ycavxx/code/bootstrap.py deleted file mode 100644 index bcb15ce..0000000 --- a/Html/runs/run_20250908-145013_ycavxx/code/bootstrap.py +++ /dev/null @@ -1,31 +0,0 @@ -from pathlib import Path -import sys, os - -def bootstrap_paths(): - """ - 让 'AlgoriAgent'(位于 repo_root/AlgoriAgent)可被 import; - 并提供 STUDENT_WORKSPACE_ROOT 的默认值(repo_root/study)。 - 适配当前工厂位置:repo_root/Html/apps/__init__.py - """ - here = Path(__file__).resolve() - # repo_root = .../Html/apps/../../ => parents[2] - repo_root = here.parents[2] - - # 兜底:如果目录结构变化,尝试向上搜索包含 AlgoriAgent 的目录作为 repo_root - if not (repo_root / "AlgoriAgent").exists(): - for p in here.parents: - if (p / "AlgoriAgent").is_dir(): - repo_root = p - break - - # 确保仓库根在 sys.path(这样 'AlgoriAgent' 顶层包可被发现) - repo_root_str = str(repo_root) - if repo_root_str not in sys.path: - sys.path.insert(0, repo_root_str) - - # 可选:如果你还有其它顶层包,也可在此处继续插入 - - # 默认学习工作区目录(也可放到 config.ini / 环境变量覆盖) - os.environ.setdefault("STUDENT_WORKSPACE_ROOT", str(repo_root / "study")) - - return repo_root # 方便调试/日志 \ No newline at end of file diff --git a/Html/runs/run_20250908-145013_ycavxx/code/wsgi.py b/Html/runs/run_20250908-145013_ycavxx/code/wsgi.py deleted file mode 100644 index bbcbe5f..0000000 --- a/Html/runs/run_20250908-145013_ycavxx/code/wsgi.py +++ /dev/null @@ -1,6 +0,0 @@ -# wsgi.py -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -# 提供一个可被 WSGI/进程管理器导入的 app 对象 -app = create_app() diff --git a/Html/runs/run_20250908-145013_ycavxx/logging.chat b/Html/runs/run_20250908-145013_ycavxx/logging.chat deleted file mode 100644 index e69de29..0000000 diff --git a/Html/runs/run_20250908-145013_ycavxx/logging.log b/Html/runs/run_20250908-145013_ycavxx/logging.log deleted file mode 100644 index aa221a2..0000000 --- a/Html/runs/run_20250908-145013_ycavxx/logging.log +++ /dev/null @@ -1 +0,0 @@ -2025-09-08 14:50:17.500 | INFO | agentscope.models:read_model_configs:186 - Load configs for model wrapper: openai_cfg diff --git a/Html/runs/run_20250911-033735_3vhfbh/.config b/Html/runs/run_20250911-033735_3vhfbh/.config deleted file mode 100644 index ca48838..0000000 --- a/Html/runs/run_20250911-033735_3vhfbh/.config +++ /dev/null @@ -1,7 +0,0 @@ -{ - "project": "3mAqiD", - "name": "3vhfbh", - "run_id": "run_20250911-033735_3vhfbh", - "timestamp": "2025-09-11 03:37:35", - "pid": 14599 -} \ No newline at end of file diff --git a/Html/runs/run_20250911-033735_3vhfbh/agentscope.db b/Html/runs/run_20250911-033735_3vhfbh/agentscope.db deleted file mode 100644 index 666055b77679cda29c14fcf23b4ef1d039c5b52a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI%L2KJE6bEoS4Q(k)+glI2yjv3-0%NB!Hs&O1YUav`W0U1F<0V=#BsNLx(sSu$ z>=W&q?4#^B$!*yt2YT5l`~^0a^z(#~{ zkyg6w!t)u0!@f%5aeaJcfD9*Q_b$ozCY8>~CFA6|{Z2V!N;Z^cIq}eS$>x3HY|^=j z7lokrf1)Z$x@_R^N~@apn7OPMkZ(I<*1WJCw@v3GWy2n6&RcIQ0~zlR_x8^$%be!% zmxb7@7V;}H+K5#l(wSbZKXKY!mys6ROyi|!%aN@+%REpi?;B-K4PC3&{>iCzQnNB+ zwbW!z4iA{x(V_2L+5VJ1vMJeN;5l68yJ9?OZyl-TNCEp4P{^H8$cTGExdq$9ANE6@ zA@`ZUhb>is+Y=S?%$C1fnN{muZU1a!nMRV%#qFbMT;y3hf|KlJ)00Izz00bZa0SG_<0uX=z1a@EGHy1PL*Z=?k diff --git a/Html/runs/run_20250911-033735_3vhfbh/code/app.py b/Html/runs/run_20250911-033735_3vhfbh/code/app.py deleted file mode 100644 index c7f31f7..0000000 --- a/Html/runs/run_20250911-033735_3vhfbh/code/app.py +++ /dev/null @@ -1,21 +0,0 @@ -# app.py 0.1.1 rise to factory mode -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -from apps.extensions import socketio - -# 工厂创建 app,工厂里已经做了:加载配置/注册蓝图/注册 namespaces -app = create_app() - -if __name__ == "__main__": - # 仅本地开发用;生产不要用 werkzeug 自带的开发服务器 - socketio.run( - app, - host="0.0.0.0", - port=5551, - debug=True, # 开发期打开 - allow_unsafe_werkzeug=True, # 避免 dev server 的安全限制提示 - # ssl_context=('server.crt', 'server.key') - ) - - diff --git a/Html/runs/run_20250911-033735_3vhfbh/code/app_back.py b/Html/runs/run_20250911-033735_3vhfbh/code/app_back.py deleted file mode 100644 index 246853c..0000000 --- a/Html/runs/run_20250911-033735_3vhfbh/code/app_back.py +++ /dev/null @@ -1,480 +0,0 @@ -from bootstrap import bootstrap_paths -bootstrap_paths() -from functools import wraps -from flask import Flask, redirect, session, request, jsonify, render_template, send_from_directory, url_for -from flask_cors import CORS -from flask_socketio import SocketIO, join_room, emit, Namespace -import markdown -import os -import uuid -import shutil -import sys -import json -from apps.auth.decorators import require_role -parent_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) -sys.path.insert(0, parent_dir) -student_workspace_root_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../study')) -current_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '.')) -sys.path.insert(0, current_dir) -from AlgoriAgent.projects.algoriAgent.agent_manager import AgentManager - - -import configparser - -from db.user_list import UserList -from db.user import User, load_user_from_json, create_user_json -from db.course_list import CourseList -from db.course import Course, load_course_from_json -GLOBAL_CONFIG = configparser.ConfigParser() -GLOBAL_CONFIG.read('config.ini') -VSCODE_WEB_URL = GLOBAL_CONFIG['VSCODE_WEB']['url'] -USER_DATA_DIR = GLOBAL_CONFIG['USER_DATA']['dir'] -COURSE_DATA_DIR = GLOBAL_CONFIG['COURSE_DATA']['dir'] - -app = Flask(__name__) -socketio = SocketIO(app, cors_allowed_origins="*",ping_timeout=60, ping_interval=5) -# socketio = SocketIO(app, cors_allowed_origins="http://localhost:9888") # 设置跨域支持 -import logging -app.secret_key = 'cakebaker' -app.logger.setLevel(logging.DEBUG) -# 配置 CORS -CORS(app, resources={r"/*": {"origins": VSCODE_WEB_URL},}, supports_credentials=True) - - -userid_recorder = {} # user_id&path -> session['user_id'] - -''' -Backboard -''' -from backboardManager import BackBoardManager, Backboard - -backboard_manager = BackBoardManager() -uuid2username = {} -username2uuid = {} - - - -# 定义命名空间:用于和 VSCode 插件交流 -class VSCodeNamespace(Namespace): - def on_login(self,data): - print("VSCode client connected") - print(data) - dataconfig = data['config'] - user_id = dataconfig.get('user_id') - path = dataconfig.get('path') - course_id = dataconfig.get('course_id') - lesson_id = dataconfig.get('chapter_id') - print(f"User {user_id} connected with path: {path}") - useruuid = username2uuid[user_id] - join_room(useruuid, namespace='/vscode') - if backboard_manager.get_backboard(useruuid) == None: - backboard_manager.add_backboard(useruuid,user_id, course_id, lesson_id, path) - - - def on_message(self, data): - print(f"Received from VSCode client: {data}") - dataconfig = data['config'] - realtime_response(dataconfig, data) - # emit('response', {'message': 'Config data received and connection established'}) - def on_disconnect(self, data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - -def realtime_response(config, realtime_action): - user_id = config['user_id'] - folder_path = config['path'] - useruuid = username2uuid[user_id] - bb = backboard_manager.get_backboard(useruuid) - assert type(bb) == Backboard - - bb.add_history(realtime_action) - - if realtime_action['type'] == 'workspaceFolders': - bb.file_tree = realtime_action['fileTree'] - - if realtime_action['type'] == 'activeFile': - file_path = realtime_action['filePath'] - assert type(file_path) == str - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - if realtime_action['type'] == 'paste': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.pasted_file_path = file_path - bb.pasted_content = realtime_action['content'] - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - if realtime_action['type'] == 'fileEdit': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - - - print("config"+str(config)) - print("realtime_action"+str(realtime_action)) - pass - - -''' -Agent and Chat -''' -agent_manager = AgentManager(app = app, socketio = socketio) -user_threads = {} -import threading -from concurrent.futures import ThreadPoolExecutor, as_completed - -# 初始化线程池 -executor = ThreadPoolExecutor(max_workers=10) -class AgentNamespace(Namespace): - def on_login(self, data): - data = json.loads(data) - user = data['username'] - course_id = data['course_id'] - chapter_id = data['chapter_id'] - user_uuid = username2uuid[user] - session['user_id'] = user_uuid - print(f'User connected with session user_id: {user_uuid}') - # 从markdown、markdown_prompts、score_prompts中各读取数据folder.md并进行new_agent - with open(f'books/markdown/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fmd,\ - open(f'books/markdown_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8')as fmdp,\ - open(f'books/score_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fsp: - markdown = fmd.read() - markdown_prompts = fmdp.read() - score_prompts = fsp.read() - user_uuid, agent = agent_manager.new_agent(course_id, chapter_id, markdown, markdown_prompts, score_prompts, id=user_uuid, - root_path=f'../../study/{user}/{course_id}/{chapter_id}') - print(user_uuid) - join_room(user_uuid, namespace='/agent') # 将该用户加入以user_id为名的room - backboard_manager.add_backboard(user_uuid, user, course_id, chapter_id, root_path=f'../../study/{user}/{course_id}/{chapter_id}') - - def on_language(self, language): - id = session.get('user_id') - agent_manager.change_language(id, language) - - def on_message(self, data): - print(f"Message from client: {data}") - id = session.get('user_id') - if (type(data)==str): - data = json.loads(data) - print(id) - if data['type'] == 'text': - res = agent_manager.invoke(id, data['data'], backboard_manager.get_backboard(id).get_info_prompt()) - print('=*='*20) - print(res.content) - reply = f"{res.content['speak']}" - with app.app_context(): - emit('message',reply, room=id, namespace='/agent') - emit('request_function',res.content['function'], room=id, namespace='/agent') - - if data['type'] == 'function': - agent_manager.function_call(id, data['data']) - - def on_initiative(self,data): - print("User active function call") - user_id = session['user_id'] - if data['name'] == 'sample_judge': - agent_manager.sample_judge(user_id, backboard_manager.get_backboard(user_id)) - if data['name'] == 'judge': - agent_manager.judge(user_id, backboard_manager.get_backboard(user_id)) - - - - def on_disconnect(self,data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - - -''' -Markdown to HTML -''' -# 配置文件路径 -MARKDOWN_DIR = 'books/markdown' # 存放 markdown 文件的文件夹 -STATIC_DIR = 'static' # 存放生成的 HTML 和图片资源的文件夹 -IMAGE_DIR = 'image' # 图片资源相对于 markdown 的位置 - - - -@app.route('/--markdown', methods=['GET']) -def convert_md(course_id, filename): - md_file_path = os.path.join(MARKDOWN_DIR,course_id, f'{filename}.md') - - if not os.path.exists(md_file_path): - return jsonify({'error': 'Markdown file not found'}), 404 - - # 读取 markdown 文件内容 - with open(md_file_path, 'r', encoding='utf-8') as file: - md_content = file.read() - - # 将 markdown 转换为 HTML - html_content = markdown.markdown(md_content) - # 插入 CSS 样式,限制图片最大宽度为 100%,高度自动调整 - html_with_styles = f""" - - - - - - - {html_content} - - - """ - # 保存 HTML 文件到 static 文件夹 - html_output_path = os.path.join(STATIC_DIR, f'{filename}.html') - with open(html_output_path, 'w', encoding='utf-8') as html_file: - html_file.write(html_with_styles) - - # 处理图片资源,将 image/xxx 文件夹拷贝到 static/image/xxx - image_source_dir = os.path.join(MARKDOWN_DIR,course_id, IMAGE_DIR, filename) - image_target_dir = os.path.join(STATIC_DIR, IMAGE_DIR, filename) - print(f"Copying image resources from {image_source_dir} to {image_target_dir}") - if os.path.exists(image_source_dir): - # 确保 static/image/xxx 目录存在 - if not os.path.exists(image_target_dir): - os.makedirs(image_target_dir) - - # 拷贝图片资源 - for image_file in os.listdir(image_source_dir): - full_image_file_path = os.path.join(image_source_dir, image_file) - if os.path.isfile(full_image_file_path): - shutil.copy(full_image_file_path, image_target_dir) - - return jsonify({'html_url': f'/static/{filename}.html'}) - -# 静态文件(HTML 和图片资源)的访问 -@app.route('/static/') -def serve_static(filename): - return send_from_directory(STATIC_DIR, filename) - - -''' -Vscode -''' -@app.route('/desktop///') -def desktop(user_id, course_id, chapter_id): - if 'user_id' not in session: - # return redirect(url_for('login')) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ user_id + "uuid is"+ session['user_id']) - username2uuid[user_id] = session['user_id'] - uuid2username[session['user_id']] = user_id - userid_recorder[user_id+'&'+course_id] = session['user_id'] - - # 在学习目录下创建一个名为 user_id_path 的文件夹 - path_dir = os.path.join(student_workspace_root_path, user_id, course_id,chapter_id) - os.makedirs(path_dir, exist_ok=True) - # 在此文件夹内部创建一个.config文件,并写入 user_id=user_id\n path=path - config_path = os.path.join(path_dir, '.config') - if GLOBAL_CONFIG['VSCODE_WEB_PATH']['is_wsl']: # 如果是在 WSL 中运行,则将路径转换为 WSL 路径 - path_dir = path_dir.replace('\\', '/') - path_dir = path_dir.replace(GLOBAL_CONFIG['VSCODE_WEB_PATH']['windows_path'] , GLOBAL_CONFIG['VSCODE_WEB_PATH']['wsl_path']) - with open(config_path, 'w', encoding='utf-8') as f: - tmpd = {'user_id': user_id, 'course_id': course_id, 'chapter_id': chapter_id, 'path': path_dir} - json.dump(tmpd, f) - print('---------------------') - print(config_path) - return render_template('desktop.html', vscode_web_url=VSCODE_WEB_URL, user_id=user_id, course_id=course_id, chapter_id=chapter_id, workspace_path=path_dir) - -@app.route('/desktop_nouser//') -def desktop_nouser(course_id, chapter_id): - if 'user_id' not in session: - return redirect(url_for('login')) - user_id = session['user_id'] - username = uuid2username[user_id] - return redirect(url_for('desktop', user_id=username, course_id=course_id, chapter_id=chapter_id)) - -@app.route('/vscode_data', methods=['POST']) -def vscode_data(): - data = request.json - config = data['config'] - realtime_response(config,data) - print(f"Received data from VSCode: {data}") - return jsonify({"status": "success", "received": data}) - - - -''' -Login - -''' -users_list = UserList() -course_list = CourseList() - - -@app.route('/register') -def register(): - return render_template('register.html') - -@app.route('/register_teacher') -def register_teacher(): - return render_template('register_teacher.html') - -@app.route('/register_teacher_post', methods=['POST']) -def register_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password, teacher=True) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - -@app.route('/register_post', methods=['POST']) -def register_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - - -@app.route('/login') -def login(): - return render_template('login.html') - if 'user_id' not in session: - return render_template('login.html') - else: - return redirect(url_for('/')) - -@app.route('/login_post', methods=['POST']) -def login_post(): - # 获取请求的 JSON 数据 - data = request.get_json() - - username = data.get('username') - password = data.get('password') - - pswd = users_list.get_user_pswd(username) - - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/login_teacher_post', methods=['POST']) -def login_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - pswd = users_list.get_user_pswd(username) - is_teacher = users_list.get_user_is_teacher(username) - if is_teacher is None or is_teacher == False: - return jsonify({'success': False, 'message': '用户名不存在或非教师账号'}) - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/teacherboard') -@require_role(roles="teacher") -def teacherboard(): - return render_template('teacherboard.html') - - -@app.route('/logout') -def logout(): - session.pop('user_id', None) - return redirect(url_for('login')) - -@app.route('/get_session') -def get_session(): - user_session = session.get('user_id', 'default_session') - return jsonify({"session": user_session}) - - -''' -DashBoard -''' -user_id2UserClass = {} -@app.route('/dashboard') -@require_role -def dashboard(): - user_id = session['user_id'] - username = uuid2username[user_id] - if (user_id not in user_id2UserClass): - user_id2UserClass[user_id] = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - user_course_data = [] - for course_id in user_id2UserClass[user_id].select_course: - course_brief_info = course_list.get_course_brief_info(course_id, load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR)) - user_course_data.append(course_brief_info) - return render_template('dashboard.html',user_data = user_id2UserClass[user_id].to_json_without_dialog(), user_course_data = json.dumps(user_course_data)) - -''' -Course -''' - -@app.route('/course/') -@require_role -def course(course_id): - c = load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR) - return render_template('course.html', course_id=course_id, course_data=c) - -@app.route('/select_course', methods=['POST']) -@require_role -def select_course(): - user = user_id2UserClass[session['user_id']] - data = request.get_json() - course_id = data.get('course_id') - if course_id: - user.select_new_course(course_id, load_course_from_json(course_id, COURSE_DATA_DIR)) - return jsonify({'success': True, 'message': '课程选择成功'}) - - -@app.route('/') -@require_role -def home_index(): - selected_courses=[] - if ('user_id' in session): - if (session['user_id'] not in user_id2UserClass): return redirect(url_for('login')) - user = user_id2UserClass[session['user_id']] - for course_id in user.select_course: - selected_courses.append(course_id) - - return render_template('index.html', courses_data = course_list, selected_courses =selected_courses) - -# 一些app辅助函数,主要提供给Agent与数据库的交互能力 - -class MyFunction: - def save_chapter_memory(self, id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal): - print("-=-=-=-=-=-=-=-") - print(id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - username = uuid2username[id] - u = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - u.save_chapter_memory(course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - -app.my_function = MyFunction() -if __name__ == '__main__': - socketio.on_namespace(VSCodeNamespace('/vscode')) - socketio.on_namespace(AgentNamespace('/agent')) - socketio.run(app, host='0.0.0.0', port=5551, debug=False,allow_unsafe_werkzeug=True) - diff --git a/Html/runs/run_20250911-033735_3vhfbh/code/backboardManager.py b/Html/runs/run_20250911-033735_3vhfbh/code/backboardManager.py deleted file mode 100644 index 7de5f19..0000000 --- a/Html/runs/run_20250911-033735_3vhfbh/code/backboardManager.py +++ /dev/null @@ -1,80 +0,0 @@ - - - -import time -import os - -class Backboard: - def __init__(self, user_uuid, username, course_id, lesson_id, root_path): - self.user_uuid = user_uuid - self.username = username - self.course_id = course_id - self.lesson_id = lesson_id - self.root_path = root_path - self.create_time = time.time() - self.enter_chapter_time = time.time() - self.history = [] - self.file_tree = "[]" - self.active_file_path = "" - self.active_file_content = "" - self.pasted_file_path = "" - self.pasted_content = "" - - - def next_chapter(self): - self.enter_chapter_time = time.time() - - def get_info_prompt(self): - - five_history = "" - for h in self.history[-5:]: - five_history += h['type'] + "\n" + h.get('filePath', '') + "\n\n" - - endl = "\n" - return (f"###Global Info:###{endl}" - f"Here are some info about now user's IDE, refer to it when you need to handle some code.{endl}" - f"- User's total study time is {self.get_deltatime_mmss(self.create_time, time.time())}{endl}" - f"- User's current chapter study time is {self.get_deltatime_mmss(self.enter_chapter_time, time.time())}{endl}" - f"- Activated file path: {self.active_file_path}{endl}" - f"```{endl}" - f"{self.active_file_content[-10:]}{endl}" - f"```{endl}" - f"- Last five action:{five_history}{endl}" - f"- File tree: {self.file_tree}{endl}") - # f"- Activated file content (current editing 10 lines): {endl}" - def add_history(self, realtime_action): - if(realtime_action['type']=='config'):return - if len(self.history)!=0: - if (self.history[-1]['type']=='fileEdit'): - if(self.history[-1]['filePath'] == realtime_action['filePath']): - self.history[-1]['content'] = realtime_action['content'] - return - self.history.append(realtime_action) - - - def get_deltatime_mmss(self, start_time, end_time): - elapsed_time = end_time - start_time - hours = int(elapsed_time // 3600) - minutes = int((elapsed_time % 3600) // 60) - seconds = int(elapsed_time % 60) - return f"{hours:02d}:{minutes:02d}:{seconds:02d}" - - - def get_active_file_reletive_path(self): - relative_path = os.path.relpath(self.active_file_path, self.root_path) - return relative_path - - - -class BackBoardManager: - def __init__(self): - self.backboards = {} # user_uuid: Backboard - - def add_backboard(self, user_uuid, username, course_id, lesson_id, root_path): - self.backboards[user_uuid] = Backboard(user_uuid,username, course_id, lesson_id, root_path) - - def get_backboard(self, user_uuid) -> Backboard: - return self.backboards[user_uuid] - - - diff --git a/Html/runs/run_20250911-033735_3vhfbh/code/bootstrap.py b/Html/runs/run_20250911-033735_3vhfbh/code/bootstrap.py deleted file mode 100644 index bcb15ce..0000000 --- a/Html/runs/run_20250911-033735_3vhfbh/code/bootstrap.py +++ /dev/null @@ -1,31 +0,0 @@ -from pathlib import Path -import sys, os - -def bootstrap_paths(): - """ - 让 'AlgoriAgent'(位于 repo_root/AlgoriAgent)可被 import; - 并提供 STUDENT_WORKSPACE_ROOT 的默认值(repo_root/study)。 - 适配当前工厂位置:repo_root/Html/apps/__init__.py - """ - here = Path(__file__).resolve() - # repo_root = .../Html/apps/../../ => parents[2] - repo_root = here.parents[2] - - # 兜底:如果目录结构变化,尝试向上搜索包含 AlgoriAgent 的目录作为 repo_root - if not (repo_root / "AlgoriAgent").exists(): - for p in here.parents: - if (p / "AlgoriAgent").is_dir(): - repo_root = p - break - - # 确保仓库根在 sys.path(这样 'AlgoriAgent' 顶层包可被发现) - repo_root_str = str(repo_root) - if repo_root_str not in sys.path: - sys.path.insert(0, repo_root_str) - - # 可选:如果你还有其它顶层包,也可在此处继续插入 - - # 默认学习工作区目录(也可放到 config.ini / 环境变量覆盖) - os.environ.setdefault("STUDENT_WORKSPACE_ROOT", str(repo_root / "study")) - - return repo_root # 方便调试/日志 \ No newline at end of file diff --git a/Html/runs/run_20250911-033735_3vhfbh/code/wsgi.py b/Html/runs/run_20250911-033735_3vhfbh/code/wsgi.py deleted file mode 100644 index bbcbe5f..0000000 --- a/Html/runs/run_20250911-033735_3vhfbh/code/wsgi.py +++ /dev/null @@ -1,6 +0,0 @@ -# wsgi.py -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -# 提供一个可被 WSGI/进程管理器导入的 app 对象 -app = create_app() diff --git a/Html/runs/run_20250911-033735_3vhfbh/logging.chat b/Html/runs/run_20250911-033735_3vhfbh/logging.chat deleted file mode 100644 index e69de29..0000000 diff --git a/Html/runs/run_20250911-033735_3vhfbh/logging.log b/Html/runs/run_20250911-033735_3vhfbh/logging.log deleted file mode 100644 index eabf99d..0000000 --- a/Html/runs/run_20250911-033735_3vhfbh/logging.log +++ /dev/null @@ -1 +0,0 @@ -2025-09-11 03:37:39.548 | INFO | agentscope.models:read_model_configs:186 - Load configs for model wrapper: openai_cfg diff --git a/Html/runs/run_20250911-033739_mqgj3c/.config b/Html/runs/run_20250911-033739_mqgj3c/.config deleted file mode 100644 index 65d80dc..0000000 --- a/Html/runs/run_20250911-033739_mqgj3c/.config +++ /dev/null @@ -1,7 +0,0 @@ -{ - "project": "YsHmeM", - "name": "mqgj3c", - "run_id": "run_20250911-033739_mqgj3c", - "timestamp": "2025-09-11 03:37:39", - "pid": 14622 -} \ No newline at end of file diff --git a/Html/runs/run_20250911-033739_mqgj3c/agentscope.db b/Html/runs/run_20250911-033739_mqgj3c/agentscope.db deleted file mode 100644 index 666055b77679cda29c14fcf23b4ef1d039c5b52a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI%L2KJE6bEoS4Q(k)+glI2yjv3-0%NB!Hs&O1YUav`W0U1F<0V=#BsNLx(sSu$ z>=W&q?4#^B$!*yt2YT5l`~^0a^z(#~{ zkyg6w!t)u0!@f%5aeaJcfD9*Q_b$ozCY8>~CFA6|{Z2V!N;Z^cIq}eS$>x3HY|^=j z7lokrf1)Z$x@_R^N~@apn7OPMkZ(I<*1WJCw@v3GWy2n6&RcIQ0~zlR_x8^$%be!% zmxb7@7V;}H+K5#l(wSbZKXKY!mys6ROyi|!%aN@+%REpi?;B-K4PC3&{>iCzQnNB+ zwbW!z4iA{x(V_2L+5VJ1vMJeN;5l68yJ9?OZyl-TNCEp4P{^H8$cTGExdq$9ANE6@ zA@`ZUhb>is+Y=S?%$C1fnN{muZU1a!nMRV%#qFbMT;y3hf|KlJ)00Izz00bZa0SG_<0uX=z1a@EGHy1PL*Z=?k diff --git a/Html/runs/run_20250911-033739_mqgj3c/code/app.py b/Html/runs/run_20250911-033739_mqgj3c/code/app.py deleted file mode 100644 index c7f31f7..0000000 --- a/Html/runs/run_20250911-033739_mqgj3c/code/app.py +++ /dev/null @@ -1,21 +0,0 @@ -# app.py 0.1.1 rise to factory mode -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -from apps.extensions import socketio - -# 工厂创建 app,工厂里已经做了:加载配置/注册蓝图/注册 namespaces -app = create_app() - -if __name__ == "__main__": - # 仅本地开发用;生产不要用 werkzeug 自带的开发服务器 - socketio.run( - app, - host="0.0.0.0", - port=5551, - debug=True, # 开发期打开 - allow_unsafe_werkzeug=True, # 避免 dev server 的安全限制提示 - # ssl_context=('server.crt', 'server.key') - ) - - diff --git a/Html/runs/run_20250911-033739_mqgj3c/code/app_back.py b/Html/runs/run_20250911-033739_mqgj3c/code/app_back.py deleted file mode 100644 index 246853c..0000000 --- a/Html/runs/run_20250911-033739_mqgj3c/code/app_back.py +++ /dev/null @@ -1,480 +0,0 @@ -from bootstrap import bootstrap_paths -bootstrap_paths() -from functools import wraps -from flask import Flask, redirect, session, request, jsonify, render_template, send_from_directory, url_for -from flask_cors import CORS -from flask_socketio import SocketIO, join_room, emit, Namespace -import markdown -import os -import uuid -import shutil -import sys -import json -from apps.auth.decorators import require_role -parent_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) -sys.path.insert(0, parent_dir) -student_workspace_root_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../study')) -current_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '.')) -sys.path.insert(0, current_dir) -from AlgoriAgent.projects.algoriAgent.agent_manager import AgentManager - - -import configparser - -from db.user_list import UserList -from db.user import User, load_user_from_json, create_user_json -from db.course_list import CourseList -from db.course import Course, load_course_from_json -GLOBAL_CONFIG = configparser.ConfigParser() -GLOBAL_CONFIG.read('config.ini') -VSCODE_WEB_URL = GLOBAL_CONFIG['VSCODE_WEB']['url'] -USER_DATA_DIR = GLOBAL_CONFIG['USER_DATA']['dir'] -COURSE_DATA_DIR = GLOBAL_CONFIG['COURSE_DATA']['dir'] - -app = Flask(__name__) -socketio = SocketIO(app, cors_allowed_origins="*",ping_timeout=60, ping_interval=5) -# socketio = SocketIO(app, cors_allowed_origins="http://localhost:9888") # 设置跨域支持 -import logging -app.secret_key = 'cakebaker' -app.logger.setLevel(logging.DEBUG) -# 配置 CORS -CORS(app, resources={r"/*": {"origins": VSCODE_WEB_URL},}, supports_credentials=True) - - -userid_recorder = {} # user_id&path -> session['user_id'] - -''' -Backboard -''' -from backboardManager import BackBoardManager, Backboard - -backboard_manager = BackBoardManager() -uuid2username = {} -username2uuid = {} - - - -# 定义命名空间:用于和 VSCode 插件交流 -class VSCodeNamespace(Namespace): - def on_login(self,data): - print("VSCode client connected") - print(data) - dataconfig = data['config'] - user_id = dataconfig.get('user_id') - path = dataconfig.get('path') - course_id = dataconfig.get('course_id') - lesson_id = dataconfig.get('chapter_id') - print(f"User {user_id} connected with path: {path}") - useruuid = username2uuid[user_id] - join_room(useruuid, namespace='/vscode') - if backboard_manager.get_backboard(useruuid) == None: - backboard_manager.add_backboard(useruuid,user_id, course_id, lesson_id, path) - - - def on_message(self, data): - print(f"Received from VSCode client: {data}") - dataconfig = data['config'] - realtime_response(dataconfig, data) - # emit('response', {'message': 'Config data received and connection established'}) - def on_disconnect(self, data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - -def realtime_response(config, realtime_action): - user_id = config['user_id'] - folder_path = config['path'] - useruuid = username2uuid[user_id] - bb = backboard_manager.get_backboard(useruuid) - assert type(bb) == Backboard - - bb.add_history(realtime_action) - - if realtime_action['type'] == 'workspaceFolders': - bb.file_tree = realtime_action['fileTree'] - - if realtime_action['type'] == 'activeFile': - file_path = realtime_action['filePath'] - assert type(file_path) == str - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - if realtime_action['type'] == 'paste': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.pasted_file_path = file_path - bb.pasted_content = realtime_action['content'] - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - if realtime_action['type'] == 'fileEdit': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - - - print("config"+str(config)) - print("realtime_action"+str(realtime_action)) - pass - - -''' -Agent and Chat -''' -agent_manager = AgentManager(app = app, socketio = socketio) -user_threads = {} -import threading -from concurrent.futures import ThreadPoolExecutor, as_completed - -# 初始化线程池 -executor = ThreadPoolExecutor(max_workers=10) -class AgentNamespace(Namespace): - def on_login(self, data): - data = json.loads(data) - user = data['username'] - course_id = data['course_id'] - chapter_id = data['chapter_id'] - user_uuid = username2uuid[user] - session['user_id'] = user_uuid - print(f'User connected with session user_id: {user_uuid}') - # 从markdown、markdown_prompts、score_prompts中各读取数据folder.md并进行new_agent - with open(f'books/markdown/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fmd,\ - open(f'books/markdown_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8')as fmdp,\ - open(f'books/score_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fsp: - markdown = fmd.read() - markdown_prompts = fmdp.read() - score_prompts = fsp.read() - user_uuid, agent = agent_manager.new_agent(course_id, chapter_id, markdown, markdown_prompts, score_prompts, id=user_uuid, - root_path=f'../../study/{user}/{course_id}/{chapter_id}') - print(user_uuid) - join_room(user_uuid, namespace='/agent') # 将该用户加入以user_id为名的room - backboard_manager.add_backboard(user_uuid, user, course_id, chapter_id, root_path=f'../../study/{user}/{course_id}/{chapter_id}') - - def on_language(self, language): - id = session.get('user_id') - agent_manager.change_language(id, language) - - def on_message(self, data): - print(f"Message from client: {data}") - id = session.get('user_id') - if (type(data)==str): - data = json.loads(data) - print(id) - if data['type'] == 'text': - res = agent_manager.invoke(id, data['data'], backboard_manager.get_backboard(id).get_info_prompt()) - print('=*='*20) - print(res.content) - reply = f"{res.content['speak']}" - with app.app_context(): - emit('message',reply, room=id, namespace='/agent') - emit('request_function',res.content['function'], room=id, namespace='/agent') - - if data['type'] == 'function': - agent_manager.function_call(id, data['data']) - - def on_initiative(self,data): - print("User active function call") - user_id = session['user_id'] - if data['name'] == 'sample_judge': - agent_manager.sample_judge(user_id, backboard_manager.get_backboard(user_id)) - if data['name'] == 'judge': - agent_manager.judge(user_id, backboard_manager.get_backboard(user_id)) - - - - def on_disconnect(self,data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - - -''' -Markdown to HTML -''' -# 配置文件路径 -MARKDOWN_DIR = 'books/markdown' # 存放 markdown 文件的文件夹 -STATIC_DIR = 'static' # 存放生成的 HTML 和图片资源的文件夹 -IMAGE_DIR = 'image' # 图片资源相对于 markdown 的位置 - - - -@app.route('/--markdown', methods=['GET']) -def convert_md(course_id, filename): - md_file_path = os.path.join(MARKDOWN_DIR,course_id, f'{filename}.md') - - if not os.path.exists(md_file_path): - return jsonify({'error': 'Markdown file not found'}), 404 - - # 读取 markdown 文件内容 - with open(md_file_path, 'r', encoding='utf-8') as file: - md_content = file.read() - - # 将 markdown 转换为 HTML - html_content = markdown.markdown(md_content) - # 插入 CSS 样式,限制图片最大宽度为 100%,高度自动调整 - html_with_styles = f""" - - - - - - - {html_content} - - - """ - # 保存 HTML 文件到 static 文件夹 - html_output_path = os.path.join(STATIC_DIR, f'{filename}.html') - with open(html_output_path, 'w', encoding='utf-8') as html_file: - html_file.write(html_with_styles) - - # 处理图片资源,将 image/xxx 文件夹拷贝到 static/image/xxx - image_source_dir = os.path.join(MARKDOWN_DIR,course_id, IMAGE_DIR, filename) - image_target_dir = os.path.join(STATIC_DIR, IMAGE_DIR, filename) - print(f"Copying image resources from {image_source_dir} to {image_target_dir}") - if os.path.exists(image_source_dir): - # 确保 static/image/xxx 目录存在 - if not os.path.exists(image_target_dir): - os.makedirs(image_target_dir) - - # 拷贝图片资源 - for image_file in os.listdir(image_source_dir): - full_image_file_path = os.path.join(image_source_dir, image_file) - if os.path.isfile(full_image_file_path): - shutil.copy(full_image_file_path, image_target_dir) - - return jsonify({'html_url': f'/static/{filename}.html'}) - -# 静态文件(HTML 和图片资源)的访问 -@app.route('/static/') -def serve_static(filename): - return send_from_directory(STATIC_DIR, filename) - - -''' -Vscode -''' -@app.route('/desktop///') -def desktop(user_id, course_id, chapter_id): - if 'user_id' not in session: - # return redirect(url_for('login')) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ user_id + "uuid is"+ session['user_id']) - username2uuid[user_id] = session['user_id'] - uuid2username[session['user_id']] = user_id - userid_recorder[user_id+'&'+course_id] = session['user_id'] - - # 在学习目录下创建一个名为 user_id_path 的文件夹 - path_dir = os.path.join(student_workspace_root_path, user_id, course_id,chapter_id) - os.makedirs(path_dir, exist_ok=True) - # 在此文件夹内部创建一个.config文件,并写入 user_id=user_id\n path=path - config_path = os.path.join(path_dir, '.config') - if GLOBAL_CONFIG['VSCODE_WEB_PATH']['is_wsl']: # 如果是在 WSL 中运行,则将路径转换为 WSL 路径 - path_dir = path_dir.replace('\\', '/') - path_dir = path_dir.replace(GLOBAL_CONFIG['VSCODE_WEB_PATH']['windows_path'] , GLOBAL_CONFIG['VSCODE_WEB_PATH']['wsl_path']) - with open(config_path, 'w', encoding='utf-8') as f: - tmpd = {'user_id': user_id, 'course_id': course_id, 'chapter_id': chapter_id, 'path': path_dir} - json.dump(tmpd, f) - print('---------------------') - print(config_path) - return render_template('desktop.html', vscode_web_url=VSCODE_WEB_URL, user_id=user_id, course_id=course_id, chapter_id=chapter_id, workspace_path=path_dir) - -@app.route('/desktop_nouser//') -def desktop_nouser(course_id, chapter_id): - if 'user_id' not in session: - return redirect(url_for('login')) - user_id = session['user_id'] - username = uuid2username[user_id] - return redirect(url_for('desktop', user_id=username, course_id=course_id, chapter_id=chapter_id)) - -@app.route('/vscode_data', methods=['POST']) -def vscode_data(): - data = request.json - config = data['config'] - realtime_response(config,data) - print(f"Received data from VSCode: {data}") - return jsonify({"status": "success", "received": data}) - - - -''' -Login - -''' -users_list = UserList() -course_list = CourseList() - - -@app.route('/register') -def register(): - return render_template('register.html') - -@app.route('/register_teacher') -def register_teacher(): - return render_template('register_teacher.html') - -@app.route('/register_teacher_post', methods=['POST']) -def register_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password, teacher=True) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - -@app.route('/register_post', methods=['POST']) -def register_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - - -@app.route('/login') -def login(): - return render_template('login.html') - if 'user_id' not in session: - return render_template('login.html') - else: - return redirect(url_for('/')) - -@app.route('/login_post', methods=['POST']) -def login_post(): - # 获取请求的 JSON 数据 - data = request.get_json() - - username = data.get('username') - password = data.get('password') - - pswd = users_list.get_user_pswd(username) - - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/login_teacher_post', methods=['POST']) -def login_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - pswd = users_list.get_user_pswd(username) - is_teacher = users_list.get_user_is_teacher(username) - if is_teacher is None or is_teacher == False: - return jsonify({'success': False, 'message': '用户名不存在或非教师账号'}) - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/teacherboard') -@require_role(roles="teacher") -def teacherboard(): - return render_template('teacherboard.html') - - -@app.route('/logout') -def logout(): - session.pop('user_id', None) - return redirect(url_for('login')) - -@app.route('/get_session') -def get_session(): - user_session = session.get('user_id', 'default_session') - return jsonify({"session": user_session}) - - -''' -DashBoard -''' -user_id2UserClass = {} -@app.route('/dashboard') -@require_role -def dashboard(): - user_id = session['user_id'] - username = uuid2username[user_id] - if (user_id not in user_id2UserClass): - user_id2UserClass[user_id] = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - user_course_data = [] - for course_id in user_id2UserClass[user_id].select_course: - course_brief_info = course_list.get_course_brief_info(course_id, load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR)) - user_course_data.append(course_brief_info) - return render_template('dashboard.html',user_data = user_id2UserClass[user_id].to_json_without_dialog(), user_course_data = json.dumps(user_course_data)) - -''' -Course -''' - -@app.route('/course/') -@require_role -def course(course_id): - c = load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR) - return render_template('course.html', course_id=course_id, course_data=c) - -@app.route('/select_course', methods=['POST']) -@require_role -def select_course(): - user = user_id2UserClass[session['user_id']] - data = request.get_json() - course_id = data.get('course_id') - if course_id: - user.select_new_course(course_id, load_course_from_json(course_id, COURSE_DATA_DIR)) - return jsonify({'success': True, 'message': '课程选择成功'}) - - -@app.route('/') -@require_role -def home_index(): - selected_courses=[] - if ('user_id' in session): - if (session['user_id'] not in user_id2UserClass): return redirect(url_for('login')) - user = user_id2UserClass[session['user_id']] - for course_id in user.select_course: - selected_courses.append(course_id) - - return render_template('index.html', courses_data = course_list, selected_courses =selected_courses) - -# 一些app辅助函数,主要提供给Agent与数据库的交互能力 - -class MyFunction: - def save_chapter_memory(self, id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal): - print("-=-=-=-=-=-=-=-") - print(id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - username = uuid2username[id] - u = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - u.save_chapter_memory(course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - -app.my_function = MyFunction() -if __name__ == '__main__': - socketio.on_namespace(VSCodeNamespace('/vscode')) - socketio.on_namespace(AgentNamespace('/agent')) - socketio.run(app, host='0.0.0.0', port=5551, debug=False,allow_unsafe_werkzeug=True) - diff --git a/Html/runs/run_20250911-033739_mqgj3c/code/backboardManager.py b/Html/runs/run_20250911-033739_mqgj3c/code/backboardManager.py deleted file mode 100644 index 7de5f19..0000000 --- a/Html/runs/run_20250911-033739_mqgj3c/code/backboardManager.py +++ /dev/null @@ -1,80 +0,0 @@ - - - -import time -import os - -class Backboard: - def __init__(self, user_uuid, username, course_id, lesson_id, root_path): - self.user_uuid = user_uuid - self.username = username - self.course_id = course_id - self.lesson_id = lesson_id - self.root_path = root_path - self.create_time = time.time() - self.enter_chapter_time = time.time() - self.history = [] - self.file_tree = "[]" - self.active_file_path = "" - self.active_file_content = "" - self.pasted_file_path = "" - self.pasted_content = "" - - - def next_chapter(self): - self.enter_chapter_time = time.time() - - def get_info_prompt(self): - - five_history = "" - for h in self.history[-5:]: - five_history += h['type'] + "\n" + h.get('filePath', '') + "\n\n" - - endl = "\n" - return (f"###Global Info:###{endl}" - f"Here are some info about now user's IDE, refer to it when you need to handle some code.{endl}" - f"- User's total study time is {self.get_deltatime_mmss(self.create_time, time.time())}{endl}" - f"- User's current chapter study time is {self.get_deltatime_mmss(self.enter_chapter_time, time.time())}{endl}" - f"- Activated file path: {self.active_file_path}{endl}" - f"```{endl}" - f"{self.active_file_content[-10:]}{endl}" - f"```{endl}" - f"- Last five action:{five_history}{endl}" - f"- File tree: {self.file_tree}{endl}") - # f"- Activated file content (current editing 10 lines): {endl}" - def add_history(self, realtime_action): - if(realtime_action['type']=='config'):return - if len(self.history)!=0: - if (self.history[-1]['type']=='fileEdit'): - if(self.history[-1]['filePath'] == realtime_action['filePath']): - self.history[-1]['content'] = realtime_action['content'] - return - self.history.append(realtime_action) - - - def get_deltatime_mmss(self, start_time, end_time): - elapsed_time = end_time - start_time - hours = int(elapsed_time // 3600) - minutes = int((elapsed_time % 3600) // 60) - seconds = int(elapsed_time % 60) - return f"{hours:02d}:{minutes:02d}:{seconds:02d}" - - - def get_active_file_reletive_path(self): - relative_path = os.path.relpath(self.active_file_path, self.root_path) - return relative_path - - - -class BackBoardManager: - def __init__(self): - self.backboards = {} # user_uuid: Backboard - - def add_backboard(self, user_uuid, username, course_id, lesson_id, root_path): - self.backboards[user_uuid] = Backboard(user_uuid,username, course_id, lesson_id, root_path) - - def get_backboard(self, user_uuid) -> Backboard: - return self.backboards[user_uuid] - - - diff --git a/Html/runs/run_20250911-033739_mqgj3c/code/bootstrap.py b/Html/runs/run_20250911-033739_mqgj3c/code/bootstrap.py deleted file mode 100644 index bcb15ce..0000000 --- a/Html/runs/run_20250911-033739_mqgj3c/code/bootstrap.py +++ /dev/null @@ -1,31 +0,0 @@ -from pathlib import Path -import sys, os - -def bootstrap_paths(): - """ - 让 'AlgoriAgent'(位于 repo_root/AlgoriAgent)可被 import; - 并提供 STUDENT_WORKSPACE_ROOT 的默认值(repo_root/study)。 - 适配当前工厂位置:repo_root/Html/apps/__init__.py - """ - here = Path(__file__).resolve() - # repo_root = .../Html/apps/../../ => parents[2] - repo_root = here.parents[2] - - # 兜底:如果目录结构变化,尝试向上搜索包含 AlgoriAgent 的目录作为 repo_root - if not (repo_root / "AlgoriAgent").exists(): - for p in here.parents: - if (p / "AlgoriAgent").is_dir(): - repo_root = p - break - - # 确保仓库根在 sys.path(这样 'AlgoriAgent' 顶层包可被发现) - repo_root_str = str(repo_root) - if repo_root_str not in sys.path: - sys.path.insert(0, repo_root_str) - - # 可选:如果你还有其它顶层包,也可在此处继续插入 - - # 默认学习工作区目录(也可放到 config.ini / 环境变量覆盖) - os.environ.setdefault("STUDENT_WORKSPACE_ROOT", str(repo_root / "study")) - - return repo_root # 方便调试/日志 \ No newline at end of file diff --git a/Html/runs/run_20250911-033739_mqgj3c/code/wsgi.py b/Html/runs/run_20250911-033739_mqgj3c/code/wsgi.py deleted file mode 100644 index bbcbe5f..0000000 --- a/Html/runs/run_20250911-033739_mqgj3c/code/wsgi.py +++ /dev/null @@ -1,6 +0,0 @@ -# wsgi.py -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -# 提供一个可被 WSGI/进程管理器导入的 app 对象 -app = create_app() diff --git a/Html/runs/run_20250911-033739_mqgj3c/logging.chat b/Html/runs/run_20250911-033739_mqgj3c/logging.chat deleted file mode 100644 index e69de29..0000000 diff --git a/Html/runs/run_20250911-033739_mqgj3c/logging.log b/Html/runs/run_20250911-033739_mqgj3c/logging.log deleted file mode 100644 index d946617..0000000 --- a/Html/runs/run_20250911-033739_mqgj3c/logging.log +++ /dev/null @@ -1 +0,0 @@ -2025-09-11 03:37:43.308 | INFO | agentscope.models:read_model_configs:186 - Load configs for model wrapper: openai_cfg diff --git a/Html/runs/run_20250911-042255_ebhoff/.config b/Html/runs/run_20250911-042255_ebhoff/.config deleted file mode 100644 index ab51b8b..0000000 --- a/Html/runs/run_20250911-042255_ebhoff/.config +++ /dev/null @@ -1,7 +0,0 @@ -{ - "project": "fV4hPV", - "name": "ebhoff", - "run_id": "run_20250911-042255_ebhoff", - "timestamp": "2025-09-11 04:22:55", - "pid": 17434 -} \ No newline at end of file diff --git a/Html/runs/run_20250911-042255_ebhoff/agentscope.db b/Html/runs/run_20250911-042255_ebhoff/agentscope.db deleted file mode 100644 index 666055b77679cda29c14fcf23b4ef1d039c5b52a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI%L2KJE6bEoS4Q(k)+glI2yjv3-0%NB!Hs&O1YUav`W0U1F<0V=#BsNLx(sSu$ z>=W&q?4#^B$!*yt2YT5l`~^0a^z(#~{ zkyg6w!t)u0!@f%5aeaJcfD9*Q_b$ozCY8>~CFA6|{Z2V!N;Z^cIq}eS$>x3HY|^=j z7lokrf1)Z$x@_R^N~@apn7OPMkZ(I<*1WJCw@v3GWy2n6&RcIQ0~zlR_x8^$%be!% zmxb7@7V;}H+K5#l(wSbZKXKY!mys6ROyi|!%aN@+%REpi?;B-K4PC3&{>iCzQnNB+ zwbW!z4iA{x(V_2L+5VJ1vMJeN;5l68yJ9?OZyl-TNCEp4P{^H8$cTGExdq$9ANE6@ zA@`ZUhb>is+Y=S?%$C1fnN{muZU1a!nMRV%#qFbMT;y3hf|KlJ)00Izz00bZa0SG_<0uX=z1a@EGHy1PL*Z=?k diff --git a/Html/runs/run_20250911-042255_ebhoff/code/app.py b/Html/runs/run_20250911-042255_ebhoff/code/app.py deleted file mode 100644 index c7f31f7..0000000 --- a/Html/runs/run_20250911-042255_ebhoff/code/app.py +++ /dev/null @@ -1,21 +0,0 @@ -# app.py 0.1.1 rise to factory mode -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -from apps.extensions import socketio - -# 工厂创建 app,工厂里已经做了:加载配置/注册蓝图/注册 namespaces -app = create_app() - -if __name__ == "__main__": - # 仅本地开发用;生产不要用 werkzeug 自带的开发服务器 - socketio.run( - app, - host="0.0.0.0", - port=5551, - debug=True, # 开发期打开 - allow_unsafe_werkzeug=True, # 避免 dev server 的安全限制提示 - # ssl_context=('server.crt', 'server.key') - ) - - diff --git a/Html/runs/run_20250911-042255_ebhoff/code/app_back.py b/Html/runs/run_20250911-042255_ebhoff/code/app_back.py deleted file mode 100644 index 246853c..0000000 --- a/Html/runs/run_20250911-042255_ebhoff/code/app_back.py +++ /dev/null @@ -1,480 +0,0 @@ -from bootstrap import bootstrap_paths -bootstrap_paths() -from functools import wraps -from flask import Flask, redirect, session, request, jsonify, render_template, send_from_directory, url_for -from flask_cors import CORS -from flask_socketio import SocketIO, join_room, emit, Namespace -import markdown -import os -import uuid -import shutil -import sys -import json -from apps.auth.decorators import require_role -parent_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) -sys.path.insert(0, parent_dir) -student_workspace_root_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../study')) -current_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '.')) -sys.path.insert(0, current_dir) -from AlgoriAgent.projects.algoriAgent.agent_manager import AgentManager - - -import configparser - -from db.user_list import UserList -from db.user import User, load_user_from_json, create_user_json -from db.course_list import CourseList -from db.course import Course, load_course_from_json -GLOBAL_CONFIG = configparser.ConfigParser() -GLOBAL_CONFIG.read('config.ini') -VSCODE_WEB_URL = GLOBAL_CONFIG['VSCODE_WEB']['url'] -USER_DATA_DIR = GLOBAL_CONFIG['USER_DATA']['dir'] -COURSE_DATA_DIR = GLOBAL_CONFIG['COURSE_DATA']['dir'] - -app = Flask(__name__) -socketio = SocketIO(app, cors_allowed_origins="*",ping_timeout=60, ping_interval=5) -# socketio = SocketIO(app, cors_allowed_origins="http://localhost:9888") # 设置跨域支持 -import logging -app.secret_key = 'cakebaker' -app.logger.setLevel(logging.DEBUG) -# 配置 CORS -CORS(app, resources={r"/*": {"origins": VSCODE_WEB_URL},}, supports_credentials=True) - - -userid_recorder = {} # user_id&path -> session['user_id'] - -''' -Backboard -''' -from backboardManager import BackBoardManager, Backboard - -backboard_manager = BackBoardManager() -uuid2username = {} -username2uuid = {} - - - -# 定义命名空间:用于和 VSCode 插件交流 -class VSCodeNamespace(Namespace): - def on_login(self,data): - print("VSCode client connected") - print(data) - dataconfig = data['config'] - user_id = dataconfig.get('user_id') - path = dataconfig.get('path') - course_id = dataconfig.get('course_id') - lesson_id = dataconfig.get('chapter_id') - print(f"User {user_id} connected with path: {path}") - useruuid = username2uuid[user_id] - join_room(useruuid, namespace='/vscode') - if backboard_manager.get_backboard(useruuid) == None: - backboard_manager.add_backboard(useruuid,user_id, course_id, lesson_id, path) - - - def on_message(self, data): - print(f"Received from VSCode client: {data}") - dataconfig = data['config'] - realtime_response(dataconfig, data) - # emit('response', {'message': 'Config data received and connection established'}) - def on_disconnect(self, data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - -def realtime_response(config, realtime_action): - user_id = config['user_id'] - folder_path = config['path'] - useruuid = username2uuid[user_id] - bb = backboard_manager.get_backboard(useruuid) - assert type(bb) == Backboard - - bb.add_history(realtime_action) - - if realtime_action['type'] == 'workspaceFolders': - bb.file_tree = realtime_action['fileTree'] - - if realtime_action['type'] == 'activeFile': - file_path = realtime_action['filePath'] - assert type(file_path) == str - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - if realtime_action['type'] == 'paste': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.pasted_file_path = file_path - bb.pasted_content = realtime_action['content'] - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - if realtime_action['type'] == 'fileEdit': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - - - print("config"+str(config)) - print("realtime_action"+str(realtime_action)) - pass - - -''' -Agent and Chat -''' -agent_manager = AgentManager(app = app, socketio = socketio) -user_threads = {} -import threading -from concurrent.futures import ThreadPoolExecutor, as_completed - -# 初始化线程池 -executor = ThreadPoolExecutor(max_workers=10) -class AgentNamespace(Namespace): - def on_login(self, data): - data = json.loads(data) - user = data['username'] - course_id = data['course_id'] - chapter_id = data['chapter_id'] - user_uuid = username2uuid[user] - session['user_id'] = user_uuid - print(f'User connected with session user_id: {user_uuid}') - # 从markdown、markdown_prompts、score_prompts中各读取数据folder.md并进行new_agent - with open(f'books/markdown/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fmd,\ - open(f'books/markdown_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8')as fmdp,\ - open(f'books/score_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fsp: - markdown = fmd.read() - markdown_prompts = fmdp.read() - score_prompts = fsp.read() - user_uuid, agent = agent_manager.new_agent(course_id, chapter_id, markdown, markdown_prompts, score_prompts, id=user_uuid, - root_path=f'../../study/{user}/{course_id}/{chapter_id}') - print(user_uuid) - join_room(user_uuid, namespace='/agent') # 将该用户加入以user_id为名的room - backboard_manager.add_backboard(user_uuid, user, course_id, chapter_id, root_path=f'../../study/{user}/{course_id}/{chapter_id}') - - def on_language(self, language): - id = session.get('user_id') - agent_manager.change_language(id, language) - - def on_message(self, data): - print(f"Message from client: {data}") - id = session.get('user_id') - if (type(data)==str): - data = json.loads(data) - print(id) - if data['type'] == 'text': - res = agent_manager.invoke(id, data['data'], backboard_manager.get_backboard(id).get_info_prompt()) - print('=*='*20) - print(res.content) - reply = f"{res.content['speak']}" - with app.app_context(): - emit('message',reply, room=id, namespace='/agent') - emit('request_function',res.content['function'], room=id, namespace='/agent') - - if data['type'] == 'function': - agent_manager.function_call(id, data['data']) - - def on_initiative(self,data): - print("User active function call") - user_id = session['user_id'] - if data['name'] == 'sample_judge': - agent_manager.sample_judge(user_id, backboard_manager.get_backboard(user_id)) - if data['name'] == 'judge': - agent_manager.judge(user_id, backboard_manager.get_backboard(user_id)) - - - - def on_disconnect(self,data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - - -''' -Markdown to HTML -''' -# 配置文件路径 -MARKDOWN_DIR = 'books/markdown' # 存放 markdown 文件的文件夹 -STATIC_DIR = 'static' # 存放生成的 HTML 和图片资源的文件夹 -IMAGE_DIR = 'image' # 图片资源相对于 markdown 的位置 - - - -@app.route('/--markdown', methods=['GET']) -def convert_md(course_id, filename): - md_file_path = os.path.join(MARKDOWN_DIR,course_id, f'{filename}.md') - - if not os.path.exists(md_file_path): - return jsonify({'error': 'Markdown file not found'}), 404 - - # 读取 markdown 文件内容 - with open(md_file_path, 'r', encoding='utf-8') as file: - md_content = file.read() - - # 将 markdown 转换为 HTML - html_content = markdown.markdown(md_content) - # 插入 CSS 样式,限制图片最大宽度为 100%,高度自动调整 - html_with_styles = f""" - - - - - - - {html_content} - - - """ - # 保存 HTML 文件到 static 文件夹 - html_output_path = os.path.join(STATIC_DIR, f'{filename}.html') - with open(html_output_path, 'w', encoding='utf-8') as html_file: - html_file.write(html_with_styles) - - # 处理图片资源,将 image/xxx 文件夹拷贝到 static/image/xxx - image_source_dir = os.path.join(MARKDOWN_DIR,course_id, IMAGE_DIR, filename) - image_target_dir = os.path.join(STATIC_DIR, IMAGE_DIR, filename) - print(f"Copying image resources from {image_source_dir} to {image_target_dir}") - if os.path.exists(image_source_dir): - # 确保 static/image/xxx 目录存在 - if not os.path.exists(image_target_dir): - os.makedirs(image_target_dir) - - # 拷贝图片资源 - for image_file in os.listdir(image_source_dir): - full_image_file_path = os.path.join(image_source_dir, image_file) - if os.path.isfile(full_image_file_path): - shutil.copy(full_image_file_path, image_target_dir) - - return jsonify({'html_url': f'/static/{filename}.html'}) - -# 静态文件(HTML 和图片资源)的访问 -@app.route('/static/') -def serve_static(filename): - return send_from_directory(STATIC_DIR, filename) - - -''' -Vscode -''' -@app.route('/desktop///') -def desktop(user_id, course_id, chapter_id): - if 'user_id' not in session: - # return redirect(url_for('login')) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ user_id + "uuid is"+ session['user_id']) - username2uuid[user_id] = session['user_id'] - uuid2username[session['user_id']] = user_id - userid_recorder[user_id+'&'+course_id] = session['user_id'] - - # 在学习目录下创建一个名为 user_id_path 的文件夹 - path_dir = os.path.join(student_workspace_root_path, user_id, course_id,chapter_id) - os.makedirs(path_dir, exist_ok=True) - # 在此文件夹内部创建一个.config文件,并写入 user_id=user_id\n path=path - config_path = os.path.join(path_dir, '.config') - if GLOBAL_CONFIG['VSCODE_WEB_PATH']['is_wsl']: # 如果是在 WSL 中运行,则将路径转换为 WSL 路径 - path_dir = path_dir.replace('\\', '/') - path_dir = path_dir.replace(GLOBAL_CONFIG['VSCODE_WEB_PATH']['windows_path'] , GLOBAL_CONFIG['VSCODE_WEB_PATH']['wsl_path']) - with open(config_path, 'w', encoding='utf-8') as f: - tmpd = {'user_id': user_id, 'course_id': course_id, 'chapter_id': chapter_id, 'path': path_dir} - json.dump(tmpd, f) - print('---------------------') - print(config_path) - return render_template('desktop.html', vscode_web_url=VSCODE_WEB_URL, user_id=user_id, course_id=course_id, chapter_id=chapter_id, workspace_path=path_dir) - -@app.route('/desktop_nouser//') -def desktop_nouser(course_id, chapter_id): - if 'user_id' not in session: - return redirect(url_for('login')) - user_id = session['user_id'] - username = uuid2username[user_id] - return redirect(url_for('desktop', user_id=username, course_id=course_id, chapter_id=chapter_id)) - -@app.route('/vscode_data', methods=['POST']) -def vscode_data(): - data = request.json - config = data['config'] - realtime_response(config,data) - print(f"Received data from VSCode: {data}") - return jsonify({"status": "success", "received": data}) - - - -''' -Login - -''' -users_list = UserList() -course_list = CourseList() - - -@app.route('/register') -def register(): - return render_template('register.html') - -@app.route('/register_teacher') -def register_teacher(): - return render_template('register_teacher.html') - -@app.route('/register_teacher_post', methods=['POST']) -def register_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password, teacher=True) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - -@app.route('/register_post', methods=['POST']) -def register_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - - -@app.route('/login') -def login(): - return render_template('login.html') - if 'user_id' not in session: - return render_template('login.html') - else: - return redirect(url_for('/')) - -@app.route('/login_post', methods=['POST']) -def login_post(): - # 获取请求的 JSON 数据 - data = request.get_json() - - username = data.get('username') - password = data.get('password') - - pswd = users_list.get_user_pswd(username) - - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/login_teacher_post', methods=['POST']) -def login_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - pswd = users_list.get_user_pswd(username) - is_teacher = users_list.get_user_is_teacher(username) - if is_teacher is None or is_teacher == False: - return jsonify({'success': False, 'message': '用户名不存在或非教师账号'}) - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/teacherboard') -@require_role(roles="teacher") -def teacherboard(): - return render_template('teacherboard.html') - - -@app.route('/logout') -def logout(): - session.pop('user_id', None) - return redirect(url_for('login')) - -@app.route('/get_session') -def get_session(): - user_session = session.get('user_id', 'default_session') - return jsonify({"session": user_session}) - - -''' -DashBoard -''' -user_id2UserClass = {} -@app.route('/dashboard') -@require_role -def dashboard(): - user_id = session['user_id'] - username = uuid2username[user_id] - if (user_id not in user_id2UserClass): - user_id2UserClass[user_id] = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - user_course_data = [] - for course_id in user_id2UserClass[user_id].select_course: - course_brief_info = course_list.get_course_brief_info(course_id, load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR)) - user_course_data.append(course_brief_info) - return render_template('dashboard.html',user_data = user_id2UserClass[user_id].to_json_without_dialog(), user_course_data = json.dumps(user_course_data)) - -''' -Course -''' - -@app.route('/course/') -@require_role -def course(course_id): - c = load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR) - return render_template('course.html', course_id=course_id, course_data=c) - -@app.route('/select_course', methods=['POST']) -@require_role -def select_course(): - user = user_id2UserClass[session['user_id']] - data = request.get_json() - course_id = data.get('course_id') - if course_id: - user.select_new_course(course_id, load_course_from_json(course_id, COURSE_DATA_DIR)) - return jsonify({'success': True, 'message': '课程选择成功'}) - - -@app.route('/') -@require_role -def home_index(): - selected_courses=[] - if ('user_id' in session): - if (session['user_id'] not in user_id2UserClass): return redirect(url_for('login')) - user = user_id2UserClass[session['user_id']] - for course_id in user.select_course: - selected_courses.append(course_id) - - return render_template('index.html', courses_data = course_list, selected_courses =selected_courses) - -# 一些app辅助函数,主要提供给Agent与数据库的交互能力 - -class MyFunction: - def save_chapter_memory(self, id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal): - print("-=-=-=-=-=-=-=-") - print(id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - username = uuid2username[id] - u = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - u.save_chapter_memory(course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - -app.my_function = MyFunction() -if __name__ == '__main__': - socketio.on_namespace(VSCodeNamespace('/vscode')) - socketio.on_namespace(AgentNamespace('/agent')) - socketio.run(app, host='0.0.0.0', port=5551, debug=False,allow_unsafe_werkzeug=True) - diff --git a/Html/runs/run_20250911-042255_ebhoff/code/backboardManager.py b/Html/runs/run_20250911-042255_ebhoff/code/backboardManager.py deleted file mode 100644 index 7de5f19..0000000 --- a/Html/runs/run_20250911-042255_ebhoff/code/backboardManager.py +++ /dev/null @@ -1,80 +0,0 @@ - - - -import time -import os - -class Backboard: - def __init__(self, user_uuid, username, course_id, lesson_id, root_path): - self.user_uuid = user_uuid - self.username = username - self.course_id = course_id - self.lesson_id = lesson_id - self.root_path = root_path - self.create_time = time.time() - self.enter_chapter_time = time.time() - self.history = [] - self.file_tree = "[]" - self.active_file_path = "" - self.active_file_content = "" - self.pasted_file_path = "" - self.pasted_content = "" - - - def next_chapter(self): - self.enter_chapter_time = time.time() - - def get_info_prompt(self): - - five_history = "" - for h in self.history[-5:]: - five_history += h['type'] + "\n" + h.get('filePath', '') + "\n\n" - - endl = "\n" - return (f"###Global Info:###{endl}" - f"Here are some info about now user's IDE, refer to it when you need to handle some code.{endl}" - f"- User's total study time is {self.get_deltatime_mmss(self.create_time, time.time())}{endl}" - f"- User's current chapter study time is {self.get_deltatime_mmss(self.enter_chapter_time, time.time())}{endl}" - f"- Activated file path: {self.active_file_path}{endl}" - f"```{endl}" - f"{self.active_file_content[-10:]}{endl}" - f"```{endl}" - f"- Last five action:{five_history}{endl}" - f"- File tree: {self.file_tree}{endl}") - # f"- Activated file content (current editing 10 lines): {endl}" - def add_history(self, realtime_action): - if(realtime_action['type']=='config'):return - if len(self.history)!=0: - if (self.history[-1]['type']=='fileEdit'): - if(self.history[-1]['filePath'] == realtime_action['filePath']): - self.history[-1]['content'] = realtime_action['content'] - return - self.history.append(realtime_action) - - - def get_deltatime_mmss(self, start_time, end_time): - elapsed_time = end_time - start_time - hours = int(elapsed_time // 3600) - minutes = int((elapsed_time % 3600) // 60) - seconds = int(elapsed_time % 60) - return f"{hours:02d}:{minutes:02d}:{seconds:02d}" - - - def get_active_file_reletive_path(self): - relative_path = os.path.relpath(self.active_file_path, self.root_path) - return relative_path - - - -class BackBoardManager: - def __init__(self): - self.backboards = {} # user_uuid: Backboard - - def add_backboard(self, user_uuid, username, course_id, lesson_id, root_path): - self.backboards[user_uuid] = Backboard(user_uuid,username, course_id, lesson_id, root_path) - - def get_backboard(self, user_uuid) -> Backboard: - return self.backboards[user_uuid] - - - diff --git a/Html/runs/run_20250911-042255_ebhoff/code/bootstrap.py b/Html/runs/run_20250911-042255_ebhoff/code/bootstrap.py deleted file mode 100644 index bcb15ce..0000000 --- a/Html/runs/run_20250911-042255_ebhoff/code/bootstrap.py +++ /dev/null @@ -1,31 +0,0 @@ -from pathlib import Path -import sys, os - -def bootstrap_paths(): - """ - 让 'AlgoriAgent'(位于 repo_root/AlgoriAgent)可被 import; - 并提供 STUDENT_WORKSPACE_ROOT 的默认值(repo_root/study)。 - 适配当前工厂位置:repo_root/Html/apps/__init__.py - """ - here = Path(__file__).resolve() - # repo_root = .../Html/apps/../../ => parents[2] - repo_root = here.parents[2] - - # 兜底:如果目录结构变化,尝试向上搜索包含 AlgoriAgent 的目录作为 repo_root - if not (repo_root / "AlgoriAgent").exists(): - for p in here.parents: - if (p / "AlgoriAgent").is_dir(): - repo_root = p - break - - # 确保仓库根在 sys.path(这样 'AlgoriAgent' 顶层包可被发现) - repo_root_str = str(repo_root) - if repo_root_str not in sys.path: - sys.path.insert(0, repo_root_str) - - # 可选:如果你还有其它顶层包,也可在此处继续插入 - - # 默认学习工作区目录(也可放到 config.ini / 环境变量覆盖) - os.environ.setdefault("STUDENT_WORKSPACE_ROOT", str(repo_root / "study")) - - return repo_root # 方便调试/日志 \ No newline at end of file diff --git a/Html/runs/run_20250911-042255_ebhoff/code/wsgi.py b/Html/runs/run_20250911-042255_ebhoff/code/wsgi.py deleted file mode 100644 index bbcbe5f..0000000 --- a/Html/runs/run_20250911-042255_ebhoff/code/wsgi.py +++ /dev/null @@ -1,6 +0,0 @@ -# wsgi.py -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -# 提供一个可被 WSGI/进程管理器导入的 app 对象 -app = create_app() diff --git a/Html/runs/run_20250911-042255_ebhoff/logging.chat b/Html/runs/run_20250911-042255_ebhoff/logging.chat deleted file mode 100644 index e69de29..0000000 diff --git a/Html/runs/run_20250911-042255_ebhoff/logging.log b/Html/runs/run_20250911-042255_ebhoff/logging.log deleted file mode 100644 index 366ee7c..0000000 --- a/Html/runs/run_20250911-042255_ebhoff/logging.log +++ /dev/null @@ -1 +0,0 @@ -2025-09-11 04:23:03.723 | INFO | agentscope.models:read_model_configs:186 - Load configs for model wrapper: openai_cfg diff --git a/Html/runs/run_20250911-042303_dshgn3/.config b/Html/runs/run_20250911-042303_dshgn3/.config deleted file mode 100644 index 5965c5c..0000000 --- a/Html/runs/run_20250911-042303_dshgn3/.config +++ /dev/null @@ -1,7 +0,0 @@ -{ - "project": "jfBTGh", - "name": "dshgn3", - "run_id": "run_20250911-042303_dshgn3", - "timestamp": "2025-09-11 04:23:03", - "pid": 17471 -} \ No newline at end of file diff --git a/Html/runs/run_20250911-042303_dshgn3/agentscope.db b/Html/runs/run_20250911-042303_dshgn3/agentscope.db deleted file mode 100644 index 666055b77679cda29c14fcf23b4ef1d039c5b52a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI%L2KJE6bEoS4Q(k)+glI2yjv3-0%NB!Hs&O1YUav`W0U1F<0V=#BsNLx(sSu$ z>=W&q?4#^B$!*yt2YT5l`~^0a^z(#~{ zkyg6w!t)u0!@f%5aeaJcfD9*Q_b$ozCY8>~CFA6|{Z2V!N;Z^cIq}eS$>x3HY|^=j z7lokrf1)Z$x@_R^N~@apn7OPMkZ(I<*1WJCw@v3GWy2n6&RcIQ0~zlR_x8^$%be!% zmxb7@7V;}H+K5#l(wSbZKXKY!mys6ROyi|!%aN@+%REpi?;B-K4PC3&{>iCzQnNB+ zwbW!z4iA{x(V_2L+5VJ1vMJeN;5l68yJ9?OZyl-TNCEp4P{^H8$cTGExdq$9ANE6@ zA@`ZUhb>is+Y=S?%$C1fnN{muZU1a!nMRV%#qFbMT;y3hf|KlJ)00Izz00bZa0SG_<0uX=z1a@EGHy1PL*Z=?k diff --git a/Html/runs/run_20250911-042303_dshgn3/code/app.py b/Html/runs/run_20250911-042303_dshgn3/code/app.py deleted file mode 100644 index c7f31f7..0000000 --- a/Html/runs/run_20250911-042303_dshgn3/code/app.py +++ /dev/null @@ -1,21 +0,0 @@ -# app.py 0.1.1 rise to factory mode -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -from apps.extensions import socketio - -# 工厂创建 app,工厂里已经做了:加载配置/注册蓝图/注册 namespaces -app = create_app() - -if __name__ == "__main__": - # 仅本地开发用;生产不要用 werkzeug 自带的开发服务器 - socketio.run( - app, - host="0.0.0.0", - port=5551, - debug=True, # 开发期打开 - allow_unsafe_werkzeug=True, # 避免 dev server 的安全限制提示 - # ssl_context=('server.crt', 'server.key') - ) - - diff --git a/Html/runs/run_20250911-042303_dshgn3/code/app_back.py b/Html/runs/run_20250911-042303_dshgn3/code/app_back.py deleted file mode 100644 index 246853c..0000000 --- a/Html/runs/run_20250911-042303_dshgn3/code/app_back.py +++ /dev/null @@ -1,480 +0,0 @@ -from bootstrap import bootstrap_paths -bootstrap_paths() -from functools import wraps -from flask import Flask, redirect, session, request, jsonify, render_template, send_from_directory, url_for -from flask_cors import CORS -from flask_socketio import SocketIO, join_room, emit, Namespace -import markdown -import os -import uuid -import shutil -import sys -import json -from apps.auth.decorators import require_role -parent_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) -sys.path.insert(0, parent_dir) -student_workspace_root_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../study')) -current_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '.')) -sys.path.insert(0, current_dir) -from AlgoriAgent.projects.algoriAgent.agent_manager import AgentManager - - -import configparser - -from db.user_list import UserList -from db.user import User, load_user_from_json, create_user_json -from db.course_list import CourseList -from db.course import Course, load_course_from_json -GLOBAL_CONFIG = configparser.ConfigParser() -GLOBAL_CONFIG.read('config.ini') -VSCODE_WEB_URL = GLOBAL_CONFIG['VSCODE_WEB']['url'] -USER_DATA_DIR = GLOBAL_CONFIG['USER_DATA']['dir'] -COURSE_DATA_DIR = GLOBAL_CONFIG['COURSE_DATA']['dir'] - -app = Flask(__name__) -socketio = SocketIO(app, cors_allowed_origins="*",ping_timeout=60, ping_interval=5) -# socketio = SocketIO(app, cors_allowed_origins="http://localhost:9888") # 设置跨域支持 -import logging -app.secret_key = 'cakebaker' -app.logger.setLevel(logging.DEBUG) -# 配置 CORS -CORS(app, resources={r"/*": {"origins": VSCODE_WEB_URL},}, supports_credentials=True) - - -userid_recorder = {} # user_id&path -> session['user_id'] - -''' -Backboard -''' -from backboardManager import BackBoardManager, Backboard - -backboard_manager = BackBoardManager() -uuid2username = {} -username2uuid = {} - - - -# 定义命名空间:用于和 VSCode 插件交流 -class VSCodeNamespace(Namespace): - def on_login(self,data): - print("VSCode client connected") - print(data) - dataconfig = data['config'] - user_id = dataconfig.get('user_id') - path = dataconfig.get('path') - course_id = dataconfig.get('course_id') - lesson_id = dataconfig.get('chapter_id') - print(f"User {user_id} connected with path: {path}") - useruuid = username2uuid[user_id] - join_room(useruuid, namespace='/vscode') - if backboard_manager.get_backboard(useruuid) == None: - backboard_manager.add_backboard(useruuid,user_id, course_id, lesson_id, path) - - - def on_message(self, data): - print(f"Received from VSCode client: {data}") - dataconfig = data['config'] - realtime_response(dataconfig, data) - # emit('response', {'message': 'Config data received and connection established'}) - def on_disconnect(self, data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - -def realtime_response(config, realtime_action): - user_id = config['user_id'] - folder_path = config['path'] - useruuid = username2uuid[user_id] - bb = backboard_manager.get_backboard(useruuid) - assert type(bb) == Backboard - - bb.add_history(realtime_action) - - if realtime_action['type'] == 'workspaceFolders': - bb.file_tree = realtime_action['fileTree'] - - if realtime_action['type'] == 'activeFile': - file_path = realtime_action['filePath'] - assert type(file_path) == str - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - if realtime_action['type'] == 'paste': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.pasted_file_path = file_path - bb.pasted_content = realtime_action['content'] - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - if realtime_action['type'] == 'fileEdit': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - - - print("config"+str(config)) - print("realtime_action"+str(realtime_action)) - pass - - -''' -Agent and Chat -''' -agent_manager = AgentManager(app = app, socketio = socketio) -user_threads = {} -import threading -from concurrent.futures import ThreadPoolExecutor, as_completed - -# 初始化线程池 -executor = ThreadPoolExecutor(max_workers=10) -class AgentNamespace(Namespace): - def on_login(self, data): - data = json.loads(data) - user = data['username'] - course_id = data['course_id'] - chapter_id = data['chapter_id'] - user_uuid = username2uuid[user] - session['user_id'] = user_uuid - print(f'User connected with session user_id: {user_uuid}') - # 从markdown、markdown_prompts、score_prompts中各读取数据folder.md并进行new_agent - with open(f'books/markdown/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fmd,\ - open(f'books/markdown_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8')as fmdp,\ - open(f'books/score_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fsp: - markdown = fmd.read() - markdown_prompts = fmdp.read() - score_prompts = fsp.read() - user_uuid, agent = agent_manager.new_agent(course_id, chapter_id, markdown, markdown_prompts, score_prompts, id=user_uuid, - root_path=f'../../study/{user}/{course_id}/{chapter_id}') - print(user_uuid) - join_room(user_uuid, namespace='/agent') # 将该用户加入以user_id为名的room - backboard_manager.add_backboard(user_uuid, user, course_id, chapter_id, root_path=f'../../study/{user}/{course_id}/{chapter_id}') - - def on_language(self, language): - id = session.get('user_id') - agent_manager.change_language(id, language) - - def on_message(self, data): - print(f"Message from client: {data}") - id = session.get('user_id') - if (type(data)==str): - data = json.loads(data) - print(id) - if data['type'] == 'text': - res = agent_manager.invoke(id, data['data'], backboard_manager.get_backboard(id).get_info_prompt()) - print('=*='*20) - print(res.content) - reply = f"{res.content['speak']}" - with app.app_context(): - emit('message',reply, room=id, namespace='/agent') - emit('request_function',res.content['function'], room=id, namespace='/agent') - - if data['type'] == 'function': - agent_manager.function_call(id, data['data']) - - def on_initiative(self,data): - print("User active function call") - user_id = session['user_id'] - if data['name'] == 'sample_judge': - agent_manager.sample_judge(user_id, backboard_manager.get_backboard(user_id)) - if data['name'] == 'judge': - agent_manager.judge(user_id, backboard_manager.get_backboard(user_id)) - - - - def on_disconnect(self,data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - - -''' -Markdown to HTML -''' -# 配置文件路径 -MARKDOWN_DIR = 'books/markdown' # 存放 markdown 文件的文件夹 -STATIC_DIR = 'static' # 存放生成的 HTML 和图片资源的文件夹 -IMAGE_DIR = 'image' # 图片资源相对于 markdown 的位置 - - - -@app.route('/--markdown', methods=['GET']) -def convert_md(course_id, filename): - md_file_path = os.path.join(MARKDOWN_DIR,course_id, f'{filename}.md') - - if not os.path.exists(md_file_path): - return jsonify({'error': 'Markdown file not found'}), 404 - - # 读取 markdown 文件内容 - with open(md_file_path, 'r', encoding='utf-8') as file: - md_content = file.read() - - # 将 markdown 转换为 HTML - html_content = markdown.markdown(md_content) - # 插入 CSS 样式,限制图片最大宽度为 100%,高度自动调整 - html_with_styles = f""" - - - - - - - {html_content} - - - """ - # 保存 HTML 文件到 static 文件夹 - html_output_path = os.path.join(STATIC_DIR, f'{filename}.html') - with open(html_output_path, 'w', encoding='utf-8') as html_file: - html_file.write(html_with_styles) - - # 处理图片资源,将 image/xxx 文件夹拷贝到 static/image/xxx - image_source_dir = os.path.join(MARKDOWN_DIR,course_id, IMAGE_DIR, filename) - image_target_dir = os.path.join(STATIC_DIR, IMAGE_DIR, filename) - print(f"Copying image resources from {image_source_dir} to {image_target_dir}") - if os.path.exists(image_source_dir): - # 确保 static/image/xxx 目录存在 - if not os.path.exists(image_target_dir): - os.makedirs(image_target_dir) - - # 拷贝图片资源 - for image_file in os.listdir(image_source_dir): - full_image_file_path = os.path.join(image_source_dir, image_file) - if os.path.isfile(full_image_file_path): - shutil.copy(full_image_file_path, image_target_dir) - - return jsonify({'html_url': f'/static/{filename}.html'}) - -# 静态文件(HTML 和图片资源)的访问 -@app.route('/static/') -def serve_static(filename): - return send_from_directory(STATIC_DIR, filename) - - -''' -Vscode -''' -@app.route('/desktop///') -def desktop(user_id, course_id, chapter_id): - if 'user_id' not in session: - # return redirect(url_for('login')) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ user_id + "uuid is"+ session['user_id']) - username2uuid[user_id] = session['user_id'] - uuid2username[session['user_id']] = user_id - userid_recorder[user_id+'&'+course_id] = session['user_id'] - - # 在学习目录下创建一个名为 user_id_path 的文件夹 - path_dir = os.path.join(student_workspace_root_path, user_id, course_id,chapter_id) - os.makedirs(path_dir, exist_ok=True) - # 在此文件夹内部创建一个.config文件,并写入 user_id=user_id\n path=path - config_path = os.path.join(path_dir, '.config') - if GLOBAL_CONFIG['VSCODE_WEB_PATH']['is_wsl']: # 如果是在 WSL 中运行,则将路径转换为 WSL 路径 - path_dir = path_dir.replace('\\', '/') - path_dir = path_dir.replace(GLOBAL_CONFIG['VSCODE_WEB_PATH']['windows_path'] , GLOBAL_CONFIG['VSCODE_WEB_PATH']['wsl_path']) - with open(config_path, 'w', encoding='utf-8') as f: - tmpd = {'user_id': user_id, 'course_id': course_id, 'chapter_id': chapter_id, 'path': path_dir} - json.dump(tmpd, f) - print('---------------------') - print(config_path) - return render_template('desktop.html', vscode_web_url=VSCODE_WEB_URL, user_id=user_id, course_id=course_id, chapter_id=chapter_id, workspace_path=path_dir) - -@app.route('/desktop_nouser//') -def desktop_nouser(course_id, chapter_id): - if 'user_id' not in session: - return redirect(url_for('login')) - user_id = session['user_id'] - username = uuid2username[user_id] - return redirect(url_for('desktop', user_id=username, course_id=course_id, chapter_id=chapter_id)) - -@app.route('/vscode_data', methods=['POST']) -def vscode_data(): - data = request.json - config = data['config'] - realtime_response(config,data) - print(f"Received data from VSCode: {data}") - return jsonify({"status": "success", "received": data}) - - - -''' -Login - -''' -users_list = UserList() -course_list = CourseList() - - -@app.route('/register') -def register(): - return render_template('register.html') - -@app.route('/register_teacher') -def register_teacher(): - return render_template('register_teacher.html') - -@app.route('/register_teacher_post', methods=['POST']) -def register_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password, teacher=True) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - -@app.route('/register_post', methods=['POST']) -def register_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - - -@app.route('/login') -def login(): - return render_template('login.html') - if 'user_id' not in session: - return render_template('login.html') - else: - return redirect(url_for('/')) - -@app.route('/login_post', methods=['POST']) -def login_post(): - # 获取请求的 JSON 数据 - data = request.get_json() - - username = data.get('username') - password = data.get('password') - - pswd = users_list.get_user_pswd(username) - - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/login_teacher_post', methods=['POST']) -def login_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - pswd = users_list.get_user_pswd(username) - is_teacher = users_list.get_user_is_teacher(username) - if is_teacher is None or is_teacher == False: - return jsonify({'success': False, 'message': '用户名不存在或非教师账号'}) - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/teacherboard') -@require_role(roles="teacher") -def teacherboard(): - return render_template('teacherboard.html') - - -@app.route('/logout') -def logout(): - session.pop('user_id', None) - return redirect(url_for('login')) - -@app.route('/get_session') -def get_session(): - user_session = session.get('user_id', 'default_session') - return jsonify({"session": user_session}) - - -''' -DashBoard -''' -user_id2UserClass = {} -@app.route('/dashboard') -@require_role -def dashboard(): - user_id = session['user_id'] - username = uuid2username[user_id] - if (user_id not in user_id2UserClass): - user_id2UserClass[user_id] = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - user_course_data = [] - for course_id in user_id2UserClass[user_id].select_course: - course_brief_info = course_list.get_course_brief_info(course_id, load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR)) - user_course_data.append(course_brief_info) - return render_template('dashboard.html',user_data = user_id2UserClass[user_id].to_json_without_dialog(), user_course_data = json.dumps(user_course_data)) - -''' -Course -''' - -@app.route('/course/') -@require_role -def course(course_id): - c = load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR) - return render_template('course.html', course_id=course_id, course_data=c) - -@app.route('/select_course', methods=['POST']) -@require_role -def select_course(): - user = user_id2UserClass[session['user_id']] - data = request.get_json() - course_id = data.get('course_id') - if course_id: - user.select_new_course(course_id, load_course_from_json(course_id, COURSE_DATA_DIR)) - return jsonify({'success': True, 'message': '课程选择成功'}) - - -@app.route('/') -@require_role -def home_index(): - selected_courses=[] - if ('user_id' in session): - if (session['user_id'] not in user_id2UserClass): return redirect(url_for('login')) - user = user_id2UserClass[session['user_id']] - for course_id in user.select_course: - selected_courses.append(course_id) - - return render_template('index.html', courses_data = course_list, selected_courses =selected_courses) - -# 一些app辅助函数,主要提供给Agent与数据库的交互能力 - -class MyFunction: - def save_chapter_memory(self, id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal): - print("-=-=-=-=-=-=-=-") - print(id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - username = uuid2username[id] - u = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - u.save_chapter_memory(course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - -app.my_function = MyFunction() -if __name__ == '__main__': - socketio.on_namespace(VSCodeNamespace('/vscode')) - socketio.on_namespace(AgentNamespace('/agent')) - socketio.run(app, host='0.0.0.0', port=5551, debug=False,allow_unsafe_werkzeug=True) - diff --git a/Html/runs/run_20250911-042303_dshgn3/code/backboardManager.py b/Html/runs/run_20250911-042303_dshgn3/code/backboardManager.py deleted file mode 100644 index 7de5f19..0000000 --- a/Html/runs/run_20250911-042303_dshgn3/code/backboardManager.py +++ /dev/null @@ -1,80 +0,0 @@ - - - -import time -import os - -class Backboard: - def __init__(self, user_uuid, username, course_id, lesson_id, root_path): - self.user_uuid = user_uuid - self.username = username - self.course_id = course_id - self.lesson_id = lesson_id - self.root_path = root_path - self.create_time = time.time() - self.enter_chapter_time = time.time() - self.history = [] - self.file_tree = "[]" - self.active_file_path = "" - self.active_file_content = "" - self.pasted_file_path = "" - self.pasted_content = "" - - - def next_chapter(self): - self.enter_chapter_time = time.time() - - def get_info_prompt(self): - - five_history = "" - for h in self.history[-5:]: - five_history += h['type'] + "\n" + h.get('filePath', '') + "\n\n" - - endl = "\n" - return (f"###Global Info:###{endl}" - f"Here are some info about now user's IDE, refer to it when you need to handle some code.{endl}" - f"- User's total study time is {self.get_deltatime_mmss(self.create_time, time.time())}{endl}" - f"- User's current chapter study time is {self.get_deltatime_mmss(self.enter_chapter_time, time.time())}{endl}" - f"- Activated file path: {self.active_file_path}{endl}" - f"```{endl}" - f"{self.active_file_content[-10:]}{endl}" - f"```{endl}" - f"- Last five action:{five_history}{endl}" - f"- File tree: {self.file_tree}{endl}") - # f"- Activated file content (current editing 10 lines): {endl}" - def add_history(self, realtime_action): - if(realtime_action['type']=='config'):return - if len(self.history)!=0: - if (self.history[-1]['type']=='fileEdit'): - if(self.history[-1]['filePath'] == realtime_action['filePath']): - self.history[-1]['content'] = realtime_action['content'] - return - self.history.append(realtime_action) - - - def get_deltatime_mmss(self, start_time, end_time): - elapsed_time = end_time - start_time - hours = int(elapsed_time // 3600) - minutes = int((elapsed_time % 3600) // 60) - seconds = int(elapsed_time % 60) - return f"{hours:02d}:{minutes:02d}:{seconds:02d}" - - - def get_active_file_reletive_path(self): - relative_path = os.path.relpath(self.active_file_path, self.root_path) - return relative_path - - - -class BackBoardManager: - def __init__(self): - self.backboards = {} # user_uuid: Backboard - - def add_backboard(self, user_uuid, username, course_id, lesson_id, root_path): - self.backboards[user_uuid] = Backboard(user_uuid,username, course_id, lesson_id, root_path) - - def get_backboard(self, user_uuid) -> Backboard: - return self.backboards[user_uuid] - - - diff --git a/Html/runs/run_20250911-042303_dshgn3/code/bootstrap.py b/Html/runs/run_20250911-042303_dshgn3/code/bootstrap.py deleted file mode 100644 index bcb15ce..0000000 --- a/Html/runs/run_20250911-042303_dshgn3/code/bootstrap.py +++ /dev/null @@ -1,31 +0,0 @@ -from pathlib import Path -import sys, os - -def bootstrap_paths(): - """ - 让 'AlgoriAgent'(位于 repo_root/AlgoriAgent)可被 import; - 并提供 STUDENT_WORKSPACE_ROOT 的默认值(repo_root/study)。 - 适配当前工厂位置:repo_root/Html/apps/__init__.py - """ - here = Path(__file__).resolve() - # repo_root = .../Html/apps/../../ => parents[2] - repo_root = here.parents[2] - - # 兜底:如果目录结构变化,尝试向上搜索包含 AlgoriAgent 的目录作为 repo_root - if not (repo_root / "AlgoriAgent").exists(): - for p in here.parents: - if (p / "AlgoriAgent").is_dir(): - repo_root = p - break - - # 确保仓库根在 sys.path(这样 'AlgoriAgent' 顶层包可被发现) - repo_root_str = str(repo_root) - if repo_root_str not in sys.path: - sys.path.insert(0, repo_root_str) - - # 可选:如果你还有其它顶层包,也可在此处继续插入 - - # 默认学习工作区目录(也可放到 config.ini / 环境变量覆盖) - os.environ.setdefault("STUDENT_WORKSPACE_ROOT", str(repo_root / "study")) - - return repo_root # 方便调试/日志 \ No newline at end of file diff --git a/Html/runs/run_20250911-042303_dshgn3/code/wsgi.py b/Html/runs/run_20250911-042303_dshgn3/code/wsgi.py deleted file mode 100644 index bbcbe5f..0000000 --- a/Html/runs/run_20250911-042303_dshgn3/code/wsgi.py +++ /dev/null @@ -1,6 +0,0 @@ -# wsgi.py -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -# 提供一个可被 WSGI/进程管理器导入的 app 对象 -app = create_app() diff --git a/Html/runs/run_20250911-042303_dshgn3/logging.chat b/Html/runs/run_20250911-042303_dshgn3/logging.chat deleted file mode 100644 index e69de29..0000000 diff --git a/Html/runs/run_20250911-042303_dshgn3/logging.log b/Html/runs/run_20250911-042303_dshgn3/logging.log deleted file mode 100644 index 6653cac..0000000 --- a/Html/runs/run_20250911-042303_dshgn3/logging.log +++ /dev/null @@ -1 +0,0 @@ -2025-09-11 04:23:07.463 | INFO | agentscope.models:read_model_configs:186 - Load configs for model wrapper: openai_cfg diff --git a/Html/runs/run_20250911-042540_a7q7yd/.config b/Html/runs/run_20250911-042540_a7q7yd/.config deleted file mode 100644 index b46de08..0000000 --- a/Html/runs/run_20250911-042540_a7q7yd/.config +++ /dev/null @@ -1,7 +0,0 @@ -{ - "project": "C8HiRw", - "name": "a7q7yd", - "run_id": "run_20250911-042540_a7q7yd", - "timestamp": "2025-09-11 04:25:40", - "pid": 17686 -} \ No newline at end of file diff --git a/Html/runs/run_20250911-042540_a7q7yd/agentscope.db b/Html/runs/run_20250911-042540_a7q7yd/agentscope.db deleted file mode 100644 index 666055b77679cda29c14fcf23b4ef1d039c5b52a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI%L2KJE6bEoS4Q(k)+glI2yjv3-0%NB!Hs&O1YUav`W0U1F<0V=#BsNLx(sSu$ z>=W&q?4#^B$!*yt2YT5l`~^0a^z(#~{ zkyg6w!t)u0!@f%5aeaJcfD9*Q_b$ozCY8>~CFA6|{Z2V!N;Z^cIq}eS$>x3HY|^=j z7lokrf1)Z$x@_R^N~@apn7OPMkZ(I<*1WJCw@v3GWy2n6&RcIQ0~zlR_x8^$%be!% zmxb7@7V;}H+K5#l(wSbZKXKY!mys6ROyi|!%aN@+%REpi?;B-K4PC3&{>iCzQnNB+ zwbW!z4iA{x(V_2L+5VJ1vMJeN;5l68yJ9?OZyl-TNCEp4P{^H8$cTGExdq$9ANE6@ zA@`ZUhb>is+Y=S?%$C1fnN{muZU1a!nMRV%#qFbMT;y3hf|KlJ)00Izz00bZa0SG_<0uX=z1a@EGHy1PL*Z=?k diff --git a/Html/runs/run_20250911-042540_a7q7yd/code/app.py b/Html/runs/run_20250911-042540_a7q7yd/code/app.py deleted file mode 100644 index c7f31f7..0000000 --- a/Html/runs/run_20250911-042540_a7q7yd/code/app.py +++ /dev/null @@ -1,21 +0,0 @@ -# app.py 0.1.1 rise to factory mode -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -from apps.extensions import socketio - -# 工厂创建 app,工厂里已经做了:加载配置/注册蓝图/注册 namespaces -app = create_app() - -if __name__ == "__main__": - # 仅本地开发用;生产不要用 werkzeug 自带的开发服务器 - socketio.run( - app, - host="0.0.0.0", - port=5551, - debug=True, # 开发期打开 - allow_unsafe_werkzeug=True, # 避免 dev server 的安全限制提示 - # ssl_context=('server.crt', 'server.key') - ) - - diff --git a/Html/runs/run_20250911-042540_a7q7yd/code/app_back.py b/Html/runs/run_20250911-042540_a7q7yd/code/app_back.py deleted file mode 100644 index 246853c..0000000 --- a/Html/runs/run_20250911-042540_a7q7yd/code/app_back.py +++ /dev/null @@ -1,480 +0,0 @@ -from bootstrap import bootstrap_paths -bootstrap_paths() -from functools import wraps -from flask import Flask, redirect, session, request, jsonify, render_template, send_from_directory, url_for -from flask_cors import CORS -from flask_socketio import SocketIO, join_room, emit, Namespace -import markdown -import os -import uuid -import shutil -import sys -import json -from apps.auth.decorators import require_role -parent_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) -sys.path.insert(0, parent_dir) -student_workspace_root_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../study')) -current_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '.')) -sys.path.insert(0, current_dir) -from AlgoriAgent.projects.algoriAgent.agent_manager import AgentManager - - -import configparser - -from db.user_list import UserList -from db.user import User, load_user_from_json, create_user_json -from db.course_list import CourseList -from db.course import Course, load_course_from_json -GLOBAL_CONFIG = configparser.ConfigParser() -GLOBAL_CONFIG.read('config.ini') -VSCODE_WEB_URL = GLOBAL_CONFIG['VSCODE_WEB']['url'] -USER_DATA_DIR = GLOBAL_CONFIG['USER_DATA']['dir'] -COURSE_DATA_DIR = GLOBAL_CONFIG['COURSE_DATA']['dir'] - -app = Flask(__name__) -socketio = SocketIO(app, cors_allowed_origins="*",ping_timeout=60, ping_interval=5) -# socketio = SocketIO(app, cors_allowed_origins="http://localhost:9888") # 设置跨域支持 -import logging -app.secret_key = 'cakebaker' -app.logger.setLevel(logging.DEBUG) -# 配置 CORS -CORS(app, resources={r"/*": {"origins": VSCODE_WEB_URL},}, supports_credentials=True) - - -userid_recorder = {} # user_id&path -> session['user_id'] - -''' -Backboard -''' -from backboardManager import BackBoardManager, Backboard - -backboard_manager = BackBoardManager() -uuid2username = {} -username2uuid = {} - - - -# 定义命名空间:用于和 VSCode 插件交流 -class VSCodeNamespace(Namespace): - def on_login(self,data): - print("VSCode client connected") - print(data) - dataconfig = data['config'] - user_id = dataconfig.get('user_id') - path = dataconfig.get('path') - course_id = dataconfig.get('course_id') - lesson_id = dataconfig.get('chapter_id') - print(f"User {user_id} connected with path: {path}") - useruuid = username2uuid[user_id] - join_room(useruuid, namespace='/vscode') - if backboard_manager.get_backboard(useruuid) == None: - backboard_manager.add_backboard(useruuid,user_id, course_id, lesson_id, path) - - - def on_message(self, data): - print(f"Received from VSCode client: {data}") - dataconfig = data['config'] - realtime_response(dataconfig, data) - # emit('response', {'message': 'Config data received and connection established'}) - def on_disconnect(self, data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - -def realtime_response(config, realtime_action): - user_id = config['user_id'] - folder_path = config['path'] - useruuid = username2uuid[user_id] - bb = backboard_manager.get_backboard(useruuid) - assert type(bb) == Backboard - - bb.add_history(realtime_action) - - if realtime_action['type'] == 'workspaceFolders': - bb.file_tree = realtime_action['fileTree'] - - if realtime_action['type'] == 'activeFile': - file_path = realtime_action['filePath'] - assert type(file_path) == str - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - if realtime_action['type'] == 'paste': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.pasted_file_path = file_path - bb.pasted_content = realtime_action['content'] - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - if realtime_action['type'] == 'fileEdit': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - - - print("config"+str(config)) - print("realtime_action"+str(realtime_action)) - pass - - -''' -Agent and Chat -''' -agent_manager = AgentManager(app = app, socketio = socketio) -user_threads = {} -import threading -from concurrent.futures import ThreadPoolExecutor, as_completed - -# 初始化线程池 -executor = ThreadPoolExecutor(max_workers=10) -class AgentNamespace(Namespace): - def on_login(self, data): - data = json.loads(data) - user = data['username'] - course_id = data['course_id'] - chapter_id = data['chapter_id'] - user_uuid = username2uuid[user] - session['user_id'] = user_uuid - print(f'User connected with session user_id: {user_uuid}') - # 从markdown、markdown_prompts、score_prompts中各读取数据folder.md并进行new_agent - with open(f'books/markdown/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fmd,\ - open(f'books/markdown_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8')as fmdp,\ - open(f'books/score_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fsp: - markdown = fmd.read() - markdown_prompts = fmdp.read() - score_prompts = fsp.read() - user_uuid, agent = agent_manager.new_agent(course_id, chapter_id, markdown, markdown_prompts, score_prompts, id=user_uuid, - root_path=f'../../study/{user}/{course_id}/{chapter_id}') - print(user_uuid) - join_room(user_uuid, namespace='/agent') # 将该用户加入以user_id为名的room - backboard_manager.add_backboard(user_uuid, user, course_id, chapter_id, root_path=f'../../study/{user}/{course_id}/{chapter_id}') - - def on_language(self, language): - id = session.get('user_id') - agent_manager.change_language(id, language) - - def on_message(self, data): - print(f"Message from client: {data}") - id = session.get('user_id') - if (type(data)==str): - data = json.loads(data) - print(id) - if data['type'] == 'text': - res = agent_manager.invoke(id, data['data'], backboard_manager.get_backboard(id).get_info_prompt()) - print('=*='*20) - print(res.content) - reply = f"{res.content['speak']}" - with app.app_context(): - emit('message',reply, room=id, namespace='/agent') - emit('request_function',res.content['function'], room=id, namespace='/agent') - - if data['type'] == 'function': - agent_manager.function_call(id, data['data']) - - def on_initiative(self,data): - print("User active function call") - user_id = session['user_id'] - if data['name'] == 'sample_judge': - agent_manager.sample_judge(user_id, backboard_manager.get_backboard(user_id)) - if data['name'] == 'judge': - agent_manager.judge(user_id, backboard_manager.get_backboard(user_id)) - - - - def on_disconnect(self,data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - - -''' -Markdown to HTML -''' -# 配置文件路径 -MARKDOWN_DIR = 'books/markdown' # 存放 markdown 文件的文件夹 -STATIC_DIR = 'static' # 存放生成的 HTML 和图片资源的文件夹 -IMAGE_DIR = 'image' # 图片资源相对于 markdown 的位置 - - - -@app.route('/--markdown', methods=['GET']) -def convert_md(course_id, filename): - md_file_path = os.path.join(MARKDOWN_DIR,course_id, f'{filename}.md') - - if not os.path.exists(md_file_path): - return jsonify({'error': 'Markdown file not found'}), 404 - - # 读取 markdown 文件内容 - with open(md_file_path, 'r', encoding='utf-8') as file: - md_content = file.read() - - # 将 markdown 转换为 HTML - html_content = markdown.markdown(md_content) - # 插入 CSS 样式,限制图片最大宽度为 100%,高度自动调整 - html_with_styles = f""" - - - - - - - {html_content} - - - """ - # 保存 HTML 文件到 static 文件夹 - html_output_path = os.path.join(STATIC_DIR, f'{filename}.html') - with open(html_output_path, 'w', encoding='utf-8') as html_file: - html_file.write(html_with_styles) - - # 处理图片资源,将 image/xxx 文件夹拷贝到 static/image/xxx - image_source_dir = os.path.join(MARKDOWN_DIR,course_id, IMAGE_DIR, filename) - image_target_dir = os.path.join(STATIC_DIR, IMAGE_DIR, filename) - print(f"Copying image resources from {image_source_dir} to {image_target_dir}") - if os.path.exists(image_source_dir): - # 确保 static/image/xxx 目录存在 - if not os.path.exists(image_target_dir): - os.makedirs(image_target_dir) - - # 拷贝图片资源 - for image_file in os.listdir(image_source_dir): - full_image_file_path = os.path.join(image_source_dir, image_file) - if os.path.isfile(full_image_file_path): - shutil.copy(full_image_file_path, image_target_dir) - - return jsonify({'html_url': f'/static/{filename}.html'}) - -# 静态文件(HTML 和图片资源)的访问 -@app.route('/static/') -def serve_static(filename): - return send_from_directory(STATIC_DIR, filename) - - -''' -Vscode -''' -@app.route('/desktop///') -def desktop(user_id, course_id, chapter_id): - if 'user_id' not in session: - # return redirect(url_for('login')) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ user_id + "uuid is"+ session['user_id']) - username2uuid[user_id] = session['user_id'] - uuid2username[session['user_id']] = user_id - userid_recorder[user_id+'&'+course_id] = session['user_id'] - - # 在学习目录下创建一个名为 user_id_path 的文件夹 - path_dir = os.path.join(student_workspace_root_path, user_id, course_id,chapter_id) - os.makedirs(path_dir, exist_ok=True) - # 在此文件夹内部创建一个.config文件,并写入 user_id=user_id\n path=path - config_path = os.path.join(path_dir, '.config') - if GLOBAL_CONFIG['VSCODE_WEB_PATH']['is_wsl']: # 如果是在 WSL 中运行,则将路径转换为 WSL 路径 - path_dir = path_dir.replace('\\', '/') - path_dir = path_dir.replace(GLOBAL_CONFIG['VSCODE_WEB_PATH']['windows_path'] , GLOBAL_CONFIG['VSCODE_WEB_PATH']['wsl_path']) - with open(config_path, 'w', encoding='utf-8') as f: - tmpd = {'user_id': user_id, 'course_id': course_id, 'chapter_id': chapter_id, 'path': path_dir} - json.dump(tmpd, f) - print('---------------------') - print(config_path) - return render_template('desktop.html', vscode_web_url=VSCODE_WEB_URL, user_id=user_id, course_id=course_id, chapter_id=chapter_id, workspace_path=path_dir) - -@app.route('/desktop_nouser//') -def desktop_nouser(course_id, chapter_id): - if 'user_id' not in session: - return redirect(url_for('login')) - user_id = session['user_id'] - username = uuid2username[user_id] - return redirect(url_for('desktop', user_id=username, course_id=course_id, chapter_id=chapter_id)) - -@app.route('/vscode_data', methods=['POST']) -def vscode_data(): - data = request.json - config = data['config'] - realtime_response(config,data) - print(f"Received data from VSCode: {data}") - return jsonify({"status": "success", "received": data}) - - - -''' -Login - -''' -users_list = UserList() -course_list = CourseList() - - -@app.route('/register') -def register(): - return render_template('register.html') - -@app.route('/register_teacher') -def register_teacher(): - return render_template('register_teacher.html') - -@app.route('/register_teacher_post', methods=['POST']) -def register_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password, teacher=True) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - -@app.route('/register_post', methods=['POST']) -def register_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - - -@app.route('/login') -def login(): - return render_template('login.html') - if 'user_id' not in session: - return render_template('login.html') - else: - return redirect(url_for('/')) - -@app.route('/login_post', methods=['POST']) -def login_post(): - # 获取请求的 JSON 数据 - data = request.get_json() - - username = data.get('username') - password = data.get('password') - - pswd = users_list.get_user_pswd(username) - - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/login_teacher_post', methods=['POST']) -def login_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - pswd = users_list.get_user_pswd(username) - is_teacher = users_list.get_user_is_teacher(username) - if is_teacher is None or is_teacher == False: - return jsonify({'success': False, 'message': '用户名不存在或非教师账号'}) - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/teacherboard') -@require_role(roles="teacher") -def teacherboard(): - return render_template('teacherboard.html') - - -@app.route('/logout') -def logout(): - session.pop('user_id', None) - return redirect(url_for('login')) - -@app.route('/get_session') -def get_session(): - user_session = session.get('user_id', 'default_session') - return jsonify({"session": user_session}) - - -''' -DashBoard -''' -user_id2UserClass = {} -@app.route('/dashboard') -@require_role -def dashboard(): - user_id = session['user_id'] - username = uuid2username[user_id] - if (user_id not in user_id2UserClass): - user_id2UserClass[user_id] = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - user_course_data = [] - for course_id in user_id2UserClass[user_id].select_course: - course_brief_info = course_list.get_course_brief_info(course_id, load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR)) - user_course_data.append(course_brief_info) - return render_template('dashboard.html',user_data = user_id2UserClass[user_id].to_json_without_dialog(), user_course_data = json.dumps(user_course_data)) - -''' -Course -''' - -@app.route('/course/') -@require_role -def course(course_id): - c = load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR) - return render_template('course.html', course_id=course_id, course_data=c) - -@app.route('/select_course', methods=['POST']) -@require_role -def select_course(): - user = user_id2UserClass[session['user_id']] - data = request.get_json() - course_id = data.get('course_id') - if course_id: - user.select_new_course(course_id, load_course_from_json(course_id, COURSE_DATA_DIR)) - return jsonify({'success': True, 'message': '课程选择成功'}) - - -@app.route('/') -@require_role -def home_index(): - selected_courses=[] - if ('user_id' in session): - if (session['user_id'] not in user_id2UserClass): return redirect(url_for('login')) - user = user_id2UserClass[session['user_id']] - for course_id in user.select_course: - selected_courses.append(course_id) - - return render_template('index.html', courses_data = course_list, selected_courses =selected_courses) - -# 一些app辅助函数,主要提供给Agent与数据库的交互能力 - -class MyFunction: - def save_chapter_memory(self, id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal): - print("-=-=-=-=-=-=-=-") - print(id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - username = uuid2username[id] - u = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - u.save_chapter_memory(course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - -app.my_function = MyFunction() -if __name__ == '__main__': - socketio.on_namespace(VSCodeNamespace('/vscode')) - socketio.on_namespace(AgentNamespace('/agent')) - socketio.run(app, host='0.0.0.0', port=5551, debug=False,allow_unsafe_werkzeug=True) - diff --git a/Html/runs/run_20250911-042540_a7q7yd/code/backboardManager.py b/Html/runs/run_20250911-042540_a7q7yd/code/backboardManager.py deleted file mode 100644 index 7de5f19..0000000 --- a/Html/runs/run_20250911-042540_a7q7yd/code/backboardManager.py +++ /dev/null @@ -1,80 +0,0 @@ - - - -import time -import os - -class Backboard: - def __init__(self, user_uuid, username, course_id, lesson_id, root_path): - self.user_uuid = user_uuid - self.username = username - self.course_id = course_id - self.lesson_id = lesson_id - self.root_path = root_path - self.create_time = time.time() - self.enter_chapter_time = time.time() - self.history = [] - self.file_tree = "[]" - self.active_file_path = "" - self.active_file_content = "" - self.pasted_file_path = "" - self.pasted_content = "" - - - def next_chapter(self): - self.enter_chapter_time = time.time() - - def get_info_prompt(self): - - five_history = "" - for h in self.history[-5:]: - five_history += h['type'] + "\n" + h.get('filePath', '') + "\n\n" - - endl = "\n" - return (f"###Global Info:###{endl}" - f"Here are some info about now user's IDE, refer to it when you need to handle some code.{endl}" - f"- User's total study time is {self.get_deltatime_mmss(self.create_time, time.time())}{endl}" - f"- User's current chapter study time is {self.get_deltatime_mmss(self.enter_chapter_time, time.time())}{endl}" - f"- Activated file path: {self.active_file_path}{endl}" - f"```{endl}" - f"{self.active_file_content[-10:]}{endl}" - f"```{endl}" - f"- Last five action:{five_history}{endl}" - f"- File tree: {self.file_tree}{endl}") - # f"- Activated file content (current editing 10 lines): {endl}" - def add_history(self, realtime_action): - if(realtime_action['type']=='config'):return - if len(self.history)!=0: - if (self.history[-1]['type']=='fileEdit'): - if(self.history[-1]['filePath'] == realtime_action['filePath']): - self.history[-1]['content'] = realtime_action['content'] - return - self.history.append(realtime_action) - - - def get_deltatime_mmss(self, start_time, end_time): - elapsed_time = end_time - start_time - hours = int(elapsed_time // 3600) - minutes = int((elapsed_time % 3600) // 60) - seconds = int(elapsed_time % 60) - return f"{hours:02d}:{minutes:02d}:{seconds:02d}" - - - def get_active_file_reletive_path(self): - relative_path = os.path.relpath(self.active_file_path, self.root_path) - return relative_path - - - -class BackBoardManager: - def __init__(self): - self.backboards = {} # user_uuid: Backboard - - def add_backboard(self, user_uuid, username, course_id, lesson_id, root_path): - self.backboards[user_uuid] = Backboard(user_uuid,username, course_id, lesson_id, root_path) - - def get_backboard(self, user_uuid) -> Backboard: - return self.backboards[user_uuid] - - - diff --git a/Html/runs/run_20250911-042540_a7q7yd/code/bootstrap.py b/Html/runs/run_20250911-042540_a7q7yd/code/bootstrap.py deleted file mode 100644 index bcb15ce..0000000 --- a/Html/runs/run_20250911-042540_a7q7yd/code/bootstrap.py +++ /dev/null @@ -1,31 +0,0 @@ -from pathlib import Path -import sys, os - -def bootstrap_paths(): - """ - 让 'AlgoriAgent'(位于 repo_root/AlgoriAgent)可被 import; - 并提供 STUDENT_WORKSPACE_ROOT 的默认值(repo_root/study)。 - 适配当前工厂位置:repo_root/Html/apps/__init__.py - """ - here = Path(__file__).resolve() - # repo_root = .../Html/apps/../../ => parents[2] - repo_root = here.parents[2] - - # 兜底:如果目录结构变化,尝试向上搜索包含 AlgoriAgent 的目录作为 repo_root - if not (repo_root / "AlgoriAgent").exists(): - for p in here.parents: - if (p / "AlgoriAgent").is_dir(): - repo_root = p - break - - # 确保仓库根在 sys.path(这样 'AlgoriAgent' 顶层包可被发现) - repo_root_str = str(repo_root) - if repo_root_str not in sys.path: - sys.path.insert(0, repo_root_str) - - # 可选:如果你还有其它顶层包,也可在此处继续插入 - - # 默认学习工作区目录(也可放到 config.ini / 环境变量覆盖) - os.environ.setdefault("STUDENT_WORKSPACE_ROOT", str(repo_root / "study")) - - return repo_root # 方便调试/日志 \ No newline at end of file diff --git a/Html/runs/run_20250911-042540_a7q7yd/code/wsgi.py b/Html/runs/run_20250911-042540_a7q7yd/code/wsgi.py deleted file mode 100644 index bbcbe5f..0000000 --- a/Html/runs/run_20250911-042540_a7q7yd/code/wsgi.py +++ /dev/null @@ -1,6 +0,0 @@ -# wsgi.py -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -# 提供一个可被 WSGI/进程管理器导入的 app 对象 -app = create_app() diff --git a/Html/runs/run_20250911-042540_a7q7yd/logging.chat b/Html/runs/run_20250911-042540_a7q7yd/logging.chat deleted file mode 100644 index e69de29..0000000 diff --git a/Html/runs/run_20250911-042540_a7q7yd/logging.log b/Html/runs/run_20250911-042540_a7q7yd/logging.log deleted file mode 100644 index 59ed79c..0000000 --- a/Html/runs/run_20250911-042540_a7q7yd/logging.log +++ /dev/null @@ -1 +0,0 @@ -2025-09-11 04:25:48.003 | INFO | agentscope.models:read_model_configs:186 - Load configs for model wrapper: openai_cfg diff --git a/Html/runs/run_20250911-042825_sfp33j/.config b/Html/runs/run_20250911-042825_sfp33j/.config deleted file mode 100644 index d0df888..0000000 --- a/Html/runs/run_20250911-042825_sfp33j/.config +++ /dev/null @@ -1,7 +0,0 @@ -{ - "project": "nZE5EB", - "name": "sfp33j", - "run_id": "run_20250911-042825_sfp33j", - "timestamp": "2025-09-11 04:28:25", - "pid": 18079 -} \ No newline at end of file diff --git a/Html/runs/run_20250911-042825_sfp33j/agentscope.db b/Html/runs/run_20250911-042825_sfp33j/agentscope.db deleted file mode 100644 index 666055b77679cda29c14fcf23b4ef1d039c5b52a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI%L2KJE6bEoS4Q(k)+glI2yjv3-0%NB!Hs&O1YUav`W0U1F<0V=#BsNLx(sSu$ z>=W&q?4#^B$!*yt2YT5l`~^0a^z(#~{ zkyg6w!t)u0!@f%5aeaJcfD9*Q_b$ozCY8>~CFA6|{Z2V!N;Z^cIq}eS$>x3HY|^=j z7lokrf1)Z$x@_R^N~@apn7OPMkZ(I<*1WJCw@v3GWy2n6&RcIQ0~zlR_x8^$%be!% zmxb7@7V;}H+K5#l(wSbZKXKY!mys6ROyi|!%aN@+%REpi?;B-K4PC3&{>iCzQnNB+ zwbW!z4iA{x(V_2L+5VJ1vMJeN;5l68yJ9?OZyl-TNCEp4P{^H8$cTGExdq$9ANE6@ zA@`ZUhb>is+Y=S?%$C1fnN{muZU1a!nMRV%#qFbMT;y3hf|KlJ)00Izz00bZa0SG_<0uX=z1a@EGHy1PL*Z=?k diff --git a/Html/runs/run_20250911-042825_sfp33j/code/app.py b/Html/runs/run_20250911-042825_sfp33j/code/app.py deleted file mode 100644 index c7f31f7..0000000 --- a/Html/runs/run_20250911-042825_sfp33j/code/app.py +++ /dev/null @@ -1,21 +0,0 @@ -# app.py 0.1.1 rise to factory mode -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -from apps.extensions import socketio - -# 工厂创建 app,工厂里已经做了:加载配置/注册蓝图/注册 namespaces -app = create_app() - -if __name__ == "__main__": - # 仅本地开发用;生产不要用 werkzeug 自带的开发服务器 - socketio.run( - app, - host="0.0.0.0", - port=5551, - debug=True, # 开发期打开 - allow_unsafe_werkzeug=True, # 避免 dev server 的安全限制提示 - # ssl_context=('server.crt', 'server.key') - ) - - diff --git a/Html/runs/run_20250911-042825_sfp33j/code/app_back.py b/Html/runs/run_20250911-042825_sfp33j/code/app_back.py deleted file mode 100644 index 246853c..0000000 --- a/Html/runs/run_20250911-042825_sfp33j/code/app_back.py +++ /dev/null @@ -1,480 +0,0 @@ -from bootstrap import bootstrap_paths -bootstrap_paths() -from functools import wraps -from flask import Flask, redirect, session, request, jsonify, render_template, send_from_directory, url_for -from flask_cors import CORS -from flask_socketio import SocketIO, join_room, emit, Namespace -import markdown -import os -import uuid -import shutil -import sys -import json -from apps.auth.decorators import require_role -parent_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) -sys.path.insert(0, parent_dir) -student_workspace_root_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../study')) -current_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '.')) -sys.path.insert(0, current_dir) -from AlgoriAgent.projects.algoriAgent.agent_manager import AgentManager - - -import configparser - -from db.user_list import UserList -from db.user import User, load_user_from_json, create_user_json -from db.course_list import CourseList -from db.course import Course, load_course_from_json -GLOBAL_CONFIG = configparser.ConfigParser() -GLOBAL_CONFIG.read('config.ini') -VSCODE_WEB_URL = GLOBAL_CONFIG['VSCODE_WEB']['url'] -USER_DATA_DIR = GLOBAL_CONFIG['USER_DATA']['dir'] -COURSE_DATA_DIR = GLOBAL_CONFIG['COURSE_DATA']['dir'] - -app = Flask(__name__) -socketio = SocketIO(app, cors_allowed_origins="*",ping_timeout=60, ping_interval=5) -# socketio = SocketIO(app, cors_allowed_origins="http://localhost:9888") # 设置跨域支持 -import logging -app.secret_key = 'cakebaker' -app.logger.setLevel(logging.DEBUG) -# 配置 CORS -CORS(app, resources={r"/*": {"origins": VSCODE_WEB_URL},}, supports_credentials=True) - - -userid_recorder = {} # user_id&path -> session['user_id'] - -''' -Backboard -''' -from backboardManager import BackBoardManager, Backboard - -backboard_manager = BackBoardManager() -uuid2username = {} -username2uuid = {} - - - -# 定义命名空间:用于和 VSCode 插件交流 -class VSCodeNamespace(Namespace): - def on_login(self,data): - print("VSCode client connected") - print(data) - dataconfig = data['config'] - user_id = dataconfig.get('user_id') - path = dataconfig.get('path') - course_id = dataconfig.get('course_id') - lesson_id = dataconfig.get('chapter_id') - print(f"User {user_id} connected with path: {path}") - useruuid = username2uuid[user_id] - join_room(useruuid, namespace='/vscode') - if backboard_manager.get_backboard(useruuid) == None: - backboard_manager.add_backboard(useruuid,user_id, course_id, lesson_id, path) - - - def on_message(self, data): - print(f"Received from VSCode client: {data}") - dataconfig = data['config'] - realtime_response(dataconfig, data) - # emit('response', {'message': 'Config data received and connection established'}) - def on_disconnect(self, data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - -def realtime_response(config, realtime_action): - user_id = config['user_id'] - folder_path = config['path'] - useruuid = username2uuid[user_id] - bb = backboard_manager.get_backboard(useruuid) - assert type(bb) == Backboard - - bb.add_history(realtime_action) - - if realtime_action['type'] == 'workspaceFolders': - bb.file_tree = realtime_action['fileTree'] - - if realtime_action['type'] == 'activeFile': - file_path = realtime_action['filePath'] - assert type(file_path) == str - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - if realtime_action['type'] == 'paste': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.pasted_file_path = file_path - bb.pasted_content = realtime_action['content'] - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - if realtime_action['type'] == 'fileEdit': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - - - print("config"+str(config)) - print("realtime_action"+str(realtime_action)) - pass - - -''' -Agent and Chat -''' -agent_manager = AgentManager(app = app, socketio = socketio) -user_threads = {} -import threading -from concurrent.futures import ThreadPoolExecutor, as_completed - -# 初始化线程池 -executor = ThreadPoolExecutor(max_workers=10) -class AgentNamespace(Namespace): - def on_login(self, data): - data = json.loads(data) - user = data['username'] - course_id = data['course_id'] - chapter_id = data['chapter_id'] - user_uuid = username2uuid[user] - session['user_id'] = user_uuid - print(f'User connected with session user_id: {user_uuid}') - # 从markdown、markdown_prompts、score_prompts中各读取数据folder.md并进行new_agent - with open(f'books/markdown/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fmd,\ - open(f'books/markdown_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8')as fmdp,\ - open(f'books/score_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fsp: - markdown = fmd.read() - markdown_prompts = fmdp.read() - score_prompts = fsp.read() - user_uuid, agent = agent_manager.new_agent(course_id, chapter_id, markdown, markdown_prompts, score_prompts, id=user_uuid, - root_path=f'../../study/{user}/{course_id}/{chapter_id}') - print(user_uuid) - join_room(user_uuid, namespace='/agent') # 将该用户加入以user_id为名的room - backboard_manager.add_backboard(user_uuid, user, course_id, chapter_id, root_path=f'../../study/{user}/{course_id}/{chapter_id}') - - def on_language(self, language): - id = session.get('user_id') - agent_manager.change_language(id, language) - - def on_message(self, data): - print(f"Message from client: {data}") - id = session.get('user_id') - if (type(data)==str): - data = json.loads(data) - print(id) - if data['type'] == 'text': - res = agent_manager.invoke(id, data['data'], backboard_manager.get_backboard(id).get_info_prompt()) - print('=*='*20) - print(res.content) - reply = f"{res.content['speak']}" - with app.app_context(): - emit('message',reply, room=id, namespace='/agent') - emit('request_function',res.content['function'], room=id, namespace='/agent') - - if data['type'] == 'function': - agent_manager.function_call(id, data['data']) - - def on_initiative(self,data): - print("User active function call") - user_id = session['user_id'] - if data['name'] == 'sample_judge': - agent_manager.sample_judge(user_id, backboard_manager.get_backboard(user_id)) - if data['name'] == 'judge': - agent_manager.judge(user_id, backboard_manager.get_backboard(user_id)) - - - - def on_disconnect(self,data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - - -''' -Markdown to HTML -''' -# 配置文件路径 -MARKDOWN_DIR = 'books/markdown' # 存放 markdown 文件的文件夹 -STATIC_DIR = 'static' # 存放生成的 HTML 和图片资源的文件夹 -IMAGE_DIR = 'image' # 图片资源相对于 markdown 的位置 - - - -@app.route('/--markdown', methods=['GET']) -def convert_md(course_id, filename): - md_file_path = os.path.join(MARKDOWN_DIR,course_id, f'{filename}.md') - - if not os.path.exists(md_file_path): - return jsonify({'error': 'Markdown file not found'}), 404 - - # 读取 markdown 文件内容 - with open(md_file_path, 'r', encoding='utf-8') as file: - md_content = file.read() - - # 将 markdown 转换为 HTML - html_content = markdown.markdown(md_content) - # 插入 CSS 样式,限制图片最大宽度为 100%,高度自动调整 - html_with_styles = f""" - - - - - - - {html_content} - - - """ - # 保存 HTML 文件到 static 文件夹 - html_output_path = os.path.join(STATIC_DIR, f'{filename}.html') - with open(html_output_path, 'w', encoding='utf-8') as html_file: - html_file.write(html_with_styles) - - # 处理图片资源,将 image/xxx 文件夹拷贝到 static/image/xxx - image_source_dir = os.path.join(MARKDOWN_DIR,course_id, IMAGE_DIR, filename) - image_target_dir = os.path.join(STATIC_DIR, IMAGE_DIR, filename) - print(f"Copying image resources from {image_source_dir} to {image_target_dir}") - if os.path.exists(image_source_dir): - # 确保 static/image/xxx 目录存在 - if not os.path.exists(image_target_dir): - os.makedirs(image_target_dir) - - # 拷贝图片资源 - for image_file in os.listdir(image_source_dir): - full_image_file_path = os.path.join(image_source_dir, image_file) - if os.path.isfile(full_image_file_path): - shutil.copy(full_image_file_path, image_target_dir) - - return jsonify({'html_url': f'/static/{filename}.html'}) - -# 静态文件(HTML 和图片资源)的访问 -@app.route('/static/') -def serve_static(filename): - return send_from_directory(STATIC_DIR, filename) - - -''' -Vscode -''' -@app.route('/desktop///') -def desktop(user_id, course_id, chapter_id): - if 'user_id' not in session: - # return redirect(url_for('login')) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ user_id + "uuid is"+ session['user_id']) - username2uuid[user_id] = session['user_id'] - uuid2username[session['user_id']] = user_id - userid_recorder[user_id+'&'+course_id] = session['user_id'] - - # 在学习目录下创建一个名为 user_id_path 的文件夹 - path_dir = os.path.join(student_workspace_root_path, user_id, course_id,chapter_id) - os.makedirs(path_dir, exist_ok=True) - # 在此文件夹内部创建一个.config文件,并写入 user_id=user_id\n path=path - config_path = os.path.join(path_dir, '.config') - if GLOBAL_CONFIG['VSCODE_WEB_PATH']['is_wsl']: # 如果是在 WSL 中运行,则将路径转换为 WSL 路径 - path_dir = path_dir.replace('\\', '/') - path_dir = path_dir.replace(GLOBAL_CONFIG['VSCODE_WEB_PATH']['windows_path'] , GLOBAL_CONFIG['VSCODE_WEB_PATH']['wsl_path']) - with open(config_path, 'w', encoding='utf-8') as f: - tmpd = {'user_id': user_id, 'course_id': course_id, 'chapter_id': chapter_id, 'path': path_dir} - json.dump(tmpd, f) - print('---------------------') - print(config_path) - return render_template('desktop.html', vscode_web_url=VSCODE_WEB_URL, user_id=user_id, course_id=course_id, chapter_id=chapter_id, workspace_path=path_dir) - -@app.route('/desktop_nouser//') -def desktop_nouser(course_id, chapter_id): - if 'user_id' not in session: - return redirect(url_for('login')) - user_id = session['user_id'] - username = uuid2username[user_id] - return redirect(url_for('desktop', user_id=username, course_id=course_id, chapter_id=chapter_id)) - -@app.route('/vscode_data', methods=['POST']) -def vscode_data(): - data = request.json - config = data['config'] - realtime_response(config,data) - print(f"Received data from VSCode: {data}") - return jsonify({"status": "success", "received": data}) - - - -''' -Login - -''' -users_list = UserList() -course_list = CourseList() - - -@app.route('/register') -def register(): - return render_template('register.html') - -@app.route('/register_teacher') -def register_teacher(): - return render_template('register_teacher.html') - -@app.route('/register_teacher_post', methods=['POST']) -def register_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password, teacher=True) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - -@app.route('/register_post', methods=['POST']) -def register_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - - -@app.route('/login') -def login(): - return render_template('login.html') - if 'user_id' not in session: - return render_template('login.html') - else: - return redirect(url_for('/')) - -@app.route('/login_post', methods=['POST']) -def login_post(): - # 获取请求的 JSON 数据 - data = request.get_json() - - username = data.get('username') - password = data.get('password') - - pswd = users_list.get_user_pswd(username) - - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/login_teacher_post', methods=['POST']) -def login_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - pswd = users_list.get_user_pswd(username) - is_teacher = users_list.get_user_is_teacher(username) - if is_teacher is None or is_teacher == False: - return jsonify({'success': False, 'message': '用户名不存在或非教师账号'}) - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/teacherboard') -@require_role(roles="teacher") -def teacherboard(): - return render_template('teacherboard.html') - - -@app.route('/logout') -def logout(): - session.pop('user_id', None) - return redirect(url_for('login')) - -@app.route('/get_session') -def get_session(): - user_session = session.get('user_id', 'default_session') - return jsonify({"session": user_session}) - - -''' -DashBoard -''' -user_id2UserClass = {} -@app.route('/dashboard') -@require_role -def dashboard(): - user_id = session['user_id'] - username = uuid2username[user_id] - if (user_id not in user_id2UserClass): - user_id2UserClass[user_id] = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - user_course_data = [] - for course_id in user_id2UserClass[user_id].select_course: - course_brief_info = course_list.get_course_brief_info(course_id, load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR)) - user_course_data.append(course_brief_info) - return render_template('dashboard.html',user_data = user_id2UserClass[user_id].to_json_without_dialog(), user_course_data = json.dumps(user_course_data)) - -''' -Course -''' - -@app.route('/course/') -@require_role -def course(course_id): - c = load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR) - return render_template('course.html', course_id=course_id, course_data=c) - -@app.route('/select_course', methods=['POST']) -@require_role -def select_course(): - user = user_id2UserClass[session['user_id']] - data = request.get_json() - course_id = data.get('course_id') - if course_id: - user.select_new_course(course_id, load_course_from_json(course_id, COURSE_DATA_DIR)) - return jsonify({'success': True, 'message': '课程选择成功'}) - - -@app.route('/') -@require_role -def home_index(): - selected_courses=[] - if ('user_id' in session): - if (session['user_id'] not in user_id2UserClass): return redirect(url_for('login')) - user = user_id2UserClass[session['user_id']] - for course_id in user.select_course: - selected_courses.append(course_id) - - return render_template('index.html', courses_data = course_list, selected_courses =selected_courses) - -# 一些app辅助函数,主要提供给Agent与数据库的交互能力 - -class MyFunction: - def save_chapter_memory(self, id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal): - print("-=-=-=-=-=-=-=-") - print(id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - username = uuid2username[id] - u = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - u.save_chapter_memory(course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - -app.my_function = MyFunction() -if __name__ == '__main__': - socketio.on_namespace(VSCodeNamespace('/vscode')) - socketio.on_namespace(AgentNamespace('/agent')) - socketio.run(app, host='0.0.0.0', port=5551, debug=False,allow_unsafe_werkzeug=True) - diff --git a/Html/runs/run_20250911-042825_sfp33j/code/backboardManager.py b/Html/runs/run_20250911-042825_sfp33j/code/backboardManager.py deleted file mode 100644 index 7de5f19..0000000 --- a/Html/runs/run_20250911-042825_sfp33j/code/backboardManager.py +++ /dev/null @@ -1,80 +0,0 @@ - - - -import time -import os - -class Backboard: - def __init__(self, user_uuid, username, course_id, lesson_id, root_path): - self.user_uuid = user_uuid - self.username = username - self.course_id = course_id - self.lesson_id = lesson_id - self.root_path = root_path - self.create_time = time.time() - self.enter_chapter_time = time.time() - self.history = [] - self.file_tree = "[]" - self.active_file_path = "" - self.active_file_content = "" - self.pasted_file_path = "" - self.pasted_content = "" - - - def next_chapter(self): - self.enter_chapter_time = time.time() - - def get_info_prompt(self): - - five_history = "" - for h in self.history[-5:]: - five_history += h['type'] + "\n" + h.get('filePath', '') + "\n\n" - - endl = "\n" - return (f"###Global Info:###{endl}" - f"Here are some info about now user's IDE, refer to it when you need to handle some code.{endl}" - f"- User's total study time is {self.get_deltatime_mmss(self.create_time, time.time())}{endl}" - f"- User's current chapter study time is {self.get_deltatime_mmss(self.enter_chapter_time, time.time())}{endl}" - f"- Activated file path: {self.active_file_path}{endl}" - f"```{endl}" - f"{self.active_file_content[-10:]}{endl}" - f"```{endl}" - f"- Last five action:{five_history}{endl}" - f"- File tree: {self.file_tree}{endl}") - # f"- Activated file content (current editing 10 lines): {endl}" - def add_history(self, realtime_action): - if(realtime_action['type']=='config'):return - if len(self.history)!=0: - if (self.history[-1]['type']=='fileEdit'): - if(self.history[-1]['filePath'] == realtime_action['filePath']): - self.history[-1]['content'] = realtime_action['content'] - return - self.history.append(realtime_action) - - - def get_deltatime_mmss(self, start_time, end_time): - elapsed_time = end_time - start_time - hours = int(elapsed_time // 3600) - minutes = int((elapsed_time % 3600) // 60) - seconds = int(elapsed_time % 60) - return f"{hours:02d}:{minutes:02d}:{seconds:02d}" - - - def get_active_file_reletive_path(self): - relative_path = os.path.relpath(self.active_file_path, self.root_path) - return relative_path - - - -class BackBoardManager: - def __init__(self): - self.backboards = {} # user_uuid: Backboard - - def add_backboard(self, user_uuid, username, course_id, lesson_id, root_path): - self.backboards[user_uuid] = Backboard(user_uuid,username, course_id, lesson_id, root_path) - - def get_backboard(self, user_uuid) -> Backboard: - return self.backboards[user_uuid] - - - diff --git a/Html/runs/run_20250911-042825_sfp33j/code/bootstrap.py b/Html/runs/run_20250911-042825_sfp33j/code/bootstrap.py deleted file mode 100644 index bcb15ce..0000000 --- a/Html/runs/run_20250911-042825_sfp33j/code/bootstrap.py +++ /dev/null @@ -1,31 +0,0 @@ -from pathlib import Path -import sys, os - -def bootstrap_paths(): - """ - 让 'AlgoriAgent'(位于 repo_root/AlgoriAgent)可被 import; - 并提供 STUDENT_WORKSPACE_ROOT 的默认值(repo_root/study)。 - 适配当前工厂位置:repo_root/Html/apps/__init__.py - """ - here = Path(__file__).resolve() - # repo_root = .../Html/apps/../../ => parents[2] - repo_root = here.parents[2] - - # 兜底:如果目录结构变化,尝试向上搜索包含 AlgoriAgent 的目录作为 repo_root - if not (repo_root / "AlgoriAgent").exists(): - for p in here.parents: - if (p / "AlgoriAgent").is_dir(): - repo_root = p - break - - # 确保仓库根在 sys.path(这样 'AlgoriAgent' 顶层包可被发现) - repo_root_str = str(repo_root) - if repo_root_str not in sys.path: - sys.path.insert(0, repo_root_str) - - # 可选:如果你还有其它顶层包,也可在此处继续插入 - - # 默认学习工作区目录(也可放到 config.ini / 环境变量覆盖) - os.environ.setdefault("STUDENT_WORKSPACE_ROOT", str(repo_root / "study")) - - return repo_root # 方便调试/日志 \ No newline at end of file diff --git a/Html/runs/run_20250911-042825_sfp33j/code/wsgi.py b/Html/runs/run_20250911-042825_sfp33j/code/wsgi.py deleted file mode 100644 index bbcbe5f..0000000 --- a/Html/runs/run_20250911-042825_sfp33j/code/wsgi.py +++ /dev/null @@ -1,6 +0,0 @@ -# wsgi.py -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -# 提供一个可被 WSGI/进程管理器导入的 app 对象 -app = create_app() diff --git a/Html/runs/run_20250911-042825_sfp33j/logging.chat b/Html/runs/run_20250911-042825_sfp33j/logging.chat deleted file mode 100644 index e69de29..0000000 diff --git a/Html/runs/run_20250911-042825_sfp33j/logging.log b/Html/runs/run_20250911-042825_sfp33j/logging.log deleted file mode 100644 index 8d25703..0000000 --- a/Html/runs/run_20250911-042825_sfp33j/logging.log +++ /dev/null @@ -1 +0,0 @@ -2025-09-11 04:28:30.929 | INFO | agentscope.models:read_model_configs:186 - Load configs for model wrapper: openai_cfg diff --git a/Html/runs/run_20250911-055537_tio6to/.config b/Html/runs/run_20250911-055537_tio6to/.config deleted file mode 100644 index 5cdcac2..0000000 --- a/Html/runs/run_20250911-055537_tio6to/.config +++ /dev/null @@ -1,7 +0,0 @@ -{ - "project": "o34vU2", - "name": "tio6to", - "run_id": "run_20250911-055537_tio6to", - "timestamp": "2025-09-11 05:55:37", - "pid": 30630 -} \ No newline at end of file diff --git a/Html/runs/run_20250911-055537_tio6to/agentscope.db b/Html/runs/run_20250911-055537_tio6to/agentscope.db deleted file mode 100644 index 666055b77679cda29c14fcf23b4ef1d039c5b52a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI%L2KJE6bEoS4Q(k)+glI2yjv3-0%NB!Hs&O1YUav`W0U1F<0V=#BsNLx(sSu$ z>=W&q?4#^B$!*yt2YT5l`~^0a^z(#~{ zkyg6w!t)u0!@f%5aeaJcfD9*Q_b$ozCY8>~CFA6|{Z2V!N;Z^cIq}eS$>x3HY|^=j z7lokrf1)Z$x@_R^N~@apn7OPMkZ(I<*1WJCw@v3GWy2n6&RcIQ0~zlR_x8^$%be!% zmxb7@7V;}H+K5#l(wSbZKXKY!mys6ROyi|!%aN@+%REpi?;B-K4PC3&{>iCzQnNB+ zwbW!z4iA{x(V_2L+5VJ1vMJeN;5l68yJ9?OZyl-TNCEp4P{^H8$cTGExdq$9ANE6@ zA@`ZUhb>is+Y=S?%$C1fnN{muZU1a!nMRV%#qFbMT;y3hf|KlJ)00Izz00bZa0SG_<0uX=z1a@EGHy1PL*Z=?k diff --git a/Html/runs/run_20250911-055537_tio6to/code/app.py b/Html/runs/run_20250911-055537_tio6to/code/app.py deleted file mode 100644 index c7f31f7..0000000 --- a/Html/runs/run_20250911-055537_tio6to/code/app.py +++ /dev/null @@ -1,21 +0,0 @@ -# app.py 0.1.1 rise to factory mode -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -from apps.extensions import socketio - -# 工厂创建 app,工厂里已经做了:加载配置/注册蓝图/注册 namespaces -app = create_app() - -if __name__ == "__main__": - # 仅本地开发用;生产不要用 werkzeug 自带的开发服务器 - socketio.run( - app, - host="0.0.0.0", - port=5551, - debug=True, # 开发期打开 - allow_unsafe_werkzeug=True, # 避免 dev server 的安全限制提示 - # ssl_context=('server.crt', 'server.key') - ) - - diff --git a/Html/runs/run_20250911-055537_tio6to/code/app_back.py b/Html/runs/run_20250911-055537_tio6to/code/app_back.py deleted file mode 100644 index 246853c..0000000 --- a/Html/runs/run_20250911-055537_tio6to/code/app_back.py +++ /dev/null @@ -1,480 +0,0 @@ -from bootstrap import bootstrap_paths -bootstrap_paths() -from functools import wraps -from flask import Flask, redirect, session, request, jsonify, render_template, send_from_directory, url_for -from flask_cors import CORS -from flask_socketio import SocketIO, join_room, emit, Namespace -import markdown -import os -import uuid -import shutil -import sys -import json -from apps.auth.decorators import require_role -parent_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) -sys.path.insert(0, parent_dir) -student_workspace_root_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../study')) -current_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '.')) -sys.path.insert(0, current_dir) -from AlgoriAgent.projects.algoriAgent.agent_manager import AgentManager - - -import configparser - -from db.user_list import UserList -from db.user import User, load_user_from_json, create_user_json -from db.course_list import CourseList -from db.course import Course, load_course_from_json -GLOBAL_CONFIG = configparser.ConfigParser() -GLOBAL_CONFIG.read('config.ini') -VSCODE_WEB_URL = GLOBAL_CONFIG['VSCODE_WEB']['url'] -USER_DATA_DIR = GLOBAL_CONFIG['USER_DATA']['dir'] -COURSE_DATA_DIR = GLOBAL_CONFIG['COURSE_DATA']['dir'] - -app = Flask(__name__) -socketio = SocketIO(app, cors_allowed_origins="*",ping_timeout=60, ping_interval=5) -# socketio = SocketIO(app, cors_allowed_origins="http://localhost:9888") # 设置跨域支持 -import logging -app.secret_key = 'cakebaker' -app.logger.setLevel(logging.DEBUG) -# 配置 CORS -CORS(app, resources={r"/*": {"origins": VSCODE_WEB_URL},}, supports_credentials=True) - - -userid_recorder = {} # user_id&path -> session['user_id'] - -''' -Backboard -''' -from backboardManager import BackBoardManager, Backboard - -backboard_manager = BackBoardManager() -uuid2username = {} -username2uuid = {} - - - -# 定义命名空间:用于和 VSCode 插件交流 -class VSCodeNamespace(Namespace): - def on_login(self,data): - print("VSCode client connected") - print(data) - dataconfig = data['config'] - user_id = dataconfig.get('user_id') - path = dataconfig.get('path') - course_id = dataconfig.get('course_id') - lesson_id = dataconfig.get('chapter_id') - print(f"User {user_id} connected with path: {path}") - useruuid = username2uuid[user_id] - join_room(useruuid, namespace='/vscode') - if backboard_manager.get_backboard(useruuid) == None: - backboard_manager.add_backboard(useruuid,user_id, course_id, lesson_id, path) - - - def on_message(self, data): - print(f"Received from VSCode client: {data}") - dataconfig = data['config'] - realtime_response(dataconfig, data) - # emit('response', {'message': 'Config data received and connection established'}) - def on_disconnect(self, data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - -def realtime_response(config, realtime_action): - user_id = config['user_id'] - folder_path = config['path'] - useruuid = username2uuid[user_id] - bb = backboard_manager.get_backboard(useruuid) - assert type(bb) == Backboard - - bb.add_history(realtime_action) - - if realtime_action['type'] == 'workspaceFolders': - bb.file_tree = realtime_action['fileTree'] - - if realtime_action['type'] == 'activeFile': - file_path = realtime_action['filePath'] - assert type(file_path) == str - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - if realtime_action['type'] == 'paste': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.pasted_file_path = file_path - bb.pasted_content = realtime_action['content'] - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - if realtime_action['type'] == 'fileEdit': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - - - print("config"+str(config)) - print("realtime_action"+str(realtime_action)) - pass - - -''' -Agent and Chat -''' -agent_manager = AgentManager(app = app, socketio = socketio) -user_threads = {} -import threading -from concurrent.futures import ThreadPoolExecutor, as_completed - -# 初始化线程池 -executor = ThreadPoolExecutor(max_workers=10) -class AgentNamespace(Namespace): - def on_login(self, data): - data = json.loads(data) - user = data['username'] - course_id = data['course_id'] - chapter_id = data['chapter_id'] - user_uuid = username2uuid[user] - session['user_id'] = user_uuid - print(f'User connected with session user_id: {user_uuid}') - # 从markdown、markdown_prompts、score_prompts中各读取数据folder.md并进行new_agent - with open(f'books/markdown/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fmd,\ - open(f'books/markdown_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8')as fmdp,\ - open(f'books/score_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fsp: - markdown = fmd.read() - markdown_prompts = fmdp.read() - score_prompts = fsp.read() - user_uuid, agent = agent_manager.new_agent(course_id, chapter_id, markdown, markdown_prompts, score_prompts, id=user_uuid, - root_path=f'../../study/{user}/{course_id}/{chapter_id}') - print(user_uuid) - join_room(user_uuid, namespace='/agent') # 将该用户加入以user_id为名的room - backboard_manager.add_backboard(user_uuid, user, course_id, chapter_id, root_path=f'../../study/{user}/{course_id}/{chapter_id}') - - def on_language(self, language): - id = session.get('user_id') - agent_manager.change_language(id, language) - - def on_message(self, data): - print(f"Message from client: {data}") - id = session.get('user_id') - if (type(data)==str): - data = json.loads(data) - print(id) - if data['type'] == 'text': - res = agent_manager.invoke(id, data['data'], backboard_manager.get_backboard(id).get_info_prompt()) - print('=*='*20) - print(res.content) - reply = f"{res.content['speak']}" - with app.app_context(): - emit('message',reply, room=id, namespace='/agent') - emit('request_function',res.content['function'], room=id, namespace='/agent') - - if data['type'] == 'function': - agent_manager.function_call(id, data['data']) - - def on_initiative(self,data): - print("User active function call") - user_id = session['user_id'] - if data['name'] == 'sample_judge': - agent_manager.sample_judge(user_id, backboard_manager.get_backboard(user_id)) - if data['name'] == 'judge': - agent_manager.judge(user_id, backboard_manager.get_backboard(user_id)) - - - - def on_disconnect(self,data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - - -''' -Markdown to HTML -''' -# 配置文件路径 -MARKDOWN_DIR = 'books/markdown' # 存放 markdown 文件的文件夹 -STATIC_DIR = 'static' # 存放生成的 HTML 和图片资源的文件夹 -IMAGE_DIR = 'image' # 图片资源相对于 markdown 的位置 - - - -@app.route('/--markdown', methods=['GET']) -def convert_md(course_id, filename): - md_file_path = os.path.join(MARKDOWN_DIR,course_id, f'{filename}.md') - - if not os.path.exists(md_file_path): - return jsonify({'error': 'Markdown file not found'}), 404 - - # 读取 markdown 文件内容 - with open(md_file_path, 'r', encoding='utf-8') as file: - md_content = file.read() - - # 将 markdown 转换为 HTML - html_content = markdown.markdown(md_content) - # 插入 CSS 样式,限制图片最大宽度为 100%,高度自动调整 - html_with_styles = f""" - - - - - - - {html_content} - - - """ - # 保存 HTML 文件到 static 文件夹 - html_output_path = os.path.join(STATIC_DIR, f'{filename}.html') - with open(html_output_path, 'w', encoding='utf-8') as html_file: - html_file.write(html_with_styles) - - # 处理图片资源,将 image/xxx 文件夹拷贝到 static/image/xxx - image_source_dir = os.path.join(MARKDOWN_DIR,course_id, IMAGE_DIR, filename) - image_target_dir = os.path.join(STATIC_DIR, IMAGE_DIR, filename) - print(f"Copying image resources from {image_source_dir} to {image_target_dir}") - if os.path.exists(image_source_dir): - # 确保 static/image/xxx 目录存在 - if not os.path.exists(image_target_dir): - os.makedirs(image_target_dir) - - # 拷贝图片资源 - for image_file in os.listdir(image_source_dir): - full_image_file_path = os.path.join(image_source_dir, image_file) - if os.path.isfile(full_image_file_path): - shutil.copy(full_image_file_path, image_target_dir) - - return jsonify({'html_url': f'/static/{filename}.html'}) - -# 静态文件(HTML 和图片资源)的访问 -@app.route('/static/') -def serve_static(filename): - return send_from_directory(STATIC_DIR, filename) - - -''' -Vscode -''' -@app.route('/desktop///') -def desktop(user_id, course_id, chapter_id): - if 'user_id' not in session: - # return redirect(url_for('login')) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ user_id + "uuid is"+ session['user_id']) - username2uuid[user_id] = session['user_id'] - uuid2username[session['user_id']] = user_id - userid_recorder[user_id+'&'+course_id] = session['user_id'] - - # 在学习目录下创建一个名为 user_id_path 的文件夹 - path_dir = os.path.join(student_workspace_root_path, user_id, course_id,chapter_id) - os.makedirs(path_dir, exist_ok=True) - # 在此文件夹内部创建一个.config文件,并写入 user_id=user_id\n path=path - config_path = os.path.join(path_dir, '.config') - if GLOBAL_CONFIG['VSCODE_WEB_PATH']['is_wsl']: # 如果是在 WSL 中运行,则将路径转换为 WSL 路径 - path_dir = path_dir.replace('\\', '/') - path_dir = path_dir.replace(GLOBAL_CONFIG['VSCODE_WEB_PATH']['windows_path'] , GLOBAL_CONFIG['VSCODE_WEB_PATH']['wsl_path']) - with open(config_path, 'w', encoding='utf-8') as f: - tmpd = {'user_id': user_id, 'course_id': course_id, 'chapter_id': chapter_id, 'path': path_dir} - json.dump(tmpd, f) - print('---------------------') - print(config_path) - return render_template('desktop.html', vscode_web_url=VSCODE_WEB_URL, user_id=user_id, course_id=course_id, chapter_id=chapter_id, workspace_path=path_dir) - -@app.route('/desktop_nouser//') -def desktop_nouser(course_id, chapter_id): - if 'user_id' not in session: - return redirect(url_for('login')) - user_id = session['user_id'] - username = uuid2username[user_id] - return redirect(url_for('desktop', user_id=username, course_id=course_id, chapter_id=chapter_id)) - -@app.route('/vscode_data', methods=['POST']) -def vscode_data(): - data = request.json - config = data['config'] - realtime_response(config,data) - print(f"Received data from VSCode: {data}") - return jsonify({"status": "success", "received": data}) - - - -''' -Login - -''' -users_list = UserList() -course_list = CourseList() - - -@app.route('/register') -def register(): - return render_template('register.html') - -@app.route('/register_teacher') -def register_teacher(): - return render_template('register_teacher.html') - -@app.route('/register_teacher_post', methods=['POST']) -def register_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password, teacher=True) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - -@app.route('/register_post', methods=['POST']) -def register_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - - -@app.route('/login') -def login(): - return render_template('login.html') - if 'user_id' not in session: - return render_template('login.html') - else: - return redirect(url_for('/')) - -@app.route('/login_post', methods=['POST']) -def login_post(): - # 获取请求的 JSON 数据 - data = request.get_json() - - username = data.get('username') - password = data.get('password') - - pswd = users_list.get_user_pswd(username) - - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/login_teacher_post', methods=['POST']) -def login_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - pswd = users_list.get_user_pswd(username) - is_teacher = users_list.get_user_is_teacher(username) - if is_teacher is None or is_teacher == False: - return jsonify({'success': False, 'message': '用户名不存在或非教师账号'}) - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/teacherboard') -@require_role(roles="teacher") -def teacherboard(): - return render_template('teacherboard.html') - - -@app.route('/logout') -def logout(): - session.pop('user_id', None) - return redirect(url_for('login')) - -@app.route('/get_session') -def get_session(): - user_session = session.get('user_id', 'default_session') - return jsonify({"session": user_session}) - - -''' -DashBoard -''' -user_id2UserClass = {} -@app.route('/dashboard') -@require_role -def dashboard(): - user_id = session['user_id'] - username = uuid2username[user_id] - if (user_id not in user_id2UserClass): - user_id2UserClass[user_id] = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - user_course_data = [] - for course_id in user_id2UserClass[user_id].select_course: - course_brief_info = course_list.get_course_brief_info(course_id, load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR)) - user_course_data.append(course_brief_info) - return render_template('dashboard.html',user_data = user_id2UserClass[user_id].to_json_without_dialog(), user_course_data = json.dumps(user_course_data)) - -''' -Course -''' - -@app.route('/course/') -@require_role -def course(course_id): - c = load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR) - return render_template('course.html', course_id=course_id, course_data=c) - -@app.route('/select_course', methods=['POST']) -@require_role -def select_course(): - user = user_id2UserClass[session['user_id']] - data = request.get_json() - course_id = data.get('course_id') - if course_id: - user.select_new_course(course_id, load_course_from_json(course_id, COURSE_DATA_DIR)) - return jsonify({'success': True, 'message': '课程选择成功'}) - - -@app.route('/') -@require_role -def home_index(): - selected_courses=[] - if ('user_id' in session): - if (session['user_id'] not in user_id2UserClass): return redirect(url_for('login')) - user = user_id2UserClass[session['user_id']] - for course_id in user.select_course: - selected_courses.append(course_id) - - return render_template('index.html', courses_data = course_list, selected_courses =selected_courses) - -# 一些app辅助函数,主要提供给Agent与数据库的交互能力 - -class MyFunction: - def save_chapter_memory(self, id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal): - print("-=-=-=-=-=-=-=-") - print(id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - username = uuid2username[id] - u = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - u.save_chapter_memory(course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - -app.my_function = MyFunction() -if __name__ == '__main__': - socketio.on_namespace(VSCodeNamespace('/vscode')) - socketio.on_namespace(AgentNamespace('/agent')) - socketio.run(app, host='0.0.0.0', port=5551, debug=False,allow_unsafe_werkzeug=True) - diff --git a/Html/runs/run_20250911-055537_tio6to/code/backboardManager.py b/Html/runs/run_20250911-055537_tio6to/code/backboardManager.py deleted file mode 100644 index 7de5f19..0000000 --- a/Html/runs/run_20250911-055537_tio6to/code/backboardManager.py +++ /dev/null @@ -1,80 +0,0 @@ - - - -import time -import os - -class Backboard: - def __init__(self, user_uuid, username, course_id, lesson_id, root_path): - self.user_uuid = user_uuid - self.username = username - self.course_id = course_id - self.lesson_id = lesson_id - self.root_path = root_path - self.create_time = time.time() - self.enter_chapter_time = time.time() - self.history = [] - self.file_tree = "[]" - self.active_file_path = "" - self.active_file_content = "" - self.pasted_file_path = "" - self.pasted_content = "" - - - def next_chapter(self): - self.enter_chapter_time = time.time() - - def get_info_prompt(self): - - five_history = "" - for h in self.history[-5:]: - five_history += h['type'] + "\n" + h.get('filePath', '') + "\n\n" - - endl = "\n" - return (f"###Global Info:###{endl}" - f"Here are some info about now user's IDE, refer to it when you need to handle some code.{endl}" - f"- User's total study time is {self.get_deltatime_mmss(self.create_time, time.time())}{endl}" - f"- User's current chapter study time is {self.get_deltatime_mmss(self.enter_chapter_time, time.time())}{endl}" - f"- Activated file path: {self.active_file_path}{endl}" - f"```{endl}" - f"{self.active_file_content[-10:]}{endl}" - f"```{endl}" - f"- Last five action:{five_history}{endl}" - f"- File tree: {self.file_tree}{endl}") - # f"- Activated file content (current editing 10 lines): {endl}" - def add_history(self, realtime_action): - if(realtime_action['type']=='config'):return - if len(self.history)!=0: - if (self.history[-1]['type']=='fileEdit'): - if(self.history[-1]['filePath'] == realtime_action['filePath']): - self.history[-1]['content'] = realtime_action['content'] - return - self.history.append(realtime_action) - - - def get_deltatime_mmss(self, start_time, end_time): - elapsed_time = end_time - start_time - hours = int(elapsed_time // 3600) - minutes = int((elapsed_time % 3600) // 60) - seconds = int(elapsed_time % 60) - return f"{hours:02d}:{minutes:02d}:{seconds:02d}" - - - def get_active_file_reletive_path(self): - relative_path = os.path.relpath(self.active_file_path, self.root_path) - return relative_path - - - -class BackBoardManager: - def __init__(self): - self.backboards = {} # user_uuid: Backboard - - def add_backboard(self, user_uuid, username, course_id, lesson_id, root_path): - self.backboards[user_uuid] = Backboard(user_uuid,username, course_id, lesson_id, root_path) - - def get_backboard(self, user_uuid) -> Backboard: - return self.backboards[user_uuid] - - - diff --git a/Html/runs/run_20250911-055537_tio6to/code/bootstrap.py b/Html/runs/run_20250911-055537_tio6to/code/bootstrap.py deleted file mode 100644 index bcb15ce..0000000 --- a/Html/runs/run_20250911-055537_tio6to/code/bootstrap.py +++ /dev/null @@ -1,31 +0,0 @@ -from pathlib import Path -import sys, os - -def bootstrap_paths(): - """ - 让 'AlgoriAgent'(位于 repo_root/AlgoriAgent)可被 import; - 并提供 STUDENT_WORKSPACE_ROOT 的默认值(repo_root/study)。 - 适配当前工厂位置:repo_root/Html/apps/__init__.py - """ - here = Path(__file__).resolve() - # repo_root = .../Html/apps/../../ => parents[2] - repo_root = here.parents[2] - - # 兜底:如果目录结构变化,尝试向上搜索包含 AlgoriAgent 的目录作为 repo_root - if not (repo_root / "AlgoriAgent").exists(): - for p in here.parents: - if (p / "AlgoriAgent").is_dir(): - repo_root = p - break - - # 确保仓库根在 sys.path(这样 'AlgoriAgent' 顶层包可被发现) - repo_root_str = str(repo_root) - if repo_root_str not in sys.path: - sys.path.insert(0, repo_root_str) - - # 可选:如果你还有其它顶层包,也可在此处继续插入 - - # 默认学习工作区目录(也可放到 config.ini / 环境变量覆盖) - os.environ.setdefault("STUDENT_WORKSPACE_ROOT", str(repo_root / "study")) - - return repo_root # 方便调试/日志 \ No newline at end of file diff --git a/Html/runs/run_20250911-055537_tio6to/code/wsgi.py b/Html/runs/run_20250911-055537_tio6to/code/wsgi.py deleted file mode 100644 index bbcbe5f..0000000 --- a/Html/runs/run_20250911-055537_tio6to/code/wsgi.py +++ /dev/null @@ -1,6 +0,0 @@ -# wsgi.py -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -# 提供一个可被 WSGI/进程管理器导入的 app 对象 -app = create_app() diff --git a/Html/runs/run_20250911-055537_tio6to/logging.chat b/Html/runs/run_20250911-055537_tio6to/logging.chat deleted file mode 100644 index e69de29..0000000 diff --git a/Html/runs/run_20250911-055537_tio6to/logging.log b/Html/runs/run_20250911-055537_tio6to/logging.log deleted file mode 100644 index e85ec1c..0000000 --- a/Html/runs/run_20250911-055537_tio6to/logging.log +++ /dev/null @@ -1 +0,0 @@ -2025-09-11 05:55:44.651 | INFO | agentscope.models:read_model_configs:186 - Load configs for model wrapper: openai_cfg diff --git a/Html/runs/run_20250911-055544_hp3t1k/.config b/Html/runs/run_20250911-055544_hp3t1k/.config deleted file mode 100644 index 5b4fd40..0000000 --- a/Html/runs/run_20250911-055544_hp3t1k/.config +++ /dev/null @@ -1,7 +0,0 @@ -{ - "project": "taEthw", - "name": "hp3t1k", - "run_id": "run_20250911-055544_hp3t1k", - "timestamp": "2025-09-11 05:55:44", - "pid": 30651 -} \ No newline at end of file diff --git a/Html/runs/run_20250911-055544_hp3t1k/agentscope.db b/Html/runs/run_20250911-055544_hp3t1k/agentscope.db deleted file mode 100644 index 666055b77679cda29c14fcf23b4ef1d039c5b52a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI%L2KJE6bEoS4Q(k)+glI2yjv3-0%NB!Hs&O1YUav`W0U1F<0V=#BsNLx(sSu$ z>=W&q?4#^B$!*yt2YT5l`~^0a^z(#~{ zkyg6w!t)u0!@f%5aeaJcfD9*Q_b$ozCY8>~CFA6|{Z2V!N;Z^cIq}eS$>x3HY|^=j z7lokrf1)Z$x@_R^N~@apn7OPMkZ(I<*1WJCw@v3GWy2n6&RcIQ0~zlR_x8^$%be!% zmxb7@7V;}H+K5#l(wSbZKXKY!mys6ROyi|!%aN@+%REpi?;B-K4PC3&{>iCzQnNB+ zwbW!z4iA{x(V_2L+5VJ1vMJeN;5l68yJ9?OZyl-TNCEp4P{^H8$cTGExdq$9ANE6@ zA@`ZUhb>is+Y=S?%$C1fnN{muZU1a!nMRV%#qFbMT;y3hf|KlJ)00Izz00bZa0SG_<0uX=z1a@EGHy1PL*Z=?k diff --git a/Html/runs/run_20250911-055544_hp3t1k/code/app.py b/Html/runs/run_20250911-055544_hp3t1k/code/app.py deleted file mode 100644 index c7f31f7..0000000 --- a/Html/runs/run_20250911-055544_hp3t1k/code/app.py +++ /dev/null @@ -1,21 +0,0 @@ -# app.py 0.1.1 rise to factory mode -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -from apps.extensions import socketio - -# 工厂创建 app,工厂里已经做了:加载配置/注册蓝图/注册 namespaces -app = create_app() - -if __name__ == "__main__": - # 仅本地开发用;生产不要用 werkzeug 自带的开发服务器 - socketio.run( - app, - host="0.0.0.0", - port=5551, - debug=True, # 开发期打开 - allow_unsafe_werkzeug=True, # 避免 dev server 的安全限制提示 - # ssl_context=('server.crt', 'server.key') - ) - - diff --git a/Html/runs/run_20250911-055544_hp3t1k/code/app_back.py b/Html/runs/run_20250911-055544_hp3t1k/code/app_back.py deleted file mode 100644 index 246853c..0000000 --- a/Html/runs/run_20250911-055544_hp3t1k/code/app_back.py +++ /dev/null @@ -1,480 +0,0 @@ -from bootstrap import bootstrap_paths -bootstrap_paths() -from functools import wraps -from flask import Flask, redirect, session, request, jsonify, render_template, send_from_directory, url_for -from flask_cors import CORS -from flask_socketio import SocketIO, join_room, emit, Namespace -import markdown -import os -import uuid -import shutil -import sys -import json -from apps.auth.decorators import require_role -parent_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) -sys.path.insert(0, parent_dir) -student_workspace_root_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../study')) -current_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '.')) -sys.path.insert(0, current_dir) -from AlgoriAgent.projects.algoriAgent.agent_manager import AgentManager - - -import configparser - -from db.user_list import UserList -from db.user import User, load_user_from_json, create_user_json -from db.course_list import CourseList -from db.course import Course, load_course_from_json -GLOBAL_CONFIG = configparser.ConfigParser() -GLOBAL_CONFIG.read('config.ini') -VSCODE_WEB_URL = GLOBAL_CONFIG['VSCODE_WEB']['url'] -USER_DATA_DIR = GLOBAL_CONFIG['USER_DATA']['dir'] -COURSE_DATA_DIR = GLOBAL_CONFIG['COURSE_DATA']['dir'] - -app = Flask(__name__) -socketio = SocketIO(app, cors_allowed_origins="*",ping_timeout=60, ping_interval=5) -# socketio = SocketIO(app, cors_allowed_origins="http://localhost:9888") # 设置跨域支持 -import logging -app.secret_key = 'cakebaker' -app.logger.setLevel(logging.DEBUG) -# 配置 CORS -CORS(app, resources={r"/*": {"origins": VSCODE_WEB_URL},}, supports_credentials=True) - - -userid_recorder = {} # user_id&path -> session['user_id'] - -''' -Backboard -''' -from backboardManager import BackBoardManager, Backboard - -backboard_manager = BackBoardManager() -uuid2username = {} -username2uuid = {} - - - -# 定义命名空间:用于和 VSCode 插件交流 -class VSCodeNamespace(Namespace): - def on_login(self,data): - print("VSCode client connected") - print(data) - dataconfig = data['config'] - user_id = dataconfig.get('user_id') - path = dataconfig.get('path') - course_id = dataconfig.get('course_id') - lesson_id = dataconfig.get('chapter_id') - print(f"User {user_id} connected with path: {path}") - useruuid = username2uuid[user_id] - join_room(useruuid, namespace='/vscode') - if backboard_manager.get_backboard(useruuid) == None: - backboard_manager.add_backboard(useruuid,user_id, course_id, lesson_id, path) - - - def on_message(self, data): - print(f"Received from VSCode client: {data}") - dataconfig = data['config'] - realtime_response(dataconfig, data) - # emit('response', {'message': 'Config data received and connection established'}) - def on_disconnect(self, data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - -def realtime_response(config, realtime_action): - user_id = config['user_id'] - folder_path = config['path'] - useruuid = username2uuid[user_id] - bb = backboard_manager.get_backboard(useruuid) - assert type(bb) == Backboard - - bb.add_history(realtime_action) - - if realtime_action['type'] == 'workspaceFolders': - bb.file_tree = realtime_action['fileTree'] - - if realtime_action['type'] == 'activeFile': - file_path = realtime_action['filePath'] - assert type(file_path) == str - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - if realtime_action['type'] == 'paste': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.pasted_file_path = file_path - bb.pasted_content = realtime_action['content'] - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - if realtime_action['type'] == 'fileEdit': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - - - print("config"+str(config)) - print("realtime_action"+str(realtime_action)) - pass - - -''' -Agent and Chat -''' -agent_manager = AgentManager(app = app, socketio = socketio) -user_threads = {} -import threading -from concurrent.futures import ThreadPoolExecutor, as_completed - -# 初始化线程池 -executor = ThreadPoolExecutor(max_workers=10) -class AgentNamespace(Namespace): - def on_login(self, data): - data = json.loads(data) - user = data['username'] - course_id = data['course_id'] - chapter_id = data['chapter_id'] - user_uuid = username2uuid[user] - session['user_id'] = user_uuid - print(f'User connected with session user_id: {user_uuid}') - # 从markdown、markdown_prompts、score_prompts中各读取数据folder.md并进行new_agent - with open(f'books/markdown/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fmd,\ - open(f'books/markdown_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8')as fmdp,\ - open(f'books/score_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fsp: - markdown = fmd.read() - markdown_prompts = fmdp.read() - score_prompts = fsp.read() - user_uuid, agent = agent_manager.new_agent(course_id, chapter_id, markdown, markdown_prompts, score_prompts, id=user_uuid, - root_path=f'../../study/{user}/{course_id}/{chapter_id}') - print(user_uuid) - join_room(user_uuid, namespace='/agent') # 将该用户加入以user_id为名的room - backboard_manager.add_backboard(user_uuid, user, course_id, chapter_id, root_path=f'../../study/{user}/{course_id}/{chapter_id}') - - def on_language(self, language): - id = session.get('user_id') - agent_manager.change_language(id, language) - - def on_message(self, data): - print(f"Message from client: {data}") - id = session.get('user_id') - if (type(data)==str): - data = json.loads(data) - print(id) - if data['type'] == 'text': - res = agent_manager.invoke(id, data['data'], backboard_manager.get_backboard(id).get_info_prompt()) - print('=*='*20) - print(res.content) - reply = f"{res.content['speak']}" - with app.app_context(): - emit('message',reply, room=id, namespace='/agent') - emit('request_function',res.content['function'], room=id, namespace='/agent') - - if data['type'] == 'function': - agent_manager.function_call(id, data['data']) - - def on_initiative(self,data): - print("User active function call") - user_id = session['user_id'] - if data['name'] == 'sample_judge': - agent_manager.sample_judge(user_id, backboard_manager.get_backboard(user_id)) - if data['name'] == 'judge': - agent_manager.judge(user_id, backboard_manager.get_backboard(user_id)) - - - - def on_disconnect(self,data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - - -''' -Markdown to HTML -''' -# 配置文件路径 -MARKDOWN_DIR = 'books/markdown' # 存放 markdown 文件的文件夹 -STATIC_DIR = 'static' # 存放生成的 HTML 和图片资源的文件夹 -IMAGE_DIR = 'image' # 图片资源相对于 markdown 的位置 - - - -@app.route('/--markdown', methods=['GET']) -def convert_md(course_id, filename): - md_file_path = os.path.join(MARKDOWN_DIR,course_id, f'{filename}.md') - - if not os.path.exists(md_file_path): - return jsonify({'error': 'Markdown file not found'}), 404 - - # 读取 markdown 文件内容 - with open(md_file_path, 'r', encoding='utf-8') as file: - md_content = file.read() - - # 将 markdown 转换为 HTML - html_content = markdown.markdown(md_content) - # 插入 CSS 样式,限制图片最大宽度为 100%,高度自动调整 - html_with_styles = f""" - - - - - - - {html_content} - - - """ - # 保存 HTML 文件到 static 文件夹 - html_output_path = os.path.join(STATIC_DIR, f'{filename}.html') - with open(html_output_path, 'w', encoding='utf-8') as html_file: - html_file.write(html_with_styles) - - # 处理图片资源,将 image/xxx 文件夹拷贝到 static/image/xxx - image_source_dir = os.path.join(MARKDOWN_DIR,course_id, IMAGE_DIR, filename) - image_target_dir = os.path.join(STATIC_DIR, IMAGE_DIR, filename) - print(f"Copying image resources from {image_source_dir} to {image_target_dir}") - if os.path.exists(image_source_dir): - # 确保 static/image/xxx 目录存在 - if not os.path.exists(image_target_dir): - os.makedirs(image_target_dir) - - # 拷贝图片资源 - for image_file in os.listdir(image_source_dir): - full_image_file_path = os.path.join(image_source_dir, image_file) - if os.path.isfile(full_image_file_path): - shutil.copy(full_image_file_path, image_target_dir) - - return jsonify({'html_url': f'/static/{filename}.html'}) - -# 静态文件(HTML 和图片资源)的访问 -@app.route('/static/') -def serve_static(filename): - return send_from_directory(STATIC_DIR, filename) - - -''' -Vscode -''' -@app.route('/desktop///') -def desktop(user_id, course_id, chapter_id): - if 'user_id' not in session: - # return redirect(url_for('login')) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ user_id + "uuid is"+ session['user_id']) - username2uuid[user_id] = session['user_id'] - uuid2username[session['user_id']] = user_id - userid_recorder[user_id+'&'+course_id] = session['user_id'] - - # 在学习目录下创建一个名为 user_id_path 的文件夹 - path_dir = os.path.join(student_workspace_root_path, user_id, course_id,chapter_id) - os.makedirs(path_dir, exist_ok=True) - # 在此文件夹内部创建一个.config文件,并写入 user_id=user_id\n path=path - config_path = os.path.join(path_dir, '.config') - if GLOBAL_CONFIG['VSCODE_WEB_PATH']['is_wsl']: # 如果是在 WSL 中运行,则将路径转换为 WSL 路径 - path_dir = path_dir.replace('\\', '/') - path_dir = path_dir.replace(GLOBAL_CONFIG['VSCODE_WEB_PATH']['windows_path'] , GLOBAL_CONFIG['VSCODE_WEB_PATH']['wsl_path']) - with open(config_path, 'w', encoding='utf-8') as f: - tmpd = {'user_id': user_id, 'course_id': course_id, 'chapter_id': chapter_id, 'path': path_dir} - json.dump(tmpd, f) - print('---------------------') - print(config_path) - return render_template('desktop.html', vscode_web_url=VSCODE_WEB_URL, user_id=user_id, course_id=course_id, chapter_id=chapter_id, workspace_path=path_dir) - -@app.route('/desktop_nouser//') -def desktop_nouser(course_id, chapter_id): - if 'user_id' not in session: - return redirect(url_for('login')) - user_id = session['user_id'] - username = uuid2username[user_id] - return redirect(url_for('desktop', user_id=username, course_id=course_id, chapter_id=chapter_id)) - -@app.route('/vscode_data', methods=['POST']) -def vscode_data(): - data = request.json - config = data['config'] - realtime_response(config,data) - print(f"Received data from VSCode: {data}") - return jsonify({"status": "success", "received": data}) - - - -''' -Login - -''' -users_list = UserList() -course_list = CourseList() - - -@app.route('/register') -def register(): - return render_template('register.html') - -@app.route('/register_teacher') -def register_teacher(): - return render_template('register_teacher.html') - -@app.route('/register_teacher_post', methods=['POST']) -def register_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password, teacher=True) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - -@app.route('/register_post', methods=['POST']) -def register_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - - -@app.route('/login') -def login(): - return render_template('login.html') - if 'user_id' not in session: - return render_template('login.html') - else: - return redirect(url_for('/')) - -@app.route('/login_post', methods=['POST']) -def login_post(): - # 获取请求的 JSON 数据 - data = request.get_json() - - username = data.get('username') - password = data.get('password') - - pswd = users_list.get_user_pswd(username) - - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/login_teacher_post', methods=['POST']) -def login_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - pswd = users_list.get_user_pswd(username) - is_teacher = users_list.get_user_is_teacher(username) - if is_teacher is None or is_teacher == False: - return jsonify({'success': False, 'message': '用户名不存在或非教师账号'}) - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/teacherboard') -@require_role(roles="teacher") -def teacherboard(): - return render_template('teacherboard.html') - - -@app.route('/logout') -def logout(): - session.pop('user_id', None) - return redirect(url_for('login')) - -@app.route('/get_session') -def get_session(): - user_session = session.get('user_id', 'default_session') - return jsonify({"session": user_session}) - - -''' -DashBoard -''' -user_id2UserClass = {} -@app.route('/dashboard') -@require_role -def dashboard(): - user_id = session['user_id'] - username = uuid2username[user_id] - if (user_id not in user_id2UserClass): - user_id2UserClass[user_id] = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - user_course_data = [] - for course_id in user_id2UserClass[user_id].select_course: - course_brief_info = course_list.get_course_brief_info(course_id, load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR)) - user_course_data.append(course_brief_info) - return render_template('dashboard.html',user_data = user_id2UserClass[user_id].to_json_without_dialog(), user_course_data = json.dumps(user_course_data)) - -''' -Course -''' - -@app.route('/course/') -@require_role -def course(course_id): - c = load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR) - return render_template('course.html', course_id=course_id, course_data=c) - -@app.route('/select_course', methods=['POST']) -@require_role -def select_course(): - user = user_id2UserClass[session['user_id']] - data = request.get_json() - course_id = data.get('course_id') - if course_id: - user.select_new_course(course_id, load_course_from_json(course_id, COURSE_DATA_DIR)) - return jsonify({'success': True, 'message': '课程选择成功'}) - - -@app.route('/') -@require_role -def home_index(): - selected_courses=[] - if ('user_id' in session): - if (session['user_id'] not in user_id2UserClass): return redirect(url_for('login')) - user = user_id2UserClass[session['user_id']] - for course_id in user.select_course: - selected_courses.append(course_id) - - return render_template('index.html', courses_data = course_list, selected_courses =selected_courses) - -# 一些app辅助函数,主要提供给Agent与数据库的交互能力 - -class MyFunction: - def save_chapter_memory(self, id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal): - print("-=-=-=-=-=-=-=-") - print(id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - username = uuid2username[id] - u = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - u.save_chapter_memory(course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - -app.my_function = MyFunction() -if __name__ == '__main__': - socketio.on_namespace(VSCodeNamespace('/vscode')) - socketio.on_namespace(AgentNamespace('/agent')) - socketio.run(app, host='0.0.0.0', port=5551, debug=False,allow_unsafe_werkzeug=True) - diff --git a/Html/runs/run_20250911-055544_hp3t1k/code/backboardManager.py b/Html/runs/run_20250911-055544_hp3t1k/code/backboardManager.py deleted file mode 100644 index 7de5f19..0000000 --- a/Html/runs/run_20250911-055544_hp3t1k/code/backboardManager.py +++ /dev/null @@ -1,80 +0,0 @@ - - - -import time -import os - -class Backboard: - def __init__(self, user_uuid, username, course_id, lesson_id, root_path): - self.user_uuid = user_uuid - self.username = username - self.course_id = course_id - self.lesson_id = lesson_id - self.root_path = root_path - self.create_time = time.time() - self.enter_chapter_time = time.time() - self.history = [] - self.file_tree = "[]" - self.active_file_path = "" - self.active_file_content = "" - self.pasted_file_path = "" - self.pasted_content = "" - - - def next_chapter(self): - self.enter_chapter_time = time.time() - - def get_info_prompt(self): - - five_history = "" - for h in self.history[-5:]: - five_history += h['type'] + "\n" + h.get('filePath', '') + "\n\n" - - endl = "\n" - return (f"###Global Info:###{endl}" - f"Here are some info about now user's IDE, refer to it when you need to handle some code.{endl}" - f"- User's total study time is {self.get_deltatime_mmss(self.create_time, time.time())}{endl}" - f"- User's current chapter study time is {self.get_deltatime_mmss(self.enter_chapter_time, time.time())}{endl}" - f"- Activated file path: {self.active_file_path}{endl}" - f"```{endl}" - f"{self.active_file_content[-10:]}{endl}" - f"```{endl}" - f"- Last five action:{five_history}{endl}" - f"- File tree: {self.file_tree}{endl}") - # f"- Activated file content (current editing 10 lines): {endl}" - def add_history(self, realtime_action): - if(realtime_action['type']=='config'):return - if len(self.history)!=0: - if (self.history[-1]['type']=='fileEdit'): - if(self.history[-1]['filePath'] == realtime_action['filePath']): - self.history[-1]['content'] = realtime_action['content'] - return - self.history.append(realtime_action) - - - def get_deltatime_mmss(self, start_time, end_time): - elapsed_time = end_time - start_time - hours = int(elapsed_time // 3600) - minutes = int((elapsed_time % 3600) // 60) - seconds = int(elapsed_time % 60) - return f"{hours:02d}:{minutes:02d}:{seconds:02d}" - - - def get_active_file_reletive_path(self): - relative_path = os.path.relpath(self.active_file_path, self.root_path) - return relative_path - - - -class BackBoardManager: - def __init__(self): - self.backboards = {} # user_uuid: Backboard - - def add_backboard(self, user_uuid, username, course_id, lesson_id, root_path): - self.backboards[user_uuid] = Backboard(user_uuid,username, course_id, lesson_id, root_path) - - def get_backboard(self, user_uuid) -> Backboard: - return self.backboards[user_uuid] - - - diff --git a/Html/runs/run_20250911-055544_hp3t1k/code/bootstrap.py b/Html/runs/run_20250911-055544_hp3t1k/code/bootstrap.py deleted file mode 100644 index bcb15ce..0000000 --- a/Html/runs/run_20250911-055544_hp3t1k/code/bootstrap.py +++ /dev/null @@ -1,31 +0,0 @@ -from pathlib import Path -import sys, os - -def bootstrap_paths(): - """ - 让 'AlgoriAgent'(位于 repo_root/AlgoriAgent)可被 import; - 并提供 STUDENT_WORKSPACE_ROOT 的默认值(repo_root/study)。 - 适配当前工厂位置:repo_root/Html/apps/__init__.py - """ - here = Path(__file__).resolve() - # repo_root = .../Html/apps/../../ => parents[2] - repo_root = here.parents[2] - - # 兜底:如果目录结构变化,尝试向上搜索包含 AlgoriAgent 的目录作为 repo_root - if not (repo_root / "AlgoriAgent").exists(): - for p in here.parents: - if (p / "AlgoriAgent").is_dir(): - repo_root = p - break - - # 确保仓库根在 sys.path(这样 'AlgoriAgent' 顶层包可被发现) - repo_root_str = str(repo_root) - if repo_root_str not in sys.path: - sys.path.insert(0, repo_root_str) - - # 可选:如果你还有其它顶层包,也可在此处继续插入 - - # 默认学习工作区目录(也可放到 config.ini / 环境变量覆盖) - os.environ.setdefault("STUDENT_WORKSPACE_ROOT", str(repo_root / "study")) - - return repo_root # 方便调试/日志 \ No newline at end of file diff --git a/Html/runs/run_20250911-055544_hp3t1k/code/wsgi.py b/Html/runs/run_20250911-055544_hp3t1k/code/wsgi.py deleted file mode 100644 index bbcbe5f..0000000 --- a/Html/runs/run_20250911-055544_hp3t1k/code/wsgi.py +++ /dev/null @@ -1,6 +0,0 @@ -# wsgi.py -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -# 提供一个可被 WSGI/进程管理器导入的 app 对象 -app = create_app() diff --git a/Html/runs/run_20250911-055544_hp3t1k/logging.chat b/Html/runs/run_20250911-055544_hp3t1k/logging.chat deleted file mode 100644 index e69de29..0000000 diff --git a/Html/runs/run_20250911-055544_hp3t1k/logging.log b/Html/runs/run_20250911-055544_hp3t1k/logging.log deleted file mode 100644 index 44f0ede..0000000 --- a/Html/runs/run_20250911-055544_hp3t1k/logging.log +++ /dev/null @@ -1 +0,0 @@ -2025-09-11 05:55:48.549 | INFO | agentscope.models:read_model_configs:186 - Load configs for model wrapper: openai_cfg diff --git a/Html/runs/run_20250911-055810_isow4t/.config b/Html/runs/run_20250911-055810_isow4t/.config deleted file mode 100644 index fec7e6f..0000000 --- a/Html/runs/run_20250911-055810_isow4t/.config +++ /dev/null @@ -1,7 +0,0 @@ -{ - "project": "BCPMUW", - "name": "isow4t", - "run_id": "run_20250911-055810_isow4t", - "timestamp": "2025-09-11 05:58:10", - "pid": 30813 -} \ No newline at end of file diff --git a/Html/runs/run_20250911-055810_isow4t/agentscope.db b/Html/runs/run_20250911-055810_isow4t/agentscope.db deleted file mode 100644 index 666055b77679cda29c14fcf23b4ef1d039c5b52a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI%L2KJE6bEoS4Q(k)+glI2yjv3-0%NB!Hs&O1YUav`W0U1F<0V=#BsNLx(sSu$ z>=W&q?4#^B$!*yt2YT5l`~^0a^z(#~{ zkyg6w!t)u0!@f%5aeaJcfD9*Q_b$ozCY8>~CFA6|{Z2V!N;Z^cIq}eS$>x3HY|^=j z7lokrf1)Z$x@_R^N~@apn7OPMkZ(I<*1WJCw@v3GWy2n6&RcIQ0~zlR_x8^$%be!% zmxb7@7V;}H+K5#l(wSbZKXKY!mys6ROyi|!%aN@+%REpi?;B-K4PC3&{>iCzQnNB+ zwbW!z4iA{x(V_2L+5VJ1vMJeN;5l68yJ9?OZyl-TNCEp4P{^H8$cTGExdq$9ANE6@ zA@`ZUhb>is+Y=S?%$C1fnN{muZU1a!nMRV%#qFbMT;y3hf|KlJ)00Izz00bZa0SG_<0uX=z1a@EGHy1PL*Z=?k diff --git a/Html/runs/run_20250911-055810_isow4t/code/app.py b/Html/runs/run_20250911-055810_isow4t/code/app.py deleted file mode 100644 index c7f31f7..0000000 --- a/Html/runs/run_20250911-055810_isow4t/code/app.py +++ /dev/null @@ -1,21 +0,0 @@ -# app.py 0.1.1 rise to factory mode -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -from apps.extensions import socketio - -# 工厂创建 app,工厂里已经做了:加载配置/注册蓝图/注册 namespaces -app = create_app() - -if __name__ == "__main__": - # 仅本地开发用;生产不要用 werkzeug 自带的开发服务器 - socketio.run( - app, - host="0.0.0.0", - port=5551, - debug=True, # 开发期打开 - allow_unsafe_werkzeug=True, # 避免 dev server 的安全限制提示 - # ssl_context=('server.crt', 'server.key') - ) - - diff --git a/Html/runs/run_20250911-055810_isow4t/code/app_back.py b/Html/runs/run_20250911-055810_isow4t/code/app_back.py deleted file mode 100644 index 246853c..0000000 --- a/Html/runs/run_20250911-055810_isow4t/code/app_back.py +++ /dev/null @@ -1,480 +0,0 @@ -from bootstrap import bootstrap_paths -bootstrap_paths() -from functools import wraps -from flask import Flask, redirect, session, request, jsonify, render_template, send_from_directory, url_for -from flask_cors import CORS -from flask_socketio import SocketIO, join_room, emit, Namespace -import markdown -import os -import uuid -import shutil -import sys -import json -from apps.auth.decorators import require_role -parent_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) -sys.path.insert(0, parent_dir) -student_workspace_root_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../study')) -current_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '.')) -sys.path.insert(0, current_dir) -from AlgoriAgent.projects.algoriAgent.agent_manager import AgentManager - - -import configparser - -from db.user_list import UserList -from db.user import User, load_user_from_json, create_user_json -from db.course_list import CourseList -from db.course import Course, load_course_from_json -GLOBAL_CONFIG = configparser.ConfigParser() -GLOBAL_CONFIG.read('config.ini') -VSCODE_WEB_URL = GLOBAL_CONFIG['VSCODE_WEB']['url'] -USER_DATA_DIR = GLOBAL_CONFIG['USER_DATA']['dir'] -COURSE_DATA_DIR = GLOBAL_CONFIG['COURSE_DATA']['dir'] - -app = Flask(__name__) -socketio = SocketIO(app, cors_allowed_origins="*",ping_timeout=60, ping_interval=5) -# socketio = SocketIO(app, cors_allowed_origins="http://localhost:9888") # 设置跨域支持 -import logging -app.secret_key = 'cakebaker' -app.logger.setLevel(logging.DEBUG) -# 配置 CORS -CORS(app, resources={r"/*": {"origins": VSCODE_WEB_URL},}, supports_credentials=True) - - -userid_recorder = {} # user_id&path -> session['user_id'] - -''' -Backboard -''' -from backboardManager import BackBoardManager, Backboard - -backboard_manager = BackBoardManager() -uuid2username = {} -username2uuid = {} - - - -# 定义命名空间:用于和 VSCode 插件交流 -class VSCodeNamespace(Namespace): - def on_login(self,data): - print("VSCode client connected") - print(data) - dataconfig = data['config'] - user_id = dataconfig.get('user_id') - path = dataconfig.get('path') - course_id = dataconfig.get('course_id') - lesson_id = dataconfig.get('chapter_id') - print(f"User {user_id} connected with path: {path}") - useruuid = username2uuid[user_id] - join_room(useruuid, namespace='/vscode') - if backboard_manager.get_backboard(useruuid) == None: - backboard_manager.add_backboard(useruuid,user_id, course_id, lesson_id, path) - - - def on_message(self, data): - print(f"Received from VSCode client: {data}") - dataconfig = data['config'] - realtime_response(dataconfig, data) - # emit('response', {'message': 'Config data received and connection established'}) - def on_disconnect(self, data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - -def realtime_response(config, realtime_action): - user_id = config['user_id'] - folder_path = config['path'] - useruuid = username2uuid[user_id] - bb = backboard_manager.get_backboard(useruuid) - assert type(bb) == Backboard - - bb.add_history(realtime_action) - - if realtime_action['type'] == 'workspaceFolders': - bb.file_tree = realtime_action['fileTree'] - - if realtime_action['type'] == 'activeFile': - file_path = realtime_action['filePath'] - assert type(file_path) == str - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - if realtime_action['type'] == 'paste': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.pasted_file_path = file_path - bb.pasted_content = realtime_action['content'] - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - if realtime_action['type'] == 'fileEdit': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - - - print("config"+str(config)) - print("realtime_action"+str(realtime_action)) - pass - - -''' -Agent and Chat -''' -agent_manager = AgentManager(app = app, socketio = socketio) -user_threads = {} -import threading -from concurrent.futures import ThreadPoolExecutor, as_completed - -# 初始化线程池 -executor = ThreadPoolExecutor(max_workers=10) -class AgentNamespace(Namespace): - def on_login(self, data): - data = json.loads(data) - user = data['username'] - course_id = data['course_id'] - chapter_id = data['chapter_id'] - user_uuid = username2uuid[user] - session['user_id'] = user_uuid - print(f'User connected with session user_id: {user_uuid}') - # 从markdown、markdown_prompts、score_prompts中各读取数据folder.md并进行new_agent - with open(f'books/markdown/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fmd,\ - open(f'books/markdown_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8')as fmdp,\ - open(f'books/score_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fsp: - markdown = fmd.read() - markdown_prompts = fmdp.read() - score_prompts = fsp.read() - user_uuid, agent = agent_manager.new_agent(course_id, chapter_id, markdown, markdown_prompts, score_prompts, id=user_uuid, - root_path=f'../../study/{user}/{course_id}/{chapter_id}') - print(user_uuid) - join_room(user_uuid, namespace='/agent') # 将该用户加入以user_id为名的room - backboard_manager.add_backboard(user_uuid, user, course_id, chapter_id, root_path=f'../../study/{user}/{course_id}/{chapter_id}') - - def on_language(self, language): - id = session.get('user_id') - agent_manager.change_language(id, language) - - def on_message(self, data): - print(f"Message from client: {data}") - id = session.get('user_id') - if (type(data)==str): - data = json.loads(data) - print(id) - if data['type'] == 'text': - res = agent_manager.invoke(id, data['data'], backboard_manager.get_backboard(id).get_info_prompt()) - print('=*='*20) - print(res.content) - reply = f"{res.content['speak']}" - with app.app_context(): - emit('message',reply, room=id, namespace='/agent') - emit('request_function',res.content['function'], room=id, namespace='/agent') - - if data['type'] == 'function': - agent_manager.function_call(id, data['data']) - - def on_initiative(self,data): - print("User active function call") - user_id = session['user_id'] - if data['name'] == 'sample_judge': - agent_manager.sample_judge(user_id, backboard_manager.get_backboard(user_id)) - if data['name'] == 'judge': - agent_manager.judge(user_id, backboard_manager.get_backboard(user_id)) - - - - def on_disconnect(self,data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - - -''' -Markdown to HTML -''' -# 配置文件路径 -MARKDOWN_DIR = 'books/markdown' # 存放 markdown 文件的文件夹 -STATIC_DIR = 'static' # 存放生成的 HTML 和图片资源的文件夹 -IMAGE_DIR = 'image' # 图片资源相对于 markdown 的位置 - - - -@app.route('/--markdown', methods=['GET']) -def convert_md(course_id, filename): - md_file_path = os.path.join(MARKDOWN_DIR,course_id, f'{filename}.md') - - if not os.path.exists(md_file_path): - return jsonify({'error': 'Markdown file not found'}), 404 - - # 读取 markdown 文件内容 - with open(md_file_path, 'r', encoding='utf-8') as file: - md_content = file.read() - - # 将 markdown 转换为 HTML - html_content = markdown.markdown(md_content) - # 插入 CSS 样式,限制图片最大宽度为 100%,高度自动调整 - html_with_styles = f""" - - - - - - - {html_content} - - - """ - # 保存 HTML 文件到 static 文件夹 - html_output_path = os.path.join(STATIC_DIR, f'{filename}.html') - with open(html_output_path, 'w', encoding='utf-8') as html_file: - html_file.write(html_with_styles) - - # 处理图片资源,将 image/xxx 文件夹拷贝到 static/image/xxx - image_source_dir = os.path.join(MARKDOWN_DIR,course_id, IMAGE_DIR, filename) - image_target_dir = os.path.join(STATIC_DIR, IMAGE_DIR, filename) - print(f"Copying image resources from {image_source_dir} to {image_target_dir}") - if os.path.exists(image_source_dir): - # 确保 static/image/xxx 目录存在 - if not os.path.exists(image_target_dir): - os.makedirs(image_target_dir) - - # 拷贝图片资源 - for image_file in os.listdir(image_source_dir): - full_image_file_path = os.path.join(image_source_dir, image_file) - if os.path.isfile(full_image_file_path): - shutil.copy(full_image_file_path, image_target_dir) - - return jsonify({'html_url': f'/static/{filename}.html'}) - -# 静态文件(HTML 和图片资源)的访问 -@app.route('/static/') -def serve_static(filename): - return send_from_directory(STATIC_DIR, filename) - - -''' -Vscode -''' -@app.route('/desktop///') -def desktop(user_id, course_id, chapter_id): - if 'user_id' not in session: - # return redirect(url_for('login')) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ user_id + "uuid is"+ session['user_id']) - username2uuid[user_id] = session['user_id'] - uuid2username[session['user_id']] = user_id - userid_recorder[user_id+'&'+course_id] = session['user_id'] - - # 在学习目录下创建一个名为 user_id_path 的文件夹 - path_dir = os.path.join(student_workspace_root_path, user_id, course_id,chapter_id) - os.makedirs(path_dir, exist_ok=True) - # 在此文件夹内部创建一个.config文件,并写入 user_id=user_id\n path=path - config_path = os.path.join(path_dir, '.config') - if GLOBAL_CONFIG['VSCODE_WEB_PATH']['is_wsl']: # 如果是在 WSL 中运行,则将路径转换为 WSL 路径 - path_dir = path_dir.replace('\\', '/') - path_dir = path_dir.replace(GLOBAL_CONFIG['VSCODE_WEB_PATH']['windows_path'] , GLOBAL_CONFIG['VSCODE_WEB_PATH']['wsl_path']) - with open(config_path, 'w', encoding='utf-8') as f: - tmpd = {'user_id': user_id, 'course_id': course_id, 'chapter_id': chapter_id, 'path': path_dir} - json.dump(tmpd, f) - print('---------------------') - print(config_path) - return render_template('desktop.html', vscode_web_url=VSCODE_WEB_URL, user_id=user_id, course_id=course_id, chapter_id=chapter_id, workspace_path=path_dir) - -@app.route('/desktop_nouser//') -def desktop_nouser(course_id, chapter_id): - if 'user_id' not in session: - return redirect(url_for('login')) - user_id = session['user_id'] - username = uuid2username[user_id] - return redirect(url_for('desktop', user_id=username, course_id=course_id, chapter_id=chapter_id)) - -@app.route('/vscode_data', methods=['POST']) -def vscode_data(): - data = request.json - config = data['config'] - realtime_response(config,data) - print(f"Received data from VSCode: {data}") - return jsonify({"status": "success", "received": data}) - - - -''' -Login - -''' -users_list = UserList() -course_list = CourseList() - - -@app.route('/register') -def register(): - return render_template('register.html') - -@app.route('/register_teacher') -def register_teacher(): - return render_template('register_teacher.html') - -@app.route('/register_teacher_post', methods=['POST']) -def register_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password, teacher=True) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - -@app.route('/register_post', methods=['POST']) -def register_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - - -@app.route('/login') -def login(): - return render_template('login.html') - if 'user_id' not in session: - return render_template('login.html') - else: - return redirect(url_for('/')) - -@app.route('/login_post', methods=['POST']) -def login_post(): - # 获取请求的 JSON 数据 - data = request.get_json() - - username = data.get('username') - password = data.get('password') - - pswd = users_list.get_user_pswd(username) - - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/login_teacher_post', methods=['POST']) -def login_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - pswd = users_list.get_user_pswd(username) - is_teacher = users_list.get_user_is_teacher(username) - if is_teacher is None or is_teacher == False: - return jsonify({'success': False, 'message': '用户名不存在或非教师账号'}) - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/teacherboard') -@require_role(roles="teacher") -def teacherboard(): - return render_template('teacherboard.html') - - -@app.route('/logout') -def logout(): - session.pop('user_id', None) - return redirect(url_for('login')) - -@app.route('/get_session') -def get_session(): - user_session = session.get('user_id', 'default_session') - return jsonify({"session": user_session}) - - -''' -DashBoard -''' -user_id2UserClass = {} -@app.route('/dashboard') -@require_role -def dashboard(): - user_id = session['user_id'] - username = uuid2username[user_id] - if (user_id not in user_id2UserClass): - user_id2UserClass[user_id] = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - user_course_data = [] - for course_id in user_id2UserClass[user_id].select_course: - course_brief_info = course_list.get_course_brief_info(course_id, load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR)) - user_course_data.append(course_brief_info) - return render_template('dashboard.html',user_data = user_id2UserClass[user_id].to_json_without_dialog(), user_course_data = json.dumps(user_course_data)) - -''' -Course -''' - -@app.route('/course/') -@require_role -def course(course_id): - c = load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR) - return render_template('course.html', course_id=course_id, course_data=c) - -@app.route('/select_course', methods=['POST']) -@require_role -def select_course(): - user = user_id2UserClass[session['user_id']] - data = request.get_json() - course_id = data.get('course_id') - if course_id: - user.select_new_course(course_id, load_course_from_json(course_id, COURSE_DATA_DIR)) - return jsonify({'success': True, 'message': '课程选择成功'}) - - -@app.route('/') -@require_role -def home_index(): - selected_courses=[] - if ('user_id' in session): - if (session['user_id'] not in user_id2UserClass): return redirect(url_for('login')) - user = user_id2UserClass[session['user_id']] - for course_id in user.select_course: - selected_courses.append(course_id) - - return render_template('index.html', courses_data = course_list, selected_courses =selected_courses) - -# 一些app辅助函数,主要提供给Agent与数据库的交互能力 - -class MyFunction: - def save_chapter_memory(self, id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal): - print("-=-=-=-=-=-=-=-") - print(id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - username = uuid2username[id] - u = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - u.save_chapter_memory(course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - -app.my_function = MyFunction() -if __name__ == '__main__': - socketio.on_namespace(VSCodeNamespace('/vscode')) - socketio.on_namespace(AgentNamespace('/agent')) - socketio.run(app, host='0.0.0.0', port=5551, debug=False,allow_unsafe_werkzeug=True) - diff --git a/Html/runs/run_20250911-055810_isow4t/code/backboardManager.py b/Html/runs/run_20250911-055810_isow4t/code/backboardManager.py deleted file mode 100644 index 7de5f19..0000000 --- a/Html/runs/run_20250911-055810_isow4t/code/backboardManager.py +++ /dev/null @@ -1,80 +0,0 @@ - - - -import time -import os - -class Backboard: - def __init__(self, user_uuid, username, course_id, lesson_id, root_path): - self.user_uuid = user_uuid - self.username = username - self.course_id = course_id - self.lesson_id = lesson_id - self.root_path = root_path - self.create_time = time.time() - self.enter_chapter_time = time.time() - self.history = [] - self.file_tree = "[]" - self.active_file_path = "" - self.active_file_content = "" - self.pasted_file_path = "" - self.pasted_content = "" - - - def next_chapter(self): - self.enter_chapter_time = time.time() - - def get_info_prompt(self): - - five_history = "" - for h in self.history[-5:]: - five_history += h['type'] + "\n" + h.get('filePath', '') + "\n\n" - - endl = "\n" - return (f"###Global Info:###{endl}" - f"Here are some info about now user's IDE, refer to it when you need to handle some code.{endl}" - f"- User's total study time is {self.get_deltatime_mmss(self.create_time, time.time())}{endl}" - f"- User's current chapter study time is {self.get_deltatime_mmss(self.enter_chapter_time, time.time())}{endl}" - f"- Activated file path: {self.active_file_path}{endl}" - f"```{endl}" - f"{self.active_file_content[-10:]}{endl}" - f"```{endl}" - f"- Last five action:{five_history}{endl}" - f"- File tree: {self.file_tree}{endl}") - # f"- Activated file content (current editing 10 lines): {endl}" - def add_history(self, realtime_action): - if(realtime_action['type']=='config'):return - if len(self.history)!=0: - if (self.history[-1]['type']=='fileEdit'): - if(self.history[-1]['filePath'] == realtime_action['filePath']): - self.history[-1]['content'] = realtime_action['content'] - return - self.history.append(realtime_action) - - - def get_deltatime_mmss(self, start_time, end_time): - elapsed_time = end_time - start_time - hours = int(elapsed_time // 3600) - minutes = int((elapsed_time % 3600) // 60) - seconds = int(elapsed_time % 60) - return f"{hours:02d}:{minutes:02d}:{seconds:02d}" - - - def get_active_file_reletive_path(self): - relative_path = os.path.relpath(self.active_file_path, self.root_path) - return relative_path - - - -class BackBoardManager: - def __init__(self): - self.backboards = {} # user_uuid: Backboard - - def add_backboard(self, user_uuid, username, course_id, lesson_id, root_path): - self.backboards[user_uuid] = Backboard(user_uuid,username, course_id, lesson_id, root_path) - - def get_backboard(self, user_uuid) -> Backboard: - return self.backboards[user_uuid] - - - diff --git a/Html/runs/run_20250911-055810_isow4t/code/bootstrap.py b/Html/runs/run_20250911-055810_isow4t/code/bootstrap.py deleted file mode 100644 index bcb15ce..0000000 --- a/Html/runs/run_20250911-055810_isow4t/code/bootstrap.py +++ /dev/null @@ -1,31 +0,0 @@ -from pathlib import Path -import sys, os - -def bootstrap_paths(): - """ - 让 'AlgoriAgent'(位于 repo_root/AlgoriAgent)可被 import; - 并提供 STUDENT_WORKSPACE_ROOT 的默认值(repo_root/study)。 - 适配当前工厂位置:repo_root/Html/apps/__init__.py - """ - here = Path(__file__).resolve() - # repo_root = .../Html/apps/../../ => parents[2] - repo_root = here.parents[2] - - # 兜底:如果目录结构变化,尝试向上搜索包含 AlgoriAgent 的目录作为 repo_root - if not (repo_root / "AlgoriAgent").exists(): - for p in here.parents: - if (p / "AlgoriAgent").is_dir(): - repo_root = p - break - - # 确保仓库根在 sys.path(这样 'AlgoriAgent' 顶层包可被发现) - repo_root_str = str(repo_root) - if repo_root_str not in sys.path: - sys.path.insert(0, repo_root_str) - - # 可选:如果你还有其它顶层包,也可在此处继续插入 - - # 默认学习工作区目录(也可放到 config.ini / 环境变量覆盖) - os.environ.setdefault("STUDENT_WORKSPACE_ROOT", str(repo_root / "study")) - - return repo_root # 方便调试/日志 \ No newline at end of file diff --git a/Html/runs/run_20250911-055810_isow4t/code/wsgi.py b/Html/runs/run_20250911-055810_isow4t/code/wsgi.py deleted file mode 100644 index bbcbe5f..0000000 --- a/Html/runs/run_20250911-055810_isow4t/code/wsgi.py +++ /dev/null @@ -1,6 +0,0 @@ -# wsgi.py -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -# 提供一个可被 WSGI/进程管理器导入的 app 对象 -app = create_app() diff --git a/Html/runs/run_20250911-055810_isow4t/logging.chat b/Html/runs/run_20250911-055810_isow4t/logging.chat deleted file mode 100644 index e69de29..0000000 diff --git a/Html/runs/run_20250911-055810_isow4t/logging.log b/Html/runs/run_20250911-055810_isow4t/logging.log deleted file mode 100644 index c2ef8a2..0000000 --- a/Html/runs/run_20250911-055810_isow4t/logging.log +++ /dev/null @@ -1 +0,0 @@ -2025-09-11 05:58:14.117 | INFO | agentscope.models:read_model_configs:186 - Load configs for model wrapper: openai_cfg diff --git a/Html/runs/run_20250911-055837_qf7qys/.config b/Html/runs/run_20250911-055837_qf7qys/.config deleted file mode 100644 index 3644877..0000000 --- a/Html/runs/run_20250911-055837_qf7qys/.config +++ /dev/null @@ -1,7 +0,0 @@ -{ - "project": "eLopit", - "name": "qf7qys", - "run_id": "run_20250911-055837_qf7qys", - "timestamp": "2025-09-11 05:58:37", - "pid": 30922 -} \ No newline at end of file diff --git a/Html/runs/run_20250911-055837_qf7qys/agentscope.db b/Html/runs/run_20250911-055837_qf7qys/agentscope.db deleted file mode 100644 index 666055b77679cda29c14fcf23b4ef1d039c5b52a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI%L2KJE6bEoS4Q(k)+glI2yjv3-0%NB!Hs&O1YUav`W0U1F<0V=#BsNLx(sSu$ z>=W&q?4#^B$!*yt2YT5l`~^0a^z(#~{ zkyg6w!t)u0!@f%5aeaJcfD9*Q_b$ozCY8>~CFA6|{Z2V!N;Z^cIq}eS$>x3HY|^=j z7lokrf1)Z$x@_R^N~@apn7OPMkZ(I<*1WJCw@v3GWy2n6&RcIQ0~zlR_x8^$%be!% zmxb7@7V;}H+K5#l(wSbZKXKY!mys6ROyi|!%aN@+%REpi?;B-K4PC3&{>iCzQnNB+ zwbW!z4iA{x(V_2L+5VJ1vMJeN;5l68yJ9?OZyl-TNCEp4P{^H8$cTGExdq$9ANE6@ zA@`ZUhb>is+Y=S?%$C1fnN{muZU1a!nMRV%#qFbMT;y3hf|KlJ)00Izz00bZa0SG_<0uX=z1a@EGHy1PL*Z=?k diff --git a/Html/runs/run_20250911-055837_qf7qys/code/app.py b/Html/runs/run_20250911-055837_qf7qys/code/app.py deleted file mode 100644 index c7f31f7..0000000 --- a/Html/runs/run_20250911-055837_qf7qys/code/app.py +++ /dev/null @@ -1,21 +0,0 @@ -# app.py 0.1.1 rise to factory mode -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -from apps.extensions import socketio - -# 工厂创建 app,工厂里已经做了:加载配置/注册蓝图/注册 namespaces -app = create_app() - -if __name__ == "__main__": - # 仅本地开发用;生产不要用 werkzeug 自带的开发服务器 - socketio.run( - app, - host="0.0.0.0", - port=5551, - debug=True, # 开发期打开 - allow_unsafe_werkzeug=True, # 避免 dev server 的安全限制提示 - # ssl_context=('server.crt', 'server.key') - ) - - diff --git a/Html/runs/run_20250911-055837_qf7qys/code/app_back.py b/Html/runs/run_20250911-055837_qf7qys/code/app_back.py deleted file mode 100644 index 246853c..0000000 --- a/Html/runs/run_20250911-055837_qf7qys/code/app_back.py +++ /dev/null @@ -1,480 +0,0 @@ -from bootstrap import bootstrap_paths -bootstrap_paths() -from functools import wraps -from flask import Flask, redirect, session, request, jsonify, render_template, send_from_directory, url_for -from flask_cors import CORS -from flask_socketio import SocketIO, join_room, emit, Namespace -import markdown -import os -import uuid -import shutil -import sys -import json -from apps.auth.decorators import require_role -parent_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) -sys.path.insert(0, parent_dir) -student_workspace_root_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../study')) -current_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '.')) -sys.path.insert(0, current_dir) -from AlgoriAgent.projects.algoriAgent.agent_manager import AgentManager - - -import configparser - -from db.user_list import UserList -from db.user import User, load_user_from_json, create_user_json -from db.course_list import CourseList -from db.course import Course, load_course_from_json -GLOBAL_CONFIG = configparser.ConfigParser() -GLOBAL_CONFIG.read('config.ini') -VSCODE_WEB_URL = GLOBAL_CONFIG['VSCODE_WEB']['url'] -USER_DATA_DIR = GLOBAL_CONFIG['USER_DATA']['dir'] -COURSE_DATA_DIR = GLOBAL_CONFIG['COURSE_DATA']['dir'] - -app = Flask(__name__) -socketio = SocketIO(app, cors_allowed_origins="*",ping_timeout=60, ping_interval=5) -# socketio = SocketIO(app, cors_allowed_origins="http://localhost:9888") # 设置跨域支持 -import logging -app.secret_key = 'cakebaker' -app.logger.setLevel(logging.DEBUG) -# 配置 CORS -CORS(app, resources={r"/*": {"origins": VSCODE_WEB_URL},}, supports_credentials=True) - - -userid_recorder = {} # user_id&path -> session['user_id'] - -''' -Backboard -''' -from backboardManager import BackBoardManager, Backboard - -backboard_manager = BackBoardManager() -uuid2username = {} -username2uuid = {} - - - -# 定义命名空间:用于和 VSCode 插件交流 -class VSCodeNamespace(Namespace): - def on_login(self,data): - print("VSCode client connected") - print(data) - dataconfig = data['config'] - user_id = dataconfig.get('user_id') - path = dataconfig.get('path') - course_id = dataconfig.get('course_id') - lesson_id = dataconfig.get('chapter_id') - print(f"User {user_id} connected with path: {path}") - useruuid = username2uuid[user_id] - join_room(useruuid, namespace='/vscode') - if backboard_manager.get_backboard(useruuid) == None: - backboard_manager.add_backboard(useruuid,user_id, course_id, lesson_id, path) - - - def on_message(self, data): - print(f"Received from VSCode client: {data}") - dataconfig = data['config'] - realtime_response(dataconfig, data) - # emit('response', {'message': 'Config data received and connection established'}) - def on_disconnect(self, data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - -def realtime_response(config, realtime_action): - user_id = config['user_id'] - folder_path = config['path'] - useruuid = username2uuid[user_id] - bb = backboard_manager.get_backboard(useruuid) - assert type(bb) == Backboard - - bb.add_history(realtime_action) - - if realtime_action['type'] == 'workspaceFolders': - bb.file_tree = realtime_action['fileTree'] - - if realtime_action['type'] == 'activeFile': - file_path = realtime_action['filePath'] - assert type(file_path) == str - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - if realtime_action['type'] == 'paste': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.pasted_file_path = file_path - bb.pasted_content = realtime_action['content'] - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - if realtime_action['type'] == 'fileEdit': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - - - print("config"+str(config)) - print("realtime_action"+str(realtime_action)) - pass - - -''' -Agent and Chat -''' -agent_manager = AgentManager(app = app, socketio = socketio) -user_threads = {} -import threading -from concurrent.futures import ThreadPoolExecutor, as_completed - -# 初始化线程池 -executor = ThreadPoolExecutor(max_workers=10) -class AgentNamespace(Namespace): - def on_login(self, data): - data = json.loads(data) - user = data['username'] - course_id = data['course_id'] - chapter_id = data['chapter_id'] - user_uuid = username2uuid[user] - session['user_id'] = user_uuid - print(f'User connected with session user_id: {user_uuid}') - # 从markdown、markdown_prompts、score_prompts中各读取数据folder.md并进行new_agent - with open(f'books/markdown/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fmd,\ - open(f'books/markdown_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8')as fmdp,\ - open(f'books/score_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fsp: - markdown = fmd.read() - markdown_prompts = fmdp.read() - score_prompts = fsp.read() - user_uuid, agent = agent_manager.new_agent(course_id, chapter_id, markdown, markdown_prompts, score_prompts, id=user_uuid, - root_path=f'../../study/{user}/{course_id}/{chapter_id}') - print(user_uuid) - join_room(user_uuid, namespace='/agent') # 将该用户加入以user_id为名的room - backboard_manager.add_backboard(user_uuid, user, course_id, chapter_id, root_path=f'../../study/{user}/{course_id}/{chapter_id}') - - def on_language(self, language): - id = session.get('user_id') - agent_manager.change_language(id, language) - - def on_message(self, data): - print(f"Message from client: {data}") - id = session.get('user_id') - if (type(data)==str): - data = json.loads(data) - print(id) - if data['type'] == 'text': - res = agent_manager.invoke(id, data['data'], backboard_manager.get_backboard(id).get_info_prompt()) - print('=*='*20) - print(res.content) - reply = f"{res.content['speak']}" - with app.app_context(): - emit('message',reply, room=id, namespace='/agent') - emit('request_function',res.content['function'], room=id, namespace='/agent') - - if data['type'] == 'function': - agent_manager.function_call(id, data['data']) - - def on_initiative(self,data): - print("User active function call") - user_id = session['user_id'] - if data['name'] == 'sample_judge': - agent_manager.sample_judge(user_id, backboard_manager.get_backboard(user_id)) - if data['name'] == 'judge': - agent_manager.judge(user_id, backboard_manager.get_backboard(user_id)) - - - - def on_disconnect(self,data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - - -''' -Markdown to HTML -''' -# 配置文件路径 -MARKDOWN_DIR = 'books/markdown' # 存放 markdown 文件的文件夹 -STATIC_DIR = 'static' # 存放生成的 HTML 和图片资源的文件夹 -IMAGE_DIR = 'image' # 图片资源相对于 markdown 的位置 - - - -@app.route('/--markdown', methods=['GET']) -def convert_md(course_id, filename): - md_file_path = os.path.join(MARKDOWN_DIR,course_id, f'{filename}.md') - - if not os.path.exists(md_file_path): - return jsonify({'error': 'Markdown file not found'}), 404 - - # 读取 markdown 文件内容 - with open(md_file_path, 'r', encoding='utf-8') as file: - md_content = file.read() - - # 将 markdown 转换为 HTML - html_content = markdown.markdown(md_content) - # 插入 CSS 样式,限制图片最大宽度为 100%,高度自动调整 - html_with_styles = f""" - - - - - - - {html_content} - - - """ - # 保存 HTML 文件到 static 文件夹 - html_output_path = os.path.join(STATIC_DIR, f'{filename}.html') - with open(html_output_path, 'w', encoding='utf-8') as html_file: - html_file.write(html_with_styles) - - # 处理图片资源,将 image/xxx 文件夹拷贝到 static/image/xxx - image_source_dir = os.path.join(MARKDOWN_DIR,course_id, IMAGE_DIR, filename) - image_target_dir = os.path.join(STATIC_DIR, IMAGE_DIR, filename) - print(f"Copying image resources from {image_source_dir} to {image_target_dir}") - if os.path.exists(image_source_dir): - # 确保 static/image/xxx 目录存在 - if not os.path.exists(image_target_dir): - os.makedirs(image_target_dir) - - # 拷贝图片资源 - for image_file in os.listdir(image_source_dir): - full_image_file_path = os.path.join(image_source_dir, image_file) - if os.path.isfile(full_image_file_path): - shutil.copy(full_image_file_path, image_target_dir) - - return jsonify({'html_url': f'/static/{filename}.html'}) - -# 静态文件(HTML 和图片资源)的访问 -@app.route('/static/') -def serve_static(filename): - return send_from_directory(STATIC_DIR, filename) - - -''' -Vscode -''' -@app.route('/desktop///') -def desktop(user_id, course_id, chapter_id): - if 'user_id' not in session: - # return redirect(url_for('login')) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ user_id + "uuid is"+ session['user_id']) - username2uuid[user_id] = session['user_id'] - uuid2username[session['user_id']] = user_id - userid_recorder[user_id+'&'+course_id] = session['user_id'] - - # 在学习目录下创建一个名为 user_id_path 的文件夹 - path_dir = os.path.join(student_workspace_root_path, user_id, course_id,chapter_id) - os.makedirs(path_dir, exist_ok=True) - # 在此文件夹内部创建一个.config文件,并写入 user_id=user_id\n path=path - config_path = os.path.join(path_dir, '.config') - if GLOBAL_CONFIG['VSCODE_WEB_PATH']['is_wsl']: # 如果是在 WSL 中运行,则将路径转换为 WSL 路径 - path_dir = path_dir.replace('\\', '/') - path_dir = path_dir.replace(GLOBAL_CONFIG['VSCODE_WEB_PATH']['windows_path'] , GLOBAL_CONFIG['VSCODE_WEB_PATH']['wsl_path']) - with open(config_path, 'w', encoding='utf-8') as f: - tmpd = {'user_id': user_id, 'course_id': course_id, 'chapter_id': chapter_id, 'path': path_dir} - json.dump(tmpd, f) - print('---------------------') - print(config_path) - return render_template('desktop.html', vscode_web_url=VSCODE_WEB_URL, user_id=user_id, course_id=course_id, chapter_id=chapter_id, workspace_path=path_dir) - -@app.route('/desktop_nouser//') -def desktop_nouser(course_id, chapter_id): - if 'user_id' not in session: - return redirect(url_for('login')) - user_id = session['user_id'] - username = uuid2username[user_id] - return redirect(url_for('desktop', user_id=username, course_id=course_id, chapter_id=chapter_id)) - -@app.route('/vscode_data', methods=['POST']) -def vscode_data(): - data = request.json - config = data['config'] - realtime_response(config,data) - print(f"Received data from VSCode: {data}") - return jsonify({"status": "success", "received": data}) - - - -''' -Login - -''' -users_list = UserList() -course_list = CourseList() - - -@app.route('/register') -def register(): - return render_template('register.html') - -@app.route('/register_teacher') -def register_teacher(): - return render_template('register_teacher.html') - -@app.route('/register_teacher_post', methods=['POST']) -def register_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password, teacher=True) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - -@app.route('/register_post', methods=['POST']) -def register_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - - -@app.route('/login') -def login(): - return render_template('login.html') - if 'user_id' not in session: - return render_template('login.html') - else: - return redirect(url_for('/')) - -@app.route('/login_post', methods=['POST']) -def login_post(): - # 获取请求的 JSON 数据 - data = request.get_json() - - username = data.get('username') - password = data.get('password') - - pswd = users_list.get_user_pswd(username) - - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/login_teacher_post', methods=['POST']) -def login_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - pswd = users_list.get_user_pswd(username) - is_teacher = users_list.get_user_is_teacher(username) - if is_teacher is None or is_teacher == False: - return jsonify({'success': False, 'message': '用户名不存在或非教师账号'}) - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/teacherboard') -@require_role(roles="teacher") -def teacherboard(): - return render_template('teacherboard.html') - - -@app.route('/logout') -def logout(): - session.pop('user_id', None) - return redirect(url_for('login')) - -@app.route('/get_session') -def get_session(): - user_session = session.get('user_id', 'default_session') - return jsonify({"session": user_session}) - - -''' -DashBoard -''' -user_id2UserClass = {} -@app.route('/dashboard') -@require_role -def dashboard(): - user_id = session['user_id'] - username = uuid2username[user_id] - if (user_id not in user_id2UserClass): - user_id2UserClass[user_id] = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - user_course_data = [] - for course_id in user_id2UserClass[user_id].select_course: - course_brief_info = course_list.get_course_brief_info(course_id, load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR)) - user_course_data.append(course_brief_info) - return render_template('dashboard.html',user_data = user_id2UserClass[user_id].to_json_without_dialog(), user_course_data = json.dumps(user_course_data)) - -''' -Course -''' - -@app.route('/course/') -@require_role -def course(course_id): - c = load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR) - return render_template('course.html', course_id=course_id, course_data=c) - -@app.route('/select_course', methods=['POST']) -@require_role -def select_course(): - user = user_id2UserClass[session['user_id']] - data = request.get_json() - course_id = data.get('course_id') - if course_id: - user.select_new_course(course_id, load_course_from_json(course_id, COURSE_DATA_DIR)) - return jsonify({'success': True, 'message': '课程选择成功'}) - - -@app.route('/') -@require_role -def home_index(): - selected_courses=[] - if ('user_id' in session): - if (session['user_id'] not in user_id2UserClass): return redirect(url_for('login')) - user = user_id2UserClass[session['user_id']] - for course_id in user.select_course: - selected_courses.append(course_id) - - return render_template('index.html', courses_data = course_list, selected_courses =selected_courses) - -# 一些app辅助函数,主要提供给Agent与数据库的交互能力 - -class MyFunction: - def save_chapter_memory(self, id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal): - print("-=-=-=-=-=-=-=-") - print(id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - username = uuid2username[id] - u = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - u.save_chapter_memory(course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - -app.my_function = MyFunction() -if __name__ == '__main__': - socketio.on_namespace(VSCodeNamespace('/vscode')) - socketio.on_namespace(AgentNamespace('/agent')) - socketio.run(app, host='0.0.0.0', port=5551, debug=False,allow_unsafe_werkzeug=True) - diff --git a/Html/runs/run_20250911-055837_qf7qys/code/backboardManager.py b/Html/runs/run_20250911-055837_qf7qys/code/backboardManager.py deleted file mode 100644 index 7de5f19..0000000 --- a/Html/runs/run_20250911-055837_qf7qys/code/backboardManager.py +++ /dev/null @@ -1,80 +0,0 @@ - - - -import time -import os - -class Backboard: - def __init__(self, user_uuid, username, course_id, lesson_id, root_path): - self.user_uuid = user_uuid - self.username = username - self.course_id = course_id - self.lesson_id = lesson_id - self.root_path = root_path - self.create_time = time.time() - self.enter_chapter_time = time.time() - self.history = [] - self.file_tree = "[]" - self.active_file_path = "" - self.active_file_content = "" - self.pasted_file_path = "" - self.pasted_content = "" - - - def next_chapter(self): - self.enter_chapter_time = time.time() - - def get_info_prompt(self): - - five_history = "" - for h in self.history[-5:]: - five_history += h['type'] + "\n" + h.get('filePath', '') + "\n\n" - - endl = "\n" - return (f"###Global Info:###{endl}" - f"Here are some info about now user's IDE, refer to it when you need to handle some code.{endl}" - f"- User's total study time is {self.get_deltatime_mmss(self.create_time, time.time())}{endl}" - f"- User's current chapter study time is {self.get_deltatime_mmss(self.enter_chapter_time, time.time())}{endl}" - f"- Activated file path: {self.active_file_path}{endl}" - f"```{endl}" - f"{self.active_file_content[-10:]}{endl}" - f"```{endl}" - f"- Last five action:{five_history}{endl}" - f"- File tree: {self.file_tree}{endl}") - # f"- Activated file content (current editing 10 lines): {endl}" - def add_history(self, realtime_action): - if(realtime_action['type']=='config'):return - if len(self.history)!=0: - if (self.history[-1]['type']=='fileEdit'): - if(self.history[-1]['filePath'] == realtime_action['filePath']): - self.history[-1]['content'] = realtime_action['content'] - return - self.history.append(realtime_action) - - - def get_deltatime_mmss(self, start_time, end_time): - elapsed_time = end_time - start_time - hours = int(elapsed_time // 3600) - minutes = int((elapsed_time % 3600) // 60) - seconds = int(elapsed_time % 60) - return f"{hours:02d}:{minutes:02d}:{seconds:02d}" - - - def get_active_file_reletive_path(self): - relative_path = os.path.relpath(self.active_file_path, self.root_path) - return relative_path - - - -class BackBoardManager: - def __init__(self): - self.backboards = {} # user_uuid: Backboard - - def add_backboard(self, user_uuid, username, course_id, lesson_id, root_path): - self.backboards[user_uuid] = Backboard(user_uuid,username, course_id, lesson_id, root_path) - - def get_backboard(self, user_uuid) -> Backboard: - return self.backboards[user_uuid] - - - diff --git a/Html/runs/run_20250911-055837_qf7qys/code/bootstrap.py b/Html/runs/run_20250911-055837_qf7qys/code/bootstrap.py deleted file mode 100644 index bcb15ce..0000000 --- a/Html/runs/run_20250911-055837_qf7qys/code/bootstrap.py +++ /dev/null @@ -1,31 +0,0 @@ -from pathlib import Path -import sys, os - -def bootstrap_paths(): - """ - 让 'AlgoriAgent'(位于 repo_root/AlgoriAgent)可被 import; - 并提供 STUDENT_WORKSPACE_ROOT 的默认值(repo_root/study)。 - 适配当前工厂位置:repo_root/Html/apps/__init__.py - """ - here = Path(__file__).resolve() - # repo_root = .../Html/apps/../../ => parents[2] - repo_root = here.parents[2] - - # 兜底:如果目录结构变化,尝试向上搜索包含 AlgoriAgent 的目录作为 repo_root - if not (repo_root / "AlgoriAgent").exists(): - for p in here.parents: - if (p / "AlgoriAgent").is_dir(): - repo_root = p - break - - # 确保仓库根在 sys.path(这样 'AlgoriAgent' 顶层包可被发现) - repo_root_str = str(repo_root) - if repo_root_str not in sys.path: - sys.path.insert(0, repo_root_str) - - # 可选:如果你还有其它顶层包,也可在此处继续插入 - - # 默认学习工作区目录(也可放到 config.ini / 环境变量覆盖) - os.environ.setdefault("STUDENT_WORKSPACE_ROOT", str(repo_root / "study")) - - return repo_root # 方便调试/日志 \ No newline at end of file diff --git a/Html/runs/run_20250911-055837_qf7qys/code/wsgi.py b/Html/runs/run_20250911-055837_qf7qys/code/wsgi.py deleted file mode 100644 index bbcbe5f..0000000 --- a/Html/runs/run_20250911-055837_qf7qys/code/wsgi.py +++ /dev/null @@ -1,6 +0,0 @@ -# wsgi.py -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -# 提供一个可被 WSGI/进程管理器导入的 app 对象 -app = create_app() diff --git a/Html/runs/run_20250911-055837_qf7qys/logging.chat b/Html/runs/run_20250911-055837_qf7qys/logging.chat deleted file mode 100644 index e69de29..0000000 diff --git a/Html/runs/run_20250911-055837_qf7qys/logging.log b/Html/runs/run_20250911-055837_qf7qys/logging.log deleted file mode 100644 index b0b19c0..0000000 --- a/Html/runs/run_20250911-055837_qf7qys/logging.log +++ /dev/null @@ -1 +0,0 @@ -2025-09-11 05:58:41.768 | INFO | agentscope.models:read_model_configs:186 - Load configs for model wrapper: openai_cfg diff --git a/Html/runs/run_20250911-055913_b9hlng/.config b/Html/runs/run_20250911-055913_b9hlng/.config deleted file mode 100644 index 17e6dbd..0000000 --- a/Html/runs/run_20250911-055913_b9hlng/.config +++ /dev/null @@ -1,7 +0,0 @@ -{ - "project": "U57t1W", - "name": "b9hlng", - "run_id": "run_20250911-055913_b9hlng", - "timestamp": "2025-09-11 05:59:13", - "pid": 31041 -} \ No newline at end of file diff --git a/Html/runs/run_20250911-055913_b9hlng/agentscope.db b/Html/runs/run_20250911-055913_b9hlng/agentscope.db deleted file mode 100644 index 666055b77679cda29c14fcf23b4ef1d039c5b52a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI%L2KJE6bEoS4Q(k)+glI2yjv3-0%NB!Hs&O1YUav`W0U1F<0V=#BsNLx(sSu$ z>=W&q?4#^B$!*yt2YT5l`~^0a^z(#~{ zkyg6w!t)u0!@f%5aeaJcfD9*Q_b$ozCY8>~CFA6|{Z2V!N;Z^cIq}eS$>x3HY|^=j z7lokrf1)Z$x@_R^N~@apn7OPMkZ(I<*1WJCw@v3GWy2n6&RcIQ0~zlR_x8^$%be!% zmxb7@7V;}H+K5#l(wSbZKXKY!mys6ROyi|!%aN@+%REpi?;B-K4PC3&{>iCzQnNB+ zwbW!z4iA{x(V_2L+5VJ1vMJeN;5l68yJ9?OZyl-TNCEp4P{^H8$cTGExdq$9ANE6@ zA@`ZUhb>is+Y=S?%$C1fnN{muZU1a!nMRV%#qFbMT;y3hf|KlJ)00Izz00bZa0SG_<0uX=z1a@EGHy1PL*Z=?k diff --git a/Html/runs/run_20250911-055913_b9hlng/code/app.py b/Html/runs/run_20250911-055913_b9hlng/code/app.py deleted file mode 100644 index c7f31f7..0000000 --- a/Html/runs/run_20250911-055913_b9hlng/code/app.py +++ /dev/null @@ -1,21 +0,0 @@ -# app.py 0.1.1 rise to factory mode -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -from apps.extensions import socketio - -# 工厂创建 app,工厂里已经做了:加载配置/注册蓝图/注册 namespaces -app = create_app() - -if __name__ == "__main__": - # 仅本地开发用;生产不要用 werkzeug 自带的开发服务器 - socketio.run( - app, - host="0.0.0.0", - port=5551, - debug=True, # 开发期打开 - allow_unsafe_werkzeug=True, # 避免 dev server 的安全限制提示 - # ssl_context=('server.crt', 'server.key') - ) - - diff --git a/Html/runs/run_20250911-055913_b9hlng/code/app_back.py b/Html/runs/run_20250911-055913_b9hlng/code/app_back.py deleted file mode 100644 index 246853c..0000000 --- a/Html/runs/run_20250911-055913_b9hlng/code/app_back.py +++ /dev/null @@ -1,480 +0,0 @@ -from bootstrap import bootstrap_paths -bootstrap_paths() -from functools import wraps -from flask import Flask, redirect, session, request, jsonify, render_template, send_from_directory, url_for -from flask_cors import CORS -from flask_socketio import SocketIO, join_room, emit, Namespace -import markdown -import os -import uuid -import shutil -import sys -import json -from apps.auth.decorators import require_role -parent_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) -sys.path.insert(0, parent_dir) -student_workspace_root_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../study')) -current_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '.')) -sys.path.insert(0, current_dir) -from AlgoriAgent.projects.algoriAgent.agent_manager import AgentManager - - -import configparser - -from db.user_list import UserList -from db.user import User, load_user_from_json, create_user_json -from db.course_list import CourseList -from db.course import Course, load_course_from_json -GLOBAL_CONFIG = configparser.ConfigParser() -GLOBAL_CONFIG.read('config.ini') -VSCODE_WEB_URL = GLOBAL_CONFIG['VSCODE_WEB']['url'] -USER_DATA_DIR = GLOBAL_CONFIG['USER_DATA']['dir'] -COURSE_DATA_DIR = GLOBAL_CONFIG['COURSE_DATA']['dir'] - -app = Flask(__name__) -socketio = SocketIO(app, cors_allowed_origins="*",ping_timeout=60, ping_interval=5) -# socketio = SocketIO(app, cors_allowed_origins="http://localhost:9888") # 设置跨域支持 -import logging -app.secret_key = 'cakebaker' -app.logger.setLevel(logging.DEBUG) -# 配置 CORS -CORS(app, resources={r"/*": {"origins": VSCODE_WEB_URL},}, supports_credentials=True) - - -userid_recorder = {} # user_id&path -> session['user_id'] - -''' -Backboard -''' -from backboardManager import BackBoardManager, Backboard - -backboard_manager = BackBoardManager() -uuid2username = {} -username2uuid = {} - - - -# 定义命名空间:用于和 VSCode 插件交流 -class VSCodeNamespace(Namespace): - def on_login(self,data): - print("VSCode client connected") - print(data) - dataconfig = data['config'] - user_id = dataconfig.get('user_id') - path = dataconfig.get('path') - course_id = dataconfig.get('course_id') - lesson_id = dataconfig.get('chapter_id') - print(f"User {user_id} connected with path: {path}") - useruuid = username2uuid[user_id] - join_room(useruuid, namespace='/vscode') - if backboard_manager.get_backboard(useruuid) == None: - backboard_manager.add_backboard(useruuid,user_id, course_id, lesson_id, path) - - - def on_message(self, data): - print(f"Received from VSCode client: {data}") - dataconfig = data['config'] - realtime_response(dataconfig, data) - # emit('response', {'message': 'Config data received and connection established'}) - def on_disconnect(self, data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - -def realtime_response(config, realtime_action): - user_id = config['user_id'] - folder_path = config['path'] - useruuid = username2uuid[user_id] - bb = backboard_manager.get_backboard(useruuid) - assert type(bb) == Backboard - - bb.add_history(realtime_action) - - if realtime_action['type'] == 'workspaceFolders': - bb.file_tree = realtime_action['fileTree'] - - if realtime_action['type'] == 'activeFile': - file_path = realtime_action['filePath'] - assert type(file_path) == str - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - if realtime_action['type'] == 'paste': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.pasted_file_path = file_path - bb.pasted_content = realtime_action['content'] - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - if realtime_action['type'] == 'fileEdit': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - - - print("config"+str(config)) - print("realtime_action"+str(realtime_action)) - pass - - -''' -Agent and Chat -''' -agent_manager = AgentManager(app = app, socketio = socketio) -user_threads = {} -import threading -from concurrent.futures import ThreadPoolExecutor, as_completed - -# 初始化线程池 -executor = ThreadPoolExecutor(max_workers=10) -class AgentNamespace(Namespace): - def on_login(self, data): - data = json.loads(data) - user = data['username'] - course_id = data['course_id'] - chapter_id = data['chapter_id'] - user_uuid = username2uuid[user] - session['user_id'] = user_uuid - print(f'User connected with session user_id: {user_uuid}') - # 从markdown、markdown_prompts、score_prompts中各读取数据folder.md并进行new_agent - with open(f'books/markdown/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fmd,\ - open(f'books/markdown_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8')as fmdp,\ - open(f'books/score_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fsp: - markdown = fmd.read() - markdown_prompts = fmdp.read() - score_prompts = fsp.read() - user_uuid, agent = agent_manager.new_agent(course_id, chapter_id, markdown, markdown_prompts, score_prompts, id=user_uuid, - root_path=f'../../study/{user}/{course_id}/{chapter_id}') - print(user_uuid) - join_room(user_uuid, namespace='/agent') # 将该用户加入以user_id为名的room - backboard_manager.add_backboard(user_uuid, user, course_id, chapter_id, root_path=f'../../study/{user}/{course_id}/{chapter_id}') - - def on_language(self, language): - id = session.get('user_id') - agent_manager.change_language(id, language) - - def on_message(self, data): - print(f"Message from client: {data}") - id = session.get('user_id') - if (type(data)==str): - data = json.loads(data) - print(id) - if data['type'] == 'text': - res = agent_manager.invoke(id, data['data'], backboard_manager.get_backboard(id).get_info_prompt()) - print('=*='*20) - print(res.content) - reply = f"{res.content['speak']}" - with app.app_context(): - emit('message',reply, room=id, namespace='/agent') - emit('request_function',res.content['function'], room=id, namespace='/agent') - - if data['type'] == 'function': - agent_manager.function_call(id, data['data']) - - def on_initiative(self,data): - print("User active function call") - user_id = session['user_id'] - if data['name'] == 'sample_judge': - agent_manager.sample_judge(user_id, backboard_manager.get_backboard(user_id)) - if data['name'] == 'judge': - agent_manager.judge(user_id, backboard_manager.get_backboard(user_id)) - - - - def on_disconnect(self,data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - - -''' -Markdown to HTML -''' -# 配置文件路径 -MARKDOWN_DIR = 'books/markdown' # 存放 markdown 文件的文件夹 -STATIC_DIR = 'static' # 存放生成的 HTML 和图片资源的文件夹 -IMAGE_DIR = 'image' # 图片资源相对于 markdown 的位置 - - - -@app.route('/--markdown', methods=['GET']) -def convert_md(course_id, filename): - md_file_path = os.path.join(MARKDOWN_DIR,course_id, f'{filename}.md') - - if not os.path.exists(md_file_path): - return jsonify({'error': 'Markdown file not found'}), 404 - - # 读取 markdown 文件内容 - with open(md_file_path, 'r', encoding='utf-8') as file: - md_content = file.read() - - # 将 markdown 转换为 HTML - html_content = markdown.markdown(md_content) - # 插入 CSS 样式,限制图片最大宽度为 100%,高度自动调整 - html_with_styles = f""" - - - - - - - {html_content} - - - """ - # 保存 HTML 文件到 static 文件夹 - html_output_path = os.path.join(STATIC_DIR, f'{filename}.html') - with open(html_output_path, 'w', encoding='utf-8') as html_file: - html_file.write(html_with_styles) - - # 处理图片资源,将 image/xxx 文件夹拷贝到 static/image/xxx - image_source_dir = os.path.join(MARKDOWN_DIR,course_id, IMAGE_DIR, filename) - image_target_dir = os.path.join(STATIC_DIR, IMAGE_DIR, filename) - print(f"Copying image resources from {image_source_dir} to {image_target_dir}") - if os.path.exists(image_source_dir): - # 确保 static/image/xxx 目录存在 - if not os.path.exists(image_target_dir): - os.makedirs(image_target_dir) - - # 拷贝图片资源 - for image_file in os.listdir(image_source_dir): - full_image_file_path = os.path.join(image_source_dir, image_file) - if os.path.isfile(full_image_file_path): - shutil.copy(full_image_file_path, image_target_dir) - - return jsonify({'html_url': f'/static/{filename}.html'}) - -# 静态文件(HTML 和图片资源)的访问 -@app.route('/static/') -def serve_static(filename): - return send_from_directory(STATIC_DIR, filename) - - -''' -Vscode -''' -@app.route('/desktop///') -def desktop(user_id, course_id, chapter_id): - if 'user_id' not in session: - # return redirect(url_for('login')) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ user_id + "uuid is"+ session['user_id']) - username2uuid[user_id] = session['user_id'] - uuid2username[session['user_id']] = user_id - userid_recorder[user_id+'&'+course_id] = session['user_id'] - - # 在学习目录下创建一个名为 user_id_path 的文件夹 - path_dir = os.path.join(student_workspace_root_path, user_id, course_id,chapter_id) - os.makedirs(path_dir, exist_ok=True) - # 在此文件夹内部创建一个.config文件,并写入 user_id=user_id\n path=path - config_path = os.path.join(path_dir, '.config') - if GLOBAL_CONFIG['VSCODE_WEB_PATH']['is_wsl']: # 如果是在 WSL 中运行,则将路径转换为 WSL 路径 - path_dir = path_dir.replace('\\', '/') - path_dir = path_dir.replace(GLOBAL_CONFIG['VSCODE_WEB_PATH']['windows_path'] , GLOBAL_CONFIG['VSCODE_WEB_PATH']['wsl_path']) - with open(config_path, 'w', encoding='utf-8') as f: - tmpd = {'user_id': user_id, 'course_id': course_id, 'chapter_id': chapter_id, 'path': path_dir} - json.dump(tmpd, f) - print('---------------------') - print(config_path) - return render_template('desktop.html', vscode_web_url=VSCODE_WEB_URL, user_id=user_id, course_id=course_id, chapter_id=chapter_id, workspace_path=path_dir) - -@app.route('/desktop_nouser//') -def desktop_nouser(course_id, chapter_id): - if 'user_id' not in session: - return redirect(url_for('login')) - user_id = session['user_id'] - username = uuid2username[user_id] - return redirect(url_for('desktop', user_id=username, course_id=course_id, chapter_id=chapter_id)) - -@app.route('/vscode_data', methods=['POST']) -def vscode_data(): - data = request.json - config = data['config'] - realtime_response(config,data) - print(f"Received data from VSCode: {data}") - return jsonify({"status": "success", "received": data}) - - - -''' -Login - -''' -users_list = UserList() -course_list = CourseList() - - -@app.route('/register') -def register(): - return render_template('register.html') - -@app.route('/register_teacher') -def register_teacher(): - return render_template('register_teacher.html') - -@app.route('/register_teacher_post', methods=['POST']) -def register_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password, teacher=True) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - -@app.route('/register_post', methods=['POST']) -def register_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - - -@app.route('/login') -def login(): - return render_template('login.html') - if 'user_id' not in session: - return render_template('login.html') - else: - return redirect(url_for('/')) - -@app.route('/login_post', methods=['POST']) -def login_post(): - # 获取请求的 JSON 数据 - data = request.get_json() - - username = data.get('username') - password = data.get('password') - - pswd = users_list.get_user_pswd(username) - - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/login_teacher_post', methods=['POST']) -def login_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - pswd = users_list.get_user_pswd(username) - is_teacher = users_list.get_user_is_teacher(username) - if is_teacher is None or is_teacher == False: - return jsonify({'success': False, 'message': '用户名不存在或非教师账号'}) - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/teacherboard') -@require_role(roles="teacher") -def teacherboard(): - return render_template('teacherboard.html') - - -@app.route('/logout') -def logout(): - session.pop('user_id', None) - return redirect(url_for('login')) - -@app.route('/get_session') -def get_session(): - user_session = session.get('user_id', 'default_session') - return jsonify({"session": user_session}) - - -''' -DashBoard -''' -user_id2UserClass = {} -@app.route('/dashboard') -@require_role -def dashboard(): - user_id = session['user_id'] - username = uuid2username[user_id] - if (user_id not in user_id2UserClass): - user_id2UserClass[user_id] = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - user_course_data = [] - for course_id in user_id2UserClass[user_id].select_course: - course_brief_info = course_list.get_course_brief_info(course_id, load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR)) - user_course_data.append(course_brief_info) - return render_template('dashboard.html',user_data = user_id2UserClass[user_id].to_json_without_dialog(), user_course_data = json.dumps(user_course_data)) - -''' -Course -''' - -@app.route('/course/') -@require_role -def course(course_id): - c = load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR) - return render_template('course.html', course_id=course_id, course_data=c) - -@app.route('/select_course', methods=['POST']) -@require_role -def select_course(): - user = user_id2UserClass[session['user_id']] - data = request.get_json() - course_id = data.get('course_id') - if course_id: - user.select_new_course(course_id, load_course_from_json(course_id, COURSE_DATA_DIR)) - return jsonify({'success': True, 'message': '课程选择成功'}) - - -@app.route('/') -@require_role -def home_index(): - selected_courses=[] - if ('user_id' in session): - if (session['user_id'] not in user_id2UserClass): return redirect(url_for('login')) - user = user_id2UserClass[session['user_id']] - for course_id in user.select_course: - selected_courses.append(course_id) - - return render_template('index.html', courses_data = course_list, selected_courses =selected_courses) - -# 一些app辅助函数,主要提供给Agent与数据库的交互能力 - -class MyFunction: - def save_chapter_memory(self, id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal): - print("-=-=-=-=-=-=-=-") - print(id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - username = uuid2username[id] - u = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - u.save_chapter_memory(course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - -app.my_function = MyFunction() -if __name__ == '__main__': - socketio.on_namespace(VSCodeNamespace('/vscode')) - socketio.on_namespace(AgentNamespace('/agent')) - socketio.run(app, host='0.0.0.0', port=5551, debug=False,allow_unsafe_werkzeug=True) - diff --git a/Html/runs/run_20250911-055913_b9hlng/code/backboardManager.py b/Html/runs/run_20250911-055913_b9hlng/code/backboardManager.py deleted file mode 100644 index 7de5f19..0000000 --- a/Html/runs/run_20250911-055913_b9hlng/code/backboardManager.py +++ /dev/null @@ -1,80 +0,0 @@ - - - -import time -import os - -class Backboard: - def __init__(self, user_uuid, username, course_id, lesson_id, root_path): - self.user_uuid = user_uuid - self.username = username - self.course_id = course_id - self.lesson_id = lesson_id - self.root_path = root_path - self.create_time = time.time() - self.enter_chapter_time = time.time() - self.history = [] - self.file_tree = "[]" - self.active_file_path = "" - self.active_file_content = "" - self.pasted_file_path = "" - self.pasted_content = "" - - - def next_chapter(self): - self.enter_chapter_time = time.time() - - def get_info_prompt(self): - - five_history = "" - for h in self.history[-5:]: - five_history += h['type'] + "\n" + h.get('filePath', '') + "\n\n" - - endl = "\n" - return (f"###Global Info:###{endl}" - f"Here are some info about now user's IDE, refer to it when you need to handle some code.{endl}" - f"- User's total study time is {self.get_deltatime_mmss(self.create_time, time.time())}{endl}" - f"- User's current chapter study time is {self.get_deltatime_mmss(self.enter_chapter_time, time.time())}{endl}" - f"- Activated file path: {self.active_file_path}{endl}" - f"```{endl}" - f"{self.active_file_content[-10:]}{endl}" - f"```{endl}" - f"- Last five action:{five_history}{endl}" - f"- File tree: {self.file_tree}{endl}") - # f"- Activated file content (current editing 10 lines): {endl}" - def add_history(self, realtime_action): - if(realtime_action['type']=='config'):return - if len(self.history)!=0: - if (self.history[-1]['type']=='fileEdit'): - if(self.history[-1]['filePath'] == realtime_action['filePath']): - self.history[-1]['content'] = realtime_action['content'] - return - self.history.append(realtime_action) - - - def get_deltatime_mmss(self, start_time, end_time): - elapsed_time = end_time - start_time - hours = int(elapsed_time // 3600) - minutes = int((elapsed_time % 3600) // 60) - seconds = int(elapsed_time % 60) - return f"{hours:02d}:{minutes:02d}:{seconds:02d}" - - - def get_active_file_reletive_path(self): - relative_path = os.path.relpath(self.active_file_path, self.root_path) - return relative_path - - - -class BackBoardManager: - def __init__(self): - self.backboards = {} # user_uuid: Backboard - - def add_backboard(self, user_uuid, username, course_id, lesson_id, root_path): - self.backboards[user_uuid] = Backboard(user_uuid,username, course_id, lesson_id, root_path) - - def get_backboard(self, user_uuid) -> Backboard: - return self.backboards[user_uuid] - - - diff --git a/Html/runs/run_20250911-055913_b9hlng/code/bootstrap.py b/Html/runs/run_20250911-055913_b9hlng/code/bootstrap.py deleted file mode 100644 index bcb15ce..0000000 --- a/Html/runs/run_20250911-055913_b9hlng/code/bootstrap.py +++ /dev/null @@ -1,31 +0,0 @@ -from pathlib import Path -import sys, os - -def bootstrap_paths(): - """ - 让 'AlgoriAgent'(位于 repo_root/AlgoriAgent)可被 import; - 并提供 STUDENT_WORKSPACE_ROOT 的默认值(repo_root/study)。 - 适配当前工厂位置:repo_root/Html/apps/__init__.py - """ - here = Path(__file__).resolve() - # repo_root = .../Html/apps/../../ => parents[2] - repo_root = here.parents[2] - - # 兜底:如果目录结构变化,尝试向上搜索包含 AlgoriAgent 的目录作为 repo_root - if not (repo_root / "AlgoriAgent").exists(): - for p in here.parents: - if (p / "AlgoriAgent").is_dir(): - repo_root = p - break - - # 确保仓库根在 sys.path(这样 'AlgoriAgent' 顶层包可被发现) - repo_root_str = str(repo_root) - if repo_root_str not in sys.path: - sys.path.insert(0, repo_root_str) - - # 可选:如果你还有其它顶层包,也可在此处继续插入 - - # 默认学习工作区目录(也可放到 config.ini / 环境变量覆盖) - os.environ.setdefault("STUDENT_WORKSPACE_ROOT", str(repo_root / "study")) - - return repo_root # 方便调试/日志 \ No newline at end of file diff --git a/Html/runs/run_20250911-055913_b9hlng/code/wsgi.py b/Html/runs/run_20250911-055913_b9hlng/code/wsgi.py deleted file mode 100644 index bbcbe5f..0000000 --- a/Html/runs/run_20250911-055913_b9hlng/code/wsgi.py +++ /dev/null @@ -1,6 +0,0 @@ -# wsgi.py -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -# 提供一个可被 WSGI/进程管理器导入的 app 对象 -app = create_app() diff --git a/Html/runs/run_20250911-055913_b9hlng/logging.chat b/Html/runs/run_20250911-055913_b9hlng/logging.chat deleted file mode 100644 index e69de29..0000000 diff --git a/Html/runs/run_20250911-055913_b9hlng/logging.log b/Html/runs/run_20250911-055913_b9hlng/logging.log deleted file mode 100644 index 091a125..0000000 --- a/Html/runs/run_20250911-055913_b9hlng/logging.log +++ /dev/null @@ -1 +0,0 @@ -2025-09-11 05:59:16.771 | INFO | agentscope.models:read_model_configs:186 - Load configs for model wrapper: openai_cfg diff --git a/Html/runs/run_20250911-060203_yfghxt/.config b/Html/runs/run_20250911-060203_yfghxt/.config deleted file mode 100644 index d6a3b8e..0000000 --- a/Html/runs/run_20250911-060203_yfghxt/.config +++ /dev/null @@ -1,7 +0,0 @@ -{ - "project": "B1xMcN", - "name": "yfghxt", - "run_id": "run_20250911-060203_yfghxt", - "timestamp": "2025-09-11 06:02:03", - "pid": 31475 -} \ No newline at end of file diff --git a/Html/runs/run_20250911-060203_yfghxt/agentscope.db b/Html/runs/run_20250911-060203_yfghxt/agentscope.db deleted file mode 100644 index 666055b77679cda29c14fcf23b4ef1d039c5b52a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI%L2KJE6bEoS4Q(k)+glI2yjv3-0%NB!Hs&O1YUav`W0U1F<0V=#BsNLx(sSu$ z>=W&q?4#^B$!*yt2YT5l`~^0a^z(#~{ zkyg6w!t)u0!@f%5aeaJcfD9*Q_b$ozCY8>~CFA6|{Z2V!N;Z^cIq}eS$>x3HY|^=j z7lokrf1)Z$x@_R^N~@apn7OPMkZ(I<*1WJCw@v3GWy2n6&RcIQ0~zlR_x8^$%be!% zmxb7@7V;}H+K5#l(wSbZKXKY!mys6ROyi|!%aN@+%REpi?;B-K4PC3&{>iCzQnNB+ zwbW!z4iA{x(V_2L+5VJ1vMJeN;5l68yJ9?OZyl-TNCEp4P{^H8$cTGExdq$9ANE6@ zA@`ZUhb>is+Y=S?%$C1fnN{muZU1a!nMRV%#qFbMT;y3hf|KlJ)00Izz00bZa0SG_<0uX=z1a@EGHy1PL*Z=?k diff --git a/Html/runs/run_20250911-060203_yfghxt/code/app.py b/Html/runs/run_20250911-060203_yfghxt/code/app.py deleted file mode 100644 index c7f31f7..0000000 --- a/Html/runs/run_20250911-060203_yfghxt/code/app.py +++ /dev/null @@ -1,21 +0,0 @@ -# app.py 0.1.1 rise to factory mode -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -from apps.extensions import socketio - -# 工厂创建 app,工厂里已经做了:加载配置/注册蓝图/注册 namespaces -app = create_app() - -if __name__ == "__main__": - # 仅本地开发用;生产不要用 werkzeug 自带的开发服务器 - socketio.run( - app, - host="0.0.0.0", - port=5551, - debug=True, # 开发期打开 - allow_unsafe_werkzeug=True, # 避免 dev server 的安全限制提示 - # ssl_context=('server.crt', 'server.key') - ) - - diff --git a/Html/runs/run_20250911-060203_yfghxt/code/app_back.py b/Html/runs/run_20250911-060203_yfghxt/code/app_back.py deleted file mode 100644 index 246853c..0000000 --- a/Html/runs/run_20250911-060203_yfghxt/code/app_back.py +++ /dev/null @@ -1,480 +0,0 @@ -from bootstrap import bootstrap_paths -bootstrap_paths() -from functools import wraps -from flask import Flask, redirect, session, request, jsonify, render_template, send_from_directory, url_for -from flask_cors import CORS -from flask_socketio import SocketIO, join_room, emit, Namespace -import markdown -import os -import uuid -import shutil -import sys -import json -from apps.auth.decorators import require_role -parent_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) -sys.path.insert(0, parent_dir) -student_workspace_root_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../study')) -current_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '.')) -sys.path.insert(0, current_dir) -from AlgoriAgent.projects.algoriAgent.agent_manager import AgentManager - - -import configparser - -from db.user_list import UserList -from db.user import User, load_user_from_json, create_user_json -from db.course_list import CourseList -from db.course import Course, load_course_from_json -GLOBAL_CONFIG = configparser.ConfigParser() -GLOBAL_CONFIG.read('config.ini') -VSCODE_WEB_URL = GLOBAL_CONFIG['VSCODE_WEB']['url'] -USER_DATA_DIR = GLOBAL_CONFIG['USER_DATA']['dir'] -COURSE_DATA_DIR = GLOBAL_CONFIG['COURSE_DATA']['dir'] - -app = Flask(__name__) -socketio = SocketIO(app, cors_allowed_origins="*",ping_timeout=60, ping_interval=5) -# socketio = SocketIO(app, cors_allowed_origins="http://localhost:9888") # 设置跨域支持 -import logging -app.secret_key = 'cakebaker' -app.logger.setLevel(logging.DEBUG) -# 配置 CORS -CORS(app, resources={r"/*": {"origins": VSCODE_WEB_URL},}, supports_credentials=True) - - -userid_recorder = {} # user_id&path -> session['user_id'] - -''' -Backboard -''' -from backboardManager import BackBoardManager, Backboard - -backboard_manager = BackBoardManager() -uuid2username = {} -username2uuid = {} - - - -# 定义命名空间:用于和 VSCode 插件交流 -class VSCodeNamespace(Namespace): - def on_login(self,data): - print("VSCode client connected") - print(data) - dataconfig = data['config'] - user_id = dataconfig.get('user_id') - path = dataconfig.get('path') - course_id = dataconfig.get('course_id') - lesson_id = dataconfig.get('chapter_id') - print(f"User {user_id} connected with path: {path}") - useruuid = username2uuid[user_id] - join_room(useruuid, namespace='/vscode') - if backboard_manager.get_backboard(useruuid) == None: - backboard_manager.add_backboard(useruuid,user_id, course_id, lesson_id, path) - - - def on_message(self, data): - print(f"Received from VSCode client: {data}") - dataconfig = data['config'] - realtime_response(dataconfig, data) - # emit('response', {'message': 'Config data received and connection established'}) - def on_disconnect(self, data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - -def realtime_response(config, realtime_action): - user_id = config['user_id'] - folder_path = config['path'] - useruuid = username2uuid[user_id] - bb = backboard_manager.get_backboard(useruuid) - assert type(bb) == Backboard - - bb.add_history(realtime_action) - - if realtime_action['type'] == 'workspaceFolders': - bb.file_tree = realtime_action['fileTree'] - - if realtime_action['type'] == 'activeFile': - file_path = realtime_action['filePath'] - assert type(file_path) == str - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - if realtime_action['type'] == 'paste': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.pasted_file_path = file_path - bb.pasted_content = realtime_action['content'] - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - if realtime_action['type'] == 'fileEdit': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - - - print("config"+str(config)) - print("realtime_action"+str(realtime_action)) - pass - - -''' -Agent and Chat -''' -agent_manager = AgentManager(app = app, socketio = socketio) -user_threads = {} -import threading -from concurrent.futures import ThreadPoolExecutor, as_completed - -# 初始化线程池 -executor = ThreadPoolExecutor(max_workers=10) -class AgentNamespace(Namespace): - def on_login(self, data): - data = json.loads(data) - user = data['username'] - course_id = data['course_id'] - chapter_id = data['chapter_id'] - user_uuid = username2uuid[user] - session['user_id'] = user_uuid - print(f'User connected with session user_id: {user_uuid}') - # 从markdown、markdown_prompts、score_prompts中各读取数据folder.md并进行new_agent - with open(f'books/markdown/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fmd,\ - open(f'books/markdown_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8')as fmdp,\ - open(f'books/score_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fsp: - markdown = fmd.read() - markdown_prompts = fmdp.read() - score_prompts = fsp.read() - user_uuid, agent = agent_manager.new_agent(course_id, chapter_id, markdown, markdown_prompts, score_prompts, id=user_uuid, - root_path=f'../../study/{user}/{course_id}/{chapter_id}') - print(user_uuid) - join_room(user_uuid, namespace='/agent') # 将该用户加入以user_id为名的room - backboard_manager.add_backboard(user_uuid, user, course_id, chapter_id, root_path=f'../../study/{user}/{course_id}/{chapter_id}') - - def on_language(self, language): - id = session.get('user_id') - agent_manager.change_language(id, language) - - def on_message(self, data): - print(f"Message from client: {data}") - id = session.get('user_id') - if (type(data)==str): - data = json.loads(data) - print(id) - if data['type'] == 'text': - res = agent_manager.invoke(id, data['data'], backboard_manager.get_backboard(id).get_info_prompt()) - print('=*='*20) - print(res.content) - reply = f"{res.content['speak']}" - with app.app_context(): - emit('message',reply, room=id, namespace='/agent') - emit('request_function',res.content['function'], room=id, namespace='/agent') - - if data['type'] == 'function': - agent_manager.function_call(id, data['data']) - - def on_initiative(self,data): - print("User active function call") - user_id = session['user_id'] - if data['name'] == 'sample_judge': - agent_manager.sample_judge(user_id, backboard_manager.get_backboard(user_id)) - if data['name'] == 'judge': - agent_manager.judge(user_id, backboard_manager.get_backboard(user_id)) - - - - def on_disconnect(self,data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - - -''' -Markdown to HTML -''' -# 配置文件路径 -MARKDOWN_DIR = 'books/markdown' # 存放 markdown 文件的文件夹 -STATIC_DIR = 'static' # 存放生成的 HTML 和图片资源的文件夹 -IMAGE_DIR = 'image' # 图片资源相对于 markdown 的位置 - - - -@app.route('/--markdown', methods=['GET']) -def convert_md(course_id, filename): - md_file_path = os.path.join(MARKDOWN_DIR,course_id, f'{filename}.md') - - if not os.path.exists(md_file_path): - return jsonify({'error': 'Markdown file not found'}), 404 - - # 读取 markdown 文件内容 - with open(md_file_path, 'r', encoding='utf-8') as file: - md_content = file.read() - - # 将 markdown 转换为 HTML - html_content = markdown.markdown(md_content) - # 插入 CSS 样式,限制图片最大宽度为 100%,高度自动调整 - html_with_styles = f""" - - - - - - - {html_content} - - - """ - # 保存 HTML 文件到 static 文件夹 - html_output_path = os.path.join(STATIC_DIR, f'{filename}.html') - with open(html_output_path, 'w', encoding='utf-8') as html_file: - html_file.write(html_with_styles) - - # 处理图片资源,将 image/xxx 文件夹拷贝到 static/image/xxx - image_source_dir = os.path.join(MARKDOWN_DIR,course_id, IMAGE_DIR, filename) - image_target_dir = os.path.join(STATIC_DIR, IMAGE_DIR, filename) - print(f"Copying image resources from {image_source_dir} to {image_target_dir}") - if os.path.exists(image_source_dir): - # 确保 static/image/xxx 目录存在 - if not os.path.exists(image_target_dir): - os.makedirs(image_target_dir) - - # 拷贝图片资源 - for image_file in os.listdir(image_source_dir): - full_image_file_path = os.path.join(image_source_dir, image_file) - if os.path.isfile(full_image_file_path): - shutil.copy(full_image_file_path, image_target_dir) - - return jsonify({'html_url': f'/static/{filename}.html'}) - -# 静态文件(HTML 和图片资源)的访问 -@app.route('/static/') -def serve_static(filename): - return send_from_directory(STATIC_DIR, filename) - - -''' -Vscode -''' -@app.route('/desktop///') -def desktop(user_id, course_id, chapter_id): - if 'user_id' not in session: - # return redirect(url_for('login')) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ user_id + "uuid is"+ session['user_id']) - username2uuid[user_id] = session['user_id'] - uuid2username[session['user_id']] = user_id - userid_recorder[user_id+'&'+course_id] = session['user_id'] - - # 在学习目录下创建一个名为 user_id_path 的文件夹 - path_dir = os.path.join(student_workspace_root_path, user_id, course_id,chapter_id) - os.makedirs(path_dir, exist_ok=True) - # 在此文件夹内部创建一个.config文件,并写入 user_id=user_id\n path=path - config_path = os.path.join(path_dir, '.config') - if GLOBAL_CONFIG['VSCODE_WEB_PATH']['is_wsl']: # 如果是在 WSL 中运行,则将路径转换为 WSL 路径 - path_dir = path_dir.replace('\\', '/') - path_dir = path_dir.replace(GLOBAL_CONFIG['VSCODE_WEB_PATH']['windows_path'] , GLOBAL_CONFIG['VSCODE_WEB_PATH']['wsl_path']) - with open(config_path, 'w', encoding='utf-8') as f: - tmpd = {'user_id': user_id, 'course_id': course_id, 'chapter_id': chapter_id, 'path': path_dir} - json.dump(tmpd, f) - print('---------------------') - print(config_path) - return render_template('desktop.html', vscode_web_url=VSCODE_WEB_URL, user_id=user_id, course_id=course_id, chapter_id=chapter_id, workspace_path=path_dir) - -@app.route('/desktop_nouser//') -def desktop_nouser(course_id, chapter_id): - if 'user_id' not in session: - return redirect(url_for('login')) - user_id = session['user_id'] - username = uuid2username[user_id] - return redirect(url_for('desktop', user_id=username, course_id=course_id, chapter_id=chapter_id)) - -@app.route('/vscode_data', methods=['POST']) -def vscode_data(): - data = request.json - config = data['config'] - realtime_response(config,data) - print(f"Received data from VSCode: {data}") - return jsonify({"status": "success", "received": data}) - - - -''' -Login - -''' -users_list = UserList() -course_list = CourseList() - - -@app.route('/register') -def register(): - return render_template('register.html') - -@app.route('/register_teacher') -def register_teacher(): - return render_template('register_teacher.html') - -@app.route('/register_teacher_post', methods=['POST']) -def register_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password, teacher=True) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - -@app.route('/register_post', methods=['POST']) -def register_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - - -@app.route('/login') -def login(): - return render_template('login.html') - if 'user_id' not in session: - return render_template('login.html') - else: - return redirect(url_for('/')) - -@app.route('/login_post', methods=['POST']) -def login_post(): - # 获取请求的 JSON 数据 - data = request.get_json() - - username = data.get('username') - password = data.get('password') - - pswd = users_list.get_user_pswd(username) - - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/login_teacher_post', methods=['POST']) -def login_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - pswd = users_list.get_user_pswd(username) - is_teacher = users_list.get_user_is_teacher(username) - if is_teacher is None or is_teacher == False: - return jsonify({'success': False, 'message': '用户名不存在或非教师账号'}) - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/teacherboard') -@require_role(roles="teacher") -def teacherboard(): - return render_template('teacherboard.html') - - -@app.route('/logout') -def logout(): - session.pop('user_id', None) - return redirect(url_for('login')) - -@app.route('/get_session') -def get_session(): - user_session = session.get('user_id', 'default_session') - return jsonify({"session": user_session}) - - -''' -DashBoard -''' -user_id2UserClass = {} -@app.route('/dashboard') -@require_role -def dashboard(): - user_id = session['user_id'] - username = uuid2username[user_id] - if (user_id not in user_id2UserClass): - user_id2UserClass[user_id] = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - user_course_data = [] - for course_id in user_id2UserClass[user_id].select_course: - course_brief_info = course_list.get_course_brief_info(course_id, load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR)) - user_course_data.append(course_brief_info) - return render_template('dashboard.html',user_data = user_id2UserClass[user_id].to_json_without_dialog(), user_course_data = json.dumps(user_course_data)) - -''' -Course -''' - -@app.route('/course/') -@require_role -def course(course_id): - c = load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR) - return render_template('course.html', course_id=course_id, course_data=c) - -@app.route('/select_course', methods=['POST']) -@require_role -def select_course(): - user = user_id2UserClass[session['user_id']] - data = request.get_json() - course_id = data.get('course_id') - if course_id: - user.select_new_course(course_id, load_course_from_json(course_id, COURSE_DATA_DIR)) - return jsonify({'success': True, 'message': '课程选择成功'}) - - -@app.route('/') -@require_role -def home_index(): - selected_courses=[] - if ('user_id' in session): - if (session['user_id'] not in user_id2UserClass): return redirect(url_for('login')) - user = user_id2UserClass[session['user_id']] - for course_id in user.select_course: - selected_courses.append(course_id) - - return render_template('index.html', courses_data = course_list, selected_courses =selected_courses) - -# 一些app辅助函数,主要提供给Agent与数据库的交互能力 - -class MyFunction: - def save_chapter_memory(self, id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal): - print("-=-=-=-=-=-=-=-") - print(id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - username = uuid2username[id] - u = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - u.save_chapter_memory(course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - -app.my_function = MyFunction() -if __name__ == '__main__': - socketio.on_namespace(VSCodeNamespace('/vscode')) - socketio.on_namespace(AgentNamespace('/agent')) - socketio.run(app, host='0.0.0.0', port=5551, debug=False,allow_unsafe_werkzeug=True) - diff --git a/Html/runs/run_20250911-060203_yfghxt/code/backboardManager.py b/Html/runs/run_20250911-060203_yfghxt/code/backboardManager.py deleted file mode 100644 index 7de5f19..0000000 --- a/Html/runs/run_20250911-060203_yfghxt/code/backboardManager.py +++ /dev/null @@ -1,80 +0,0 @@ - - - -import time -import os - -class Backboard: - def __init__(self, user_uuid, username, course_id, lesson_id, root_path): - self.user_uuid = user_uuid - self.username = username - self.course_id = course_id - self.lesson_id = lesson_id - self.root_path = root_path - self.create_time = time.time() - self.enter_chapter_time = time.time() - self.history = [] - self.file_tree = "[]" - self.active_file_path = "" - self.active_file_content = "" - self.pasted_file_path = "" - self.pasted_content = "" - - - def next_chapter(self): - self.enter_chapter_time = time.time() - - def get_info_prompt(self): - - five_history = "" - for h in self.history[-5:]: - five_history += h['type'] + "\n" + h.get('filePath', '') + "\n\n" - - endl = "\n" - return (f"###Global Info:###{endl}" - f"Here are some info about now user's IDE, refer to it when you need to handle some code.{endl}" - f"- User's total study time is {self.get_deltatime_mmss(self.create_time, time.time())}{endl}" - f"- User's current chapter study time is {self.get_deltatime_mmss(self.enter_chapter_time, time.time())}{endl}" - f"- Activated file path: {self.active_file_path}{endl}" - f"```{endl}" - f"{self.active_file_content[-10:]}{endl}" - f"```{endl}" - f"- Last five action:{five_history}{endl}" - f"- File tree: {self.file_tree}{endl}") - # f"- Activated file content (current editing 10 lines): {endl}" - def add_history(self, realtime_action): - if(realtime_action['type']=='config'):return - if len(self.history)!=0: - if (self.history[-1]['type']=='fileEdit'): - if(self.history[-1]['filePath'] == realtime_action['filePath']): - self.history[-1]['content'] = realtime_action['content'] - return - self.history.append(realtime_action) - - - def get_deltatime_mmss(self, start_time, end_time): - elapsed_time = end_time - start_time - hours = int(elapsed_time // 3600) - minutes = int((elapsed_time % 3600) // 60) - seconds = int(elapsed_time % 60) - return f"{hours:02d}:{minutes:02d}:{seconds:02d}" - - - def get_active_file_reletive_path(self): - relative_path = os.path.relpath(self.active_file_path, self.root_path) - return relative_path - - - -class BackBoardManager: - def __init__(self): - self.backboards = {} # user_uuid: Backboard - - def add_backboard(self, user_uuid, username, course_id, lesson_id, root_path): - self.backboards[user_uuid] = Backboard(user_uuid,username, course_id, lesson_id, root_path) - - def get_backboard(self, user_uuid) -> Backboard: - return self.backboards[user_uuid] - - - diff --git a/Html/runs/run_20250911-060203_yfghxt/code/bootstrap.py b/Html/runs/run_20250911-060203_yfghxt/code/bootstrap.py deleted file mode 100644 index bcb15ce..0000000 --- a/Html/runs/run_20250911-060203_yfghxt/code/bootstrap.py +++ /dev/null @@ -1,31 +0,0 @@ -from pathlib import Path -import sys, os - -def bootstrap_paths(): - """ - 让 'AlgoriAgent'(位于 repo_root/AlgoriAgent)可被 import; - 并提供 STUDENT_WORKSPACE_ROOT 的默认值(repo_root/study)。 - 适配当前工厂位置:repo_root/Html/apps/__init__.py - """ - here = Path(__file__).resolve() - # repo_root = .../Html/apps/../../ => parents[2] - repo_root = here.parents[2] - - # 兜底:如果目录结构变化,尝试向上搜索包含 AlgoriAgent 的目录作为 repo_root - if not (repo_root / "AlgoriAgent").exists(): - for p in here.parents: - if (p / "AlgoriAgent").is_dir(): - repo_root = p - break - - # 确保仓库根在 sys.path(这样 'AlgoriAgent' 顶层包可被发现) - repo_root_str = str(repo_root) - if repo_root_str not in sys.path: - sys.path.insert(0, repo_root_str) - - # 可选:如果你还有其它顶层包,也可在此处继续插入 - - # 默认学习工作区目录(也可放到 config.ini / 环境变量覆盖) - os.environ.setdefault("STUDENT_WORKSPACE_ROOT", str(repo_root / "study")) - - return repo_root # 方便调试/日志 \ No newline at end of file diff --git a/Html/runs/run_20250911-060203_yfghxt/code/wsgi.py b/Html/runs/run_20250911-060203_yfghxt/code/wsgi.py deleted file mode 100644 index bbcbe5f..0000000 --- a/Html/runs/run_20250911-060203_yfghxt/code/wsgi.py +++ /dev/null @@ -1,6 +0,0 @@ -# wsgi.py -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -# 提供一个可被 WSGI/进程管理器导入的 app 对象 -app = create_app() diff --git a/Html/runs/run_20250911-060203_yfghxt/logging.chat b/Html/runs/run_20250911-060203_yfghxt/logging.chat deleted file mode 100644 index e69de29..0000000 diff --git a/Html/runs/run_20250911-060203_yfghxt/logging.log b/Html/runs/run_20250911-060203_yfghxt/logging.log deleted file mode 100644 index c3455da..0000000 --- a/Html/runs/run_20250911-060203_yfghxt/logging.log +++ /dev/null @@ -1 +0,0 @@ -2025-09-11 06:02:07.800 | INFO | agentscope.models:read_model_configs:186 - Load configs for model wrapper: openai_cfg diff --git a/Html/runs/run_20250911-060207_rce61h/.config b/Html/runs/run_20250911-060207_rce61h/.config deleted file mode 100644 index bb30fdb..0000000 --- a/Html/runs/run_20250911-060207_rce61h/.config +++ /dev/null @@ -1,7 +0,0 @@ -{ - "project": "kUgVXb", - "name": "rce61h", - "run_id": "run_20250911-060207_rce61h", - "timestamp": "2025-09-11 06:02:07", - "pid": 31505 -} \ No newline at end of file diff --git a/Html/runs/run_20250911-060207_rce61h/agentscope.db b/Html/runs/run_20250911-060207_rce61h/agentscope.db deleted file mode 100644 index 666055b77679cda29c14fcf23b4ef1d039c5b52a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI%L2KJE6bEoS4Q(k)+glI2yjv3-0%NB!Hs&O1YUav`W0U1F<0V=#BsNLx(sSu$ z>=W&q?4#^B$!*yt2YT5l`~^0a^z(#~{ zkyg6w!t)u0!@f%5aeaJcfD9*Q_b$ozCY8>~CFA6|{Z2V!N;Z^cIq}eS$>x3HY|^=j z7lokrf1)Z$x@_R^N~@apn7OPMkZ(I<*1WJCw@v3GWy2n6&RcIQ0~zlR_x8^$%be!% zmxb7@7V;}H+K5#l(wSbZKXKY!mys6ROyi|!%aN@+%REpi?;B-K4PC3&{>iCzQnNB+ zwbW!z4iA{x(V_2L+5VJ1vMJeN;5l68yJ9?OZyl-TNCEp4P{^H8$cTGExdq$9ANE6@ zA@`ZUhb>is+Y=S?%$C1fnN{muZU1a!nMRV%#qFbMT;y3hf|KlJ)00Izz00bZa0SG_<0uX=z1a@EGHy1PL*Z=?k diff --git a/Html/runs/run_20250911-060207_rce61h/code/app.py b/Html/runs/run_20250911-060207_rce61h/code/app.py deleted file mode 100644 index c7f31f7..0000000 --- a/Html/runs/run_20250911-060207_rce61h/code/app.py +++ /dev/null @@ -1,21 +0,0 @@ -# app.py 0.1.1 rise to factory mode -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -from apps.extensions import socketio - -# 工厂创建 app,工厂里已经做了:加载配置/注册蓝图/注册 namespaces -app = create_app() - -if __name__ == "__main__": - # 仅本地开发用;生产不要用 werkzeug 自带的开发服务器 - socketio.run( - app, - host="0.0.0.0", - port=5551, - debug=True, # 开发期打开 - allow_unsafe_werkzeug=True, # 避免 dev server 的安全限制提示 - # ssl_context=('server.crt', 'server.key') - ) - - diff --git a/Html/runs/run_20250911-060207_rce61h/code/app_back.py b/Html/runs/run_20250911-060207_rce61h/code/app_back.py deleted file mode 100644 index 246853c..0000000 --- a/Html/runs/run_20250911-060207_rce61h/code/app_back.py +++ /dev/null @@ -1,480 +0,0 @@ -from bootstrap import bootstrap_paths -bootstrap_paths() -from functools import wraps -from flask import Flask, redirect, session, request, jsonify, render_template, send_from_directory, url_for -from flask_cors import CORS -from flask_socketio import SocketIO, join_room, emit, Namespace -import markdown -import os -import uuid -import shutil -import sys -import json -from apps.auth.decorators import require_role -parent_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) -sys.path.insert(0, parent_dir) -student_workspace_root_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../study')) -current_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '.')) -sys.path.insert(0, current_dir) -from AlgoriAgent.projects.algoriAgent.agent_manager import AgentManager - - -import configparser - -from db.user_list import UserList -from db.user import User, load_user_from_json, create_user_json -from db.course_list import CourseList -from db.course import Course, load_course_from_json -GLOBAL_CONFIG = configparser.ConfigParser() -GLOBAL_CONFIG.read('config.ini') -VSCODE_WEB_URL = GLOBAL_CONFIG['VSCODE_WEB']['url'] -USER_DATA_DIR = GLOBAL_CONFIG['USER_DATA']['dir'] -COURSE_DATA_DIR = GLOBAL_CONFIG['COURSE_DATA']['dir'] - -app = Flask(__name__) -socketio = SocketIO(app, cors_allowed_origins="*",ping_timeout=60, ping_interval=5) -# socketio = SocketIO(app, cors_allowed_origins="http://localhost:9888") # 设置跨域支持 -import logging -app.secret_key = 'cakebaker' -app.logger.setLevel(logging.DEBUG) -# 配置 CORS -CORS(app, resources={r"/*": {"origins": VSCODE_WEB_URL},}, supports_credentials=True) - - -userid_recorder = {} # user_id&path -> session['user_id'] - -''' -Backboard -''' -from backboardManager import BackBoardManager, Backboard - -backboard_manager = BackBoardManager() -uuid2username = {} -username2uuid = {} - - - -# 定义命名空间:用于和 VSCode 插件交流 -class VSCodeNamespace(Namespace): - def on_login(self,data): - print("VSCode client connected") - print(data) - dataconfig = data['config'] - user_id = dataconfig.get('user_id') - path = dataconfig.get('path') - course_id = dataconfig.get('course_id') - lesson_id = dataconfig.get('chapter_id') - print(f"User {user_id} connected with path: {path}") - useruuid = username2uuid[user_id] - join_room(useruuid, namespace='/vscode') - if backboard_manager.get_backboard(useruuid) == None: - backboard_manager.add_backboard(useruuid,user_id, course_id, lesson_id, path) - - - def on_message(self, data): - print(f"Received from VSCode client: {data}") - dataconfig = data['config'] - realtime_response(dataconfig, data) - # emit('response', {'message': 'Config data received and connection established'}) - def on_disconnect(self, data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - -def realtime_response(config, realtime_action): - user_id = config['user_id'] - folder_path = config['path'] - useruuid = username2uuid[user_id] - bb = backboard_manager.get_backboard(useruuid) - assert type(bb) == Backboard - - bb.add_history(realtime_action) - - if realtime_action['type'] == 'workspaceFolders': - bb.file_tree = realtime_action['fileTree'] - - if realtime_action['type'] == 'activeFile': - file_path = realtime_action['filePath'] - assert type(file_path) == str - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - if realtime_action['type'] == 'paste': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.pasted_file_path = file_path - bb.pasted_content = realtime_action['content'] - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - if realtime_action['type'] == 'fileEdit': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - - - print("config"+str(config)) - print("realtime_action"+str(realtime_action)) - pass - - -''' -Agent and Chat -''' -agent_manager = AgentManager(app = app, socketio = socketio) -user_threads = {} -import threading -from concurrent.futures import ThreadPoolExecutor, as_completed - -# 初始化线程池 -executor = ThreadPoolExecutor(max_workers=10) -class AgentNamespace(Namespace): - def on_login(self, data): - data = json.loads(data) - user = data['username'] - course_id = data['course_id'] - chapter_id = data['chapter_id'] - user_uuid = username2uuid[user] - session['user_id'] = user_uuid - print(f'User connected with session user_id: {user_uuid}') - # 从markdown、markdown_prompts、score_prompts中各读取数据folder.md并进行new_agent - with open(f'books/markdown/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fmd,\ - open(f'books/markdown_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8')as fmdp,\ - open(f'books/score_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fsp: - markdown = fmd.read() - markdown_prompts = fmdp.read() - score_prompts = fsp.read() - user_uuid, agent = agent_manager.new_agent(course_id, chapter_id, markdown, markdown_prompts, score_prompts, id=user_uuid, - root_path=f'../../study/{user}/{course_id}/{chapter_id}') - print(user_uuid) - join_room(user_uuid, namespace='/agent') # 将该用户加入以user_id为名的room - backboard_manager.add_backboard(user_uuid, user, course_id, chapter_id, root_path=f'../../study/{user}/{course_id}/{chapter_id}') - - def on_language(self, language): - id = session.get('user_id') - agent_manager.change_language(id, language) - - def on_message(self, data): - print(f"Message from client: {data}") - id = session.get('user_id') - if (type(data)==str): - data = json.loads(data) - print(id) - if data['type'] == 'text': - res = agent_manager.invoke(id, data['data'], backboard_manager.get_backboard(id).get_info_prompt()) - print('=*='*20) - print(res.content) - reply = f"{res.content['speak']}" - with app.app_context(): - emit('message',reply, room=id, namespace='/agent') - emit('request_function',res.content['function'], room=id, namespace='/agent') - - if data['type'] == 'function': - agent_manager.function_call(id, data['data']) - - def on_initiative(self,data): - print("User active function call") - user_id = session['user_id'] - if data['name'] == 'sample_judge': - agent_manager.sample_judge(user_id, backboard_manager.get_backboard(user_id)) - if data['name'] == 'judge': - agent_manager.judge(user_id, backboard_manager.get_backboard(user_id)) - - - - def on_disconnect(self,data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - - -''' -Markdown to HTML -''' -# 配置文件路径 -MARKDOWN_DIR = 'books/markdown' # 存放 markdown 文件的文件夹 -STATIC_DIR = 'static' # 存放生成的 HTML 和图片资源的文件夹 -IMAGE_DIR = 'image' # 图片资源相对于 markdown 的位置 - - - -@app.route('/--markdown', methods=['GET']) -def convert_md(course_id, filename): - md_file_path = os.path.join(MARKDOWN_DIR,course_id, f'{filename}.md') - - if not os.path.exists(md_file_path): - return jsonify({'error': 'Markdown file not found'}), 404 - - # 读取 markdown 文件内容 - with open(md_file_path, 'r', encoding='utf-8') as file: - md_content = file.read() - - # 将 markdown 转换为 HTML - html_content = markdown.markdown(md_content) - # 插入 CSS 样式,限制图片最大宽度为 100%,高度自动调整 - html_with_styles = f""" - - - - - - - {html_content} - - - """ - # 保存 HTML 文件到 static 文件夹 - html_output_path = os.path.join(STATIC_DIR, f'{filename}.html') - with open(html_output_path, 'w', encoding='utf-8') as html_file: - html_file.write(html_with_styles) - - # 处理图片资源,将 image/xxx 文件夹拷贝到 static/image/xxx - image_source_dir = os.path.join(MARKDOWN_DIR,course_id, IMAGE_DIR, filename) - image_target_dir = os.path.join(STATIC_DIR, IMAGE_DIR, filename) - print(f"Copying image resources from {image_source_dir} to {image_target_dir}") - if os.path.exists(image_source_dir): - # 确保 static/image/xxx 目录存在 - if not os.path.exists(image_target_dir): - os.makedirs(image_target_dir) - - # 拷贝图片资源 - for image_file in os.listdir(image_source_dir): - full_image_file_path = os.path.join(image_source_dir, image_file) - if os.path.isfile(full_image_file_path): - shutil.copy(full_image_file_path, image_target_dir) - - return jsonify({'html_url': f'/static/{filename}.html'}) - -# 静态文件(HTML 和图片资源)的访问 -@app.route('/static/') -def serve_static(filename): - return send_from_directory(STATIC_DIR, filename) - - -''' -Vscode -''' -@app.route('/desktop///') -def desktop(user_id, course_id, chapter_id): - if 'user_id' not in session: - # return redirect(url_for('login')) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ user_id + "uuid is"+ session['user_id']) - username2uuid[user_id] = session['user_id'] - uuid2username[session['user_id']] = user_id - userid_recorder[user_id+'&'+course_id] = session['user_id'] - - # 在学习目录下创建一个名为 user_id_path 的文件夹 - path_dir = os.path.join(student_workspace_root_path, user_id, course_id,chapter_id) - os.makedirs(path_dir, exist_ok=True) - # 在此文件夹内部创建一个.config文件,并写入 user_id=user_id\n path=path - config_path = os.path.join(path_dir, '.config') - if GLOBAL_CONFIG['VSCODE_WEB_PATH']['is_wsl']: # 如果是在 WSL 中运行,则将路径转换为 WSL 路径 - path_dir = path_dir.replace('\\', '/') - path_dir = path_dir.replace(GLOBAL_CONFIG['VSCODE_WEB_PATH']['windows_path'] , GLOBAL_CONFIG['VSCODE_WEB_PATH']['wsl_path']) - with open(config_path, 'w', encoding='utf-8') as f: - tmpd = {'user_id': user_id, 'course_id': course_id, 'chapter_id': chapter_id, 'path': path_dir} - json.dump(tmpd, f) - print('---------------------') - print(config_path) - return render_template('desktop.html', vscode_web_url=VSCODE_WEB_URL, user_id=user_id, course_id=course_id, chapter_id=chapter_id, workspace_path=path_dir) - -@app.route('/desktop_nouser//') -def desktop_nouser(course_id, chapter_id): - if 'user_id' not in session: - return redirect(url_for('login')) - user_id = session['user_id'] - username = uuid2username[user_id] - return redirect(url_for('desktop', user_id=username, course_id=course_id, chapter_id=chapter_id)) - -@app.route('/vscode_data', methods=['POST']) -def vscode_data(): - data = request.json - config = data['config'] - realtime_response(config,data) - print(f"Received data from VSCode: {data}") - return jsonify({"status": "success", "received": data}) - - - -''' -Login - -''' -users_list = UserList() -course_list = CourseList() - - -@app.route('/register') -def register(): - return render_template('register.html') - -@app.route('/register_teacher') -def register_teacher(): - return render_template('register_teacher.html') - -@app.route('/register_teacher_post', methods=['POST']) -def register_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password, teacher=True) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - -@app.route('/register_post', methods=['POST']) -def register_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - - -@app.route('/login') -def login(): - return render_template('login.html') - if 'user_id' not in session: - return render_template('login.html') - else: - return redirect(url_for('/')) - -@app.route('/login_post', methods=['POST']) -def login_post(): - # 获取请求的 JSON 数据 - data = request.get_json() - - username = data.get('username') - password = data.get('password') - - pswd = users_list.get_user_pswd(username) - - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/login_teacher_post', methods=['POST']) -def login_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - pswd = users_list.get_user_pswd(username) - is_teacher = users_list.get_user_is_teacher(username) - if is_teacher is None or is_teacher == False: - return jsonify({'success': False, 'message': '用户名不存在或非教师账号'}) - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/teacherboard') -@require_role(roles="teacher") -def teacherboard(): - return render_template('teacherboard.html') - - -@app.route('/logout') -def logout(): - session.pop('user_id', None) - return redirect(url_for('login')) - -@app.route('/get_session') -def get_session(): - user_session = session.get('user_id', 'default_session') - return jsonify({"session": user_session}) - - -''' -DashBoard -''' -user_id2UserClass = {} -@app.route('/dashboard') -@require_role -def dashboard(): - user_id = session['user_id'] - username = uuid2username[user_id] - if (user_id not in user_id2UserClass): - user_id2UserClass[user_id] = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - user_course_data = [] - for course_id in user_id2UserClass[user_id].select_course: - course_brief_info = course_list.get_course_brief_info(course_id, load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR)) - user_course_data.append(course_brief_info) - return render_template('dashboard.html',user_data = user_id2UserClass[user_id].to_json_without_dialog(), user_course_data = json.dumps(user_course_data)) - -''' -Course -''' - -@app.route('/course/') -@require_role -def course(course_id): - c = load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR) - return render_template('course.html', course_id=course_id, course_data=c) - -@app.route('/select_course', methods=['POST']) -@require_role -def select_course(): - user = user_id2UserClass[session['user_id']] - data = request.get_json() - course_id = data.get('course_id') - if course_id: - user.select_new_course(course_id, load_course_from_json(course_id, COURSE_DATA_DIR)) - return jsonify({'success': True, 'message': '课程选择成功'}) - - -@app.route('/') -@require_role -def home_index(): - selected_courses=[] - if ('user_id' in session): - if (session['user_id'] not in user_id2UserClass): return redirect(url_for('login')) - user = user_id2UserClass[session['user_id']] - for course_id in user.select_course: - selected_courses.append(course_id) - - return render_template('index.html', courses_data = course_list, selected_courses =selected_courses) - -# 一些app辅助函数,主要提供给Agent与数据库的交互能力 - -class MyFunction: - def save_chapter_memory(self, id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal): - print("-=-=-=-=-=-=-=-") - print(id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - username = uuid2username[id] - u = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - u.save_chapter_memory(course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - -app.my_function = MyFunction() -if __name__ == '__main__': - socketio.on_namespace(VSCodeNamespace('/vscode')) - socketio.on_namespace(AgentNamespace('/agent')) - socketio.run(app, host='0.0.0.0', port=5551, debug=False,allow_unsafe_werkzeug=True) - diff --git a/Html/runs/run_20250911-060207_rce61h/code/backboardManager.py b/Html/runs/run_20250911-060207_rce61h/code/backboardManager.py deleted file mode 100644 index 7de5f19..0000000 --- a/Html/runs/run_20250911-060207_rce61h/code/backboardManager.py +++ /dev/null @@ -1,80 +0,0 @@ - - - -import time -import os - -class Backboard: - def __init__(self, user_uuid, username, course_id, lesson_id, root_path): - self.user_uuid = user_uuid - self.username = username - self.course_id = course_id - self.lesson_id = lesson_id - self.root_path = root_path - self.create_time = time.time() - self.enter_chapter_time = time.time() - self.history = [] - self.file_tree = "[]" - self.active_file_path = "" - self.active_file_content = "" - self.pasted_file_path = "" - self.pasted_content = "" - - - def next_chapter(self): - self.enter_chapter_time = time.time() - - def get_info_prompt(self): - - five_history = "" - for h in self.history[-5:]: - five_history += h['type'] + "\n" + h.get('filePath', '') + "\n\n" - - endl = "\n" - return (f"###Global Info:###{endl}" - f"Here are some info about now user's IDE, refer to it when you need to handle some code.{endl}" - f"- User's total study time is {self.get_deltatime_mmss(self.create_time, time.time())}{endl}" - f"- User's current chapter study time is {self.get_deltatime_mmss(self.enter_chapter_time, time.time())}{endl}" - f"- Activated file path: {self.active_file_path}{endl}" - f"```{endl}" - f"{self.active_file_content[-10:]}{endl}" - f"```{endl}" - f"- Last five action:{five_history}{endl}" - f"- File tree: {self.file_tree}{endl}") - # f"- Activated file content (current editing 10 lines): {endl}" - def add_history(self, realtime_action): - if(realtime_action['type']=='config'):return - if len(self.history)!=0: - if (self.history[-1]['type']=='fileEdit'): - if(self.history[-1]['filePath'] == realtime_action['filePath']): - self.history[-1]['content'] = realtime_action['content'] - return - self.history.append(realtime_action) - - - def get_deltatime_mmss(self, start_time, end_time): - elapsed_time = end_time - start_time - hours = int(elapsed_time // 3600) - minutes = int((elapsed_time % 3600) // 60) - seconds = int(elapsed_time % 60) - return f"{hours:02d}:{minutes:02d}:{seconds:02d}" - - - def get_active_file_reletive_path(self): - relative_path = os.path.relpath(self.active_file_path, self.root_path) - return relative_path - - - -class BackBoardManager: - def __init__(self): - self.backboards = {} # user_uuid: Backboard - - def add_backboard(self, user_uuid, username, course_id, lesson_id, root_path): - self.backboards[user_uuid] = Backboard(user_uuid,username, course_id, lesson_id, root_path) - - def get_backboard(self, user_uuid) -> Backboard: - return self.backboards[user_uuid] - - - diff --git a/Html/runs/run_20250911-060207_rce61h/code/bootstrap.py b/Html/runs/run_20250911-060207_rce61h/code/bootstrap.py deleted file mode 100644 index bcb15ce..0000000 --- a/Html/runs/run_20250911-060207_rce61h/code/bootstrap.py +++ /dev/null @@ -1,31 +0,0 @@ -from pathlib import Path -import sys, os - -def bootstrap_paths(): - """ - 让 'AlgoriAgent'(位于 repo_root/AlgoriAgent)可被 import; - 并提供 STUDENT_WORKSPACE_ROOT 的默认值(repo_root/study)。 - 适配当前工厂位置:repo_root/Html/apps/__init__.py - """ - here = Path(__file__).resolve() - # repo_root = .../Html/apps/../../ => parents[2] - repo_root = here.parents[2] - - # 兜底:如果目录结构变化,尝试向上搜索包含 AlgoriAgent 的目录作为 repo_root - if not (repo_root / "AlgoriAgent").exists(): - for p in here.parents: - if (p / "AlgoriAgent").is_dir(): - repo_root = p - break - - # 确保仓库根在 sys.path(这样 'AlgoriAgent' 顶层包可被发现) - repo_root_str = str(repo_root) - if repo_root_str not in sys.path: - sys.path.insert(0, repo_root_str) - - # 可选:如果你还有其它顶层包,也可在此处继续插入 - - # 默认学习工作区目录(也可放到 config.ini / 环境变量覆盖) - os.environ.setdefault("STUDENT_WORKSPACE_ROOT", str(repo_root / "study")) - - return repo_root # 方便调试/日志 \ No newline at end of file diff --git a/Html/runs/run_20250911-060207_rce61h/code/wsgi.py b/Html/runs/run_20250911-060207_rce61h/code/wsgi.py deleted file mode 100644 index bbcbe5f..0000000 --- a/Html/runs/run_20250911-060207_rce61h/code/wsgi.py +++ /dev/null @@ -1,6 +0,0 @@ -# wsgi.py -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -# 提供一个可被 WSGI/进程管理器导入的 app 对象 -app = create_app() diff --git a/Html/runs/run_20250911-060207_rce61h/logging.chat b/Html/runs/run_20250911-060207_rce61h/logging.chat deleted file mode 100644 index e69de29..0000000 diff --git a/Html/runs/run_20250911-060207_rce61h/logging.log b/Html/runs/run_20250911-060207_rce61h/logging.log deleted file mode 100644 index edd8f21..0000000 --- a/Html/runs/run_20250911-060207_rce61h/logging.log +++ /dev/null @@ -1 +0,0 @@ -2025-09-11 06:02:11.588 | INFO | agentscope.models:read_model_configs:186 - Load configs for model wrapper: openai_cfg diff --git a/Html/runs/run_20250911-060246_40ksl2/.config b/Html/runs/run_20250911-060246_40ksl2/.config deleted file mode 100644 index 0e306d3..0000000 --- a/Html/runs/run_20250911-060246_40ksl2/.config +++ /dev/null @@ -1,7 +0,0 @@ -{ - "project": "H0u7Ti", - "name": "40ksl2", - "run_id": "run_20250911-060246_40ksl2", - "timestamp": "2025-09-11 06:02:46", - "pid": 31640 -} \ No newline at end of file diff --git a/Html/runs/run_20250911-060246_40ksl2/agentscope.db b/Html/runs/run_20250911-060246_40ksl2/agentscope.db deleted file mode 100644 index 666055b77679cda29c14fcf23b4ef1d039c5b52a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI%L2KJE6bEoS4Q(k)+glI2yjv3-0%NB!Hs&O1YUav`W0U1F<0V=#BsNLx(sSu$ z>=W&q?4#^B$!*yt2YT5l`~^0a^z(#~{ zkyg6w!t)u0!@f%5aeaJcfD9*Q_b$ozCY8>~CFA6|{Z2V!N;Z^cIq}eS$>x3HY|^=j z7lokrf1)Z$x@_R^N~@apn7OPMkZ(I<*1WJCw@v3GWy2n6&RcIQ0~zlR_x8^$%be!% zmxb7@7V;}H+K5#l(wSbZKXKY!mys6ROyi|!%aN@+%REpi?;B-K4PC3&{>iCzQnNB+ zwbW!z4iA{x(V_2L+5VJ1vMJeN;5l68yJ9?OZyl-TNCEp4P{^H8$cTGExdq$9ANE6@ zA@`ZUhb>is+Y=S?%$C1fnN{muZU1a!nMRV%#qFbMT;y3hf|KlJ)00Izz00bZa0SG_<0uX=z1a@EGHy1PL*Z=?k diff --git a/Html/runs/run_20250911-060246_40ksl2/code/app.py b/Html/runs/run_20250911-060246_40ksl2/code/app.py deleted file mode 100644 index c7f31f7..0000000 --- a/Html/runs/run_20250911-060246_40ksl2/code/app.py +++ /dev/null @@ -1,21 +0,0 @@ -# app.py 0.1.1 rise to factory mode -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -from apps.extensions import socketio - -# 工厂创建 app,工厂里已经做了:加载配置/注册蓝图/注册 namespaces -app = create_app() - -if __name__ == "__main__": - # 仅本地开发用;生产不要用 werkzeug 自带的开发服务器 - socketio.run( - app, - host="0.0.0.0", - port=5551, - debug=True, # 开发期打开 - allow_unsafe_werkzeug=True, # 避免 dev server 的安全限制提示 - # ssl_context=('server.crt', 'server.key') - ) - - diff --git a/Html/runs/run_20250911-060246_40ksl2/code/app_back.py b/Html/runs/run_20250911-060246_40ksl2/code/app_back.py deleted file mode 100644 index 246853c..0000000 --- a/Html/runs/run_20250911-060246_40ksl2/code/app_back.py +++ /dev/null @@ -1,480 +0,0 @@ -from bootstrap import bootstrap_paths -bootstrap_paths() -from functools import wraps -from flask import Flask, redirect, session, request, jsonify, render_template, send_from_directory, url_for -from flask_cors import CORS -from flask_socketio import SocketIO, join_room, emit, Namespace -import markdown -import os -import uuid -import shutil -import sys -import json -from apps.auth.decorators import require_role -parent_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) -sys.path.insert(0, parent_dir) -student_workspace_root_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../study')) -current_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '.')) -sys.path.insert(0, current_dir) -from AlgoriAgent.projects.algoriAgent.agent_manager import AgentManager - - -import configparser - -from db.user_list import UserList -from db.user import User, load_user_from_json, create_user_json -from db.course_list import CourseList -from db.course import Course, load_course_from_json -GLOBAL_CONFIG = configparser.ConfigParser() -GLOBAL_CONFIG.read('config.ini') -VSCODE_WEB_URL = GLOBAL_CONFIG['VSCODE_WEB']['url'] -USER_DATA_DIR = GLOBAL_CONFIG['USER_DATA']['dir'] -COURSE_DATA_DIR = GLOBAL_CONFIG['COURSE_DATA']['dir'] - -app = Flask(__name__) -socketio = SocketIO(app, cors_allowed_origins="*",ping_timeout=60, ping_interval=5) -# socketio = SocketIO(app, cors_allowed_origins="http://localhost:9888") # 设置跨域支持 -import logging -app.secret_key = 'cakebaker' -app.logger.setLevel(logging.DEBUG) -# 配置 CORS -CORS(app, resources={r"/*": {"origins": VSCODE_WEB_URL},}, supports_credentials=True) - - -userid_recorder = {} # user_id&path -> session['user_id'] - -''' -Backboard -''' -from backboardManager import BackBoardManager, Backboard - -backboard_manager = BackBoardManager() -uuid2username = {} -username2uuid = {} - - - -# 定义命名空间:用于和 VSCode 插件交流 -class VSCodeNamespace(Namespace): - def on_login(self,data): - print("VSCode client connected") - print(data) - dataconfig = data['config'] - user_id = dataconfig.get('user_id') - path = dataconfig.get('path') - course_id = dataconfig.get('course_id') - lesson_id = dataconfig.get('chapter_id') - print(f"User {user_id} connected with path: {path}") - useruuid = username2uuid[user_id] - join_room(useruuid, namespace='/vscode') - if backboard_manager.get_backboard(useruuid) == None: - backboard_manager.add_backboard(useruuid,user_id, course_id, lesson_id, path) - - - def on_message(self, data): - print(f"Received from VSCode client: {data}") - dataconfig = data['config'] - realtime_response(dataconfig, data) - # emit('response', {'message': 'Config data received and connection established'}) - def on_disconnect(self, data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - -def realtime_response(config, realtime_action): - user_id = config['user_id'] - folder_path = config['path'] - useruuid = username2uuid[user_id] - bb = backboard_manager.get_backboard(useruuid) - assert type(bb) == Backboard - - bb.add_history(realtime_action) - - if realtime_action['type'] == 'workspaceFolders': - bb.file_tree = realtime_action['fileTree'] - - if realtime_action['type'] == 'activeFile': - file_path = realtime_action['filePath'] - assert type(file_path) == str - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - if realtime_action['type'] == 'paste': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.pasted_file_path = file_path - bb.pasted_content = realtime_action['content'] - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - if realtime_action['type'] == 'fileEdit': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - - - print("config"+str(config)) - print("realtime_action"+str(realtime_action)) - pass - - -''' -Agent and Chat -''' -agent_manager = AgentManager(app = app, socketio = socketio) -user_threads = {} -import threading -from concurrent.futures import ThreadPoolExecutor, as_completed - -# 初始化线程池 -executor = ThreadPoolExecutor(max_workers=10) -class AgentNamespace(Namespace): - def on_login(self, data): - data = json.loads(data) - user = data['username'] - course_id = data['course_id'] - chapter_id = data['chapter_id'] - user_uuid = username2uuid[user] - session['user_id'] = user_uuid - print(f'User connected with session user_id: {user_uuid}') - # 从markdown、markdown_prompts、score_prompts中各读取数据folder.md并进行new_agent - with open(f'books/markdown/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fmd,\ - open(f'books/markdown_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8')as fmdp,\ - open(f'books/score_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fsp: - markdown = fmd.read() - markdown_prompts = fmdp.read() - score_prompts = fsp.read() - user_uuid, agent = agent_manager.new_agent(course_id, chapter_id, markdown, markdown_prompts, score_prompts, id=user_uuid, - root_path=f'../../study/{user}/{course_id}/{chapter_id}') - print(user_uuid) - join_room(user_uuid, namespace='/agent') # 将该用户加入以user_id为名的room - backboard_manager.add_backboard(user_uuid, user, course_id, chapter_id, root_path=f'../../study/{user}/{course_id}/{chapter_id}') - - def on_language(self, language): - id = session.get('user_id') - agent_manager.change_language(id, language) - - def on_message(self, data): - print(f"Message from client: {data}") - id = session.get('user_id') - if (type(data)==str): - data = json.loads(data) - print(id) - if data['type'] == 'text': - res = agent_manager.invoke(id, data['data'], backboard_manager.get_backboard(id).get_info_prompt()) - print('=*='*20) - print(res.content) - reply = f"{res.content['speak']}" - with app.app_context(): - emit('message',reply, room=id, namespace='/agent') - emit('request_function',res.content['function'], room=id, namespace='/agent') - - if data['type'] == 'function': - agent_manager.function_call(id, data['data']) - - def on_initiative(self,data): - print("User active function call") - user_id = session['user_id'] - if data['name'] == 'sample_judge': - agent_manager.sample_judge(user_id, backboard_manager.get_backboard(user_id)) - if data['name'] == 'judge': - agent_manager.judge(user_id, backboard_manager.get_backboard(user_id)) - - - - def on_disconnect(self,data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - - -''' -Markdown to HTML -''' -# 配置文件路径 -MARKDOWN_DIR = 'books/markdown' # 存放 markdown 文件的文件夹 -STATIC_DIR = 'static' # 存放生成的 HTML 和图片资源的文件夹 -IMAGE_DIR = 'image' # 图片资源相对于 markdown 的位置 - - - -@app.route('/--markdown', methods=['GET']) -def convert_md(course_id, filename): - md_file_path = os.path.join(MARKDOWN_DIR,course_id, f'{filename}.md') - - if not os.path.exists(md_file_path): - return jsonify({'error': 'Markdown file not found'}), 404 - - # 读取 markdown 文件内容 - with open(md_file_path, 'r', encoding='utf-8') as file: - md_content = file.read() - - # 将 markdown 转换为 HTML - html_content = markdown.markdown(md_content) - # 插入 CSS 样式,限制图片最大宽度为 100%,高度自动调整 - html_with_styles = f""" - - - - - - - {html_content} - - - """ - # 保存 HTML 文件到 static 文件夹 - html_output_path = os.path.join(STATIC_DIR, f'{filename}.html') - with open(html_output_path, 'w', encoding='utf-8') as html_file: - html_file.write(html_with_styles) - - # 处理图片资源,将 image/xxx 文件夹拷贝到 static/image/xxx - image_source_dir = os.path.join(MARKDOWN_DIR,course_id, IMAGE_DIR, filename) - image_target_dir = os.path.join(STATIC_DIR, IMAGE_DIR, filename) - print(f"Copying image resources from {image_source_dir} to {image_target_dir}") - if os.path.exists(image_source_dir): - # 确保 static/image/xxx 目录存在 - if not os.path.exists(image_target_dir): - os.makedirs(image_target_dir) - - # 拷贝图片资源 - for image_file in os.listdir(image_source_dir): - full_image_file_path = os.path.join(image_source_dir, image_file) - if os.path.isfile(full_image_file_path): - shutil.copy(full_image_file_path, image_target_dir) - - return jsonify({'html_url': f'/static/{filename}.html'}) - -# 静态文件(HTML 和图片资源)的访问 -@app.route('/static/') -def serve_static(filename): - return send_from_directory(STATIC_DIR, filename) - - -''' -Vscode -''' -@app.route('/desktop///') -def desktop(user_id, course_id, chapter_id): - if 'user_id' not in session: - # return redirect(url_for('login')) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ user_id + "uuid is"+ session['user_id']) - username2uuid[user_id] = session['user_id'] - uuid2username[session['user_id']] = user_id - userid_recorder[user_id+'&'+course_id] = session['user_id'] - - # 在学习目录下创建一个名为 user_id_path 的文件夹 - path_dir = os.path.join(student_workspace_root_path, user_id, course_id,chapter_id) - os.makedirs(path_dir, exist_ok=True) - # 在此文件夹内部创建一个.config文件,并写入 user_id=user_id\n path=path - config_path = os.path.join(path_dir, '.config') - if GLOBAL_CONFIG['VSCODE_WEB_PATH']['is_wsl']: # 如果是在 WSL 中运行,则将路径转换为 WSL 路径 - path_dir = path_dir.replace('\\', '/') - path_dir = path_dir.replace(GLOBAL_CONFIG['VSCODE_WEB_PATH']['windows_path'] , GLOBAL_CONFIG['VSCODE_WEB_PATH']['wsl_path']) - with open(config_path, 'w', encoding='utf-8') as f: - tmpd = {'user_id': user_id, 'course_id': course_id, 'chapter_id': chapter_id, 'path': path_dir} - json.dump(tmpd, f) - print('---------------------') - print(config_path) - return render_template('desktop.html', vscode_web_url=VSCODE_WEB_URL, user_id=user_id, course_id=course_id, chapter_id=chapter_id, workspace_path=path_dir) - -@app.route('/desktop_nouser//') -def desktop_nouser(course_id, chapter_id): - if 'user_id' not in session: - return redirect(url_for('login')) - user_id = session['user_id'] - username = uuid2username[user_id] - return redirect(url_for('desktop', user_id=username, course_id=course_id, chapter_id=chapter_id)) - -@app.route('/vscode_data', methods=['POST']) -def vscode_data(): - data = request.json - config = data['config'] - realtime_response(config,data) - print(f"Received data from VSCode: {data}") - return jsonify({"status": "success", "received": data}) - - - -''' -Login - -''' -users_list = UserList() -course_list = CourseList() - - -@app.route('/register') -def register(): - return render_template('register.html') - -@app.route('/register_teacher') -def register_teacher(): - return render_template('register_teacher.html') - -@app.route('/register_teacher_post', methods=['POST']) -def register_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password, teacher=True) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - -@app.route('/register_post', methods=['POST']) -def register_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - - -@app.route('/login') -def login(): - return render_template('login.html') - if 'user_id' not in session: - return render_template('login.html') - else: - return redirect(url_for('/')) - -@app.route('/login_post', methods=['POST']) -def login_post(): - # 获取请求的 JSON 数据 - data = request.get_json() - - username = data.get('username') - password = data.get('password') - - pswd = users_list.get_user_pswd(username) - - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/login_teacher_post', methods=['POST']) -def login_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - pswd = users_list.get_user_pswd(username) - is_teacher = users_list.get_user_is_teacher(username) - if is_teacher is None or is_teacher == False: - return jsonify({'success': False, 'message': '用户名不存在或非教师账号'}) - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/teacherboard') -@require_role(roles="teacher") -def teacherboard(): - return render_template('teacherboard.html') - - -@app.route('/logout') -def logout(): - session.pop('user_id', None) - return redirect(url_for('login')) - -@app.route('/get_session') -def get_session(): - user_session = session.get('user_id', 'default_session') - return jsonify({"session": user_session}) - - -''' -DashBoard -''' -user_id2UserClass = {} -@app.route('/dashboard') -@require_role -def dashboard(): - user_id = session['user_id'] - username = uuid2username[user_id] - if (user_id not in user_id2UserClass): - user_id2UserClass[user_id] = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - user_course_data = [] - for course_id in user_id2UserClass[user_id].select_course: - course_brief_info = course_list.get_course_brief_info(course_id, load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR)) - user_course_data.append(course_brief_info) - return render_template('dashboard.html',user_data = user_id2UserClass[user_id].to_json_without_dialog(), user_course_data = json.dumps(user_course_data)) - -''' -Course -''' - -@app.route('/course/') -@require_role -def course(course_id): - c = load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR) - return render_template('course.html', course_id=course_id, course_data=c) - -@app.route('/select_course', methods=['POST']) -@require_role -def select_course(): - user = user_id2UserClass[session['user_id']] - data = request.get_json() - course_id = data.get('course_id') - if course_id: - user.select_new_course(course_id, load_course_from_json(course_id, COURSE_DATA_DIR)) - return jsonify({'success': True, 'message': '课程选择成功'}) - - -@app.route('/') -@require_role -def home_index(): - selected_courses=[] - if ('user_id' in session): - if (session['user_id'] not in user_id2UserClass): return redirect(url_for('login')) - user = user_id2UserClass[session['user_id']] - for course_id in user.select_course: - selected_courses.append(course_id) - - return render_template('index.html', courses_data = course_list, selected_courses =selected_courses) - -# 一些app辅助函数,主要提供给Agent与数据库的交互能力 - -class MyFunction: - def save_chapter_memory(self, id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal): - print("-=-=-=-=-=-=-=-") - print(id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - username = uuid2username[id] - u = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - u.save_chapter_memory(course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - -app.my_function = MyFunction() -if __name__ == '__main__': - socketio.on_namespace(VSCodeNamespace('/vscode')) - socketio.on_namespace(AgentNamespace('/agent')) - socketio.run(app, host='0.0.0.0', port=5551, debug=False,allow_unsafe_werkzeug=True) - diff --git a/Html/runs/run_20250911-060246_40ksl2/code/backboardManager.py b/Html/runs/run_20250911-060246_40ksl2/code/backboardManager.py deleted file mode 100644 index 7de5f19..0000000 --- a/Html/runs/run_20250911-060246_40ksl2/code/backboardManager.py +++ /dev/null @@ -1,80 +0,0 @@ - - - -import time -import os - -class Backboard: - def __init__(self, user_uuid, username, course_id, lesson_id, root_path): - self.user_uuid = user_uuid - self.username = username - self.course_id = course_id - self.lesson_id = lesson_id - self.root_path = root_path - self.create_time = time.time() - self.enter_chapter_time = time.time() - self.history = [] - self.file_tree = "[]" - self.active_file_path = "" - self.active_file_content = "" - self.pasted_file_path = "" - self.pasted_content = "" - - - def next_chapter(self): - self.enter_chapter_time = time.time() - - def get_info_prompt(self): - - five_history = "" - for h in self.history[-5:]: - five_history += h['type'] + "\n" + h.get('filePath', '') + "\n\n" - - endl = "\n" - return (f"###Global Info:###{endl}" - f"Here are some info about now user's IDE, refer to it when you need to handle some code.{endl}" - f"- User's total study time is {self.get_deltatime_mmss(self.create_time, time.time())}{endl}" - f"- User's current chapter study time is {self.get_deltatime_mmss(self.enter_chapter_time, time.time())}{endl}" - f"- Activated file path: {self.active_file_path}{endl}" - f"```{endl}" - f"{self.active_file_content[-10:]}{endl}" - f"```{endl}" - f"- Last five action:{five_history}{endl}" - f"- File tree: {self.file_tree}{endl}") - # f"- Activated file content (current editing 10 lines): {endl}" - def add_history(self, realtime_action): - if(realtime_action['type']=='config'):return - if len(self.history)!=0: - if (self.history[-1]['type']=='fileEdit'): - if(self.history[-1]['filePath'] == realtime_action['filePath']): - self.history[-1]['content'] = realtime_action['content'] - return - self.history.append(realtime_action) - - - def get_deltatime_mmss(self, start_time, end_time): - elapsed_time = end_time - start_time - hours = int(elapsed_time // 3600) - minutes = int((elapsed_time % 3600) // 60) - seconds = int(elapsed_time % 60) - return f"{hours:02d}:{minutes:02d}:{seconds:02d}" - - - def get_active_file_reletive_path(self): - relative_path = os.path.relpath(self.active_file_path, self.root_path) - return relative_path - - - -class BackBoardManager: - def __init__(self): - self.backboards = {} # user_uuid: Backboard - - def add_backboard(self, user_uuid, username, course_id, lesson_id, root_path): - self.backboards[user_uuid] = Backboard(user_uuid,username, course_id, lesson_id, root_path) - - def get_backboard(self, user_uuid) -> Backboard: - return self.backboards[user_uuid] - - - diff --git a/Html/runs/run_20250911-060246_40ksl2/code/bootstrap.py b/Html/runs/run_20250911-060246_40ksl2/code/bootstrap.py deleted file mode 100644 index bcb15ce..0000000 --- a/Html/runs/run_20250911-060246_40ksl2/code/bootstrap.py +++ /dev/null @@ -1,31 +0,0 @@ -from pathlib import Path -import sys, os - -def bootstrap_paths(): - """ - 让 'AlgoriAgent'(位于 repo_root/AlgoriAgent)可被 import; - 并提供 STUDENT_WORKSPACE_ROOT 的默认值(repo_root/study)。 - 适配当前工厂位置:repo_root/Html/apps/__init__.py - """ - here = Path(__file__).resolve() - # repo_root = .../Html/apps/../../ => parents[2] - repo_root = here.parents[2] - - # 兜底:如果目录结构变化,尝试向上搜索包含 AlgoriAgent 的目录作为 repo_root - if not (repo_root / "AlgoriAgent").exists(): - for p in here.parents: - if (p / "AlgoriAgent").is_dir(): - repo_root = p - break - - # 确保仓库根在 sys.path(这样 'AlgoriAgent' 顶层包可被发现) - repo_root_str = str(repo_root) - if repo_root_str not in sys.path: - sys.path.insert(0, repo_root_str) - - # 可选:如果你还有其它顶层包,也可在此处继续插入 - - # 默认学习工作区目录(也可放到 config.ini / 环境变量覆盖) - os.environ.setdefault("STUDENT_WORKSPACE_ROOT", str(repo_root / "study")) - - return repo_root # 方便调试/日志 \ No newline at end of file diff --git a/Html/runs/run_20250911-060246_40ksl2/code/wsgi.py b/Html/runs/run_20250911-060246_40ksl2/code/wsgi.py deleted file mode 100644 index bbcbe5f..0000000 --- a/Html/runs/run_20250911-060246_40ksl2/code/wsgi.py +++ /dev/null @@ -1,6 +0,0 @@ -# wsgi.py -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -# 提供一个可被 WSGI/进程管理器导入的 app 对象 -app = create_app() diff --git a/Html/runs/run_20250911-060246_40ksl2/logging.chat b/Html/runs/run_20250911-060246_40ksl2/logging.chat deleted file mode 100644 index e69de29..0000000 diff --git a/Html/runs/run_20250911-060246_40ksl2/logging.log b/Html/runs/run_20250911-060246_40ksl2/logging.log deleted file mode 100644 index 584ebe7..0000000 --- a/Html/runs/run_20250911-060246_40ksl2/logging.log +++ /dev/null @@ -1 +0,0 @@ -2025-09-11 06:02:50.778 | INFO | agentscope.models:read_model_configs:186 - Load configs for model wrapper: openai_cfg diff --git a/Html/runs/run_20250911-060318_ec1mwg/.config b/Html/runs/run_20250911-060318_ec1mwg/.config deleted file mode 100644 index de038dd..0000000 --- a/Html/runs/run_20250911-060318_ec1mwg/.config +++ /dev/null @@ -1,7 +0,0 @@ -{ - "project": "YF3OfE", - "name": "ec1mwg", - "run_id": "run_20250911-060318_ec1mwg", - "timestamp": "2025-09-11 06:03:18", - "pid": 31680 -} \ No newline at end of file diff --git a/Html/runs/run_20250911-060318_ec1mwg/agentscope.db b/Html/runs/run_20250911-060318_ec1mwg/agentscope.db deleted file mode 100644 index 666055b77679cda29c14fcf23b4ef1d039c5b52a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI%L2KJE6bEoS4Q(k)+glI2yjv3-0%NB!Hs&O1YUav`W0U1F<0V=#BsNLx(sSu$ z>=W&q?4#^B$!*yt2YT5l`~^0a^z(#~{ zkyg6w!t)u0!@f%5aeaJcfD9*Q_b$ozCY8>~CFA6|{Z2V!N;Z^cIq}eS$>x3HY|^=j z7lokrf1)Z$x@_R^N~@apn7OPMkZ(I<*1WJCw@v3GWy2n6&RcIQ0~zlR_x8^$%be!% zmxb7@7V;}H+K5#l(wSbZKXKY!mys6ROyi|!%aN@+%REpi?;B-K4PC3&{>iCzQnNB+ zwbW!z4iA{x(V_2L+5VJ1vMJeN;5l68yJ9?OZyl-TNCEp4P{^H8$cTGExdq$9ANE6@ zA@`ZUhb>is+Y=S?%$C1fnN{muZU1a!nMRV%#qFbMT;y3hf|KlJ)00Izz00bZa0SG_<0uX=z1a@EGHy1PL*Z=?k diff --git a/Html/runs/run_20250911-060318_ec1mwg/code/app.py b/Html/runs/run_20250911-060318_ec1mwg/code/app.py deleted file mode 100644 index c7f31f7..0000000 --- a/Html/runs/run_20250911-060318_ec1mwg/code/app.py +++ /dev/null @@ -1,21 +0,0 @@ -# app.py 0.1.1 rise to factory mode -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -from apps.extensions import socketio - -# 工厂创建 app,工厂里已经做了:加载配置/注册蓝图/注册 namespaces -app = create_app() - -if __name__ == "__main__": - # 仅本地开发用;生产不要用 werkzeug 自带的开发服务器 - socketio.run( - app, - host="0.0.0.0", - port=5551, - debug=True, # 开发期打开 - allow_unsafe_werkzeug=True, # 避免 dev server 的安全限制提示 - # ssl_context=('server.crt', 'server.key') - ) - - diff --git a/Html/runs/run_20250911-060318_ec1mwg/code/app_back.py b/Html/runs/run_20250911-060318_ec1mwg/code/app_back.py deleted file mode 100644 index 246853c..0000000 --- a/Html/runs/run_20250911-060318_ec1mwg/code/app_back.py +++ /dev/null @@ -1,480 +0,0 @@ -from bootstrap import bootstrap_paths -bootstrap_paths() -from functools import wraps -from flask import Flask, redirect, session, request, jsonify, render_template, send_from_directory, url_for -from flask_cors import CORS -from flask_socketio import SocketIO, join_room, emit, Namespace -import markdown -import os -import uuid -import shutil -import sys -import json -from apps.auth.decorators import require_role -parent_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) -sys.path.insert(0, parent_dir) -student_workspace_root_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../study')) -current_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '.')) -sys.path.insert(0, current_dir) -from AlgoriAgent.projects.algoriAgent.agent_manager import AgentManager - - -import configparser - -from db.user_list import UserList -from db.user import User, load_user_from_json, create_user_json -from db.course_list import CourseList -from db.course import Course, load_course_from_json -GLOBAL_CONFIG = configparser.ConfigParser() -GLOBAL_CONFIG.read('config.ini') -VSCODE_WEB_URL = GLOBAL_CONFIG['VSCODE_WEB']['url'] -USER_DATA_DIR = GLOBAL_CONFIG['USER_DATA']['dir'] -COURSE_DATA_DIR = GLOBAL_CONFIG['COURSE_DATA']['dir'] - -app = Flask(__name__) -socketio = SocketIO(app, cors_allowed_origins="*",ping_timeout=60, ping_interval=5) -# socketio = SocketIO(app, cors_allowed_origins="http://localhost:9888") # 设置跨域支持 -import logging -app.secret_key = 'cakebaker' -app.logger.setLevel(logging.DEBUG) -# 配置 CORS -CORS(app, resources={r"/*": {"origins": VSCODE_WEB_URL},}, supports_credentials=True) - - -userid_recorder = {} # user_id&path -> session['user_id'] - -''' -Backboard -''' -from backboardManager import BackBoardManager, Backboard - -backboard_manager = BackBoardManager() -uuid2username = {} -username2uuid = {} - - - -# 定义命名空间:用于和 VSCode 插件交流 -class VSCodeNamespace(Namespace): - def on_login(self,data): - print("VSCode client connected") - print(data) - dataconfig = data['config'] - user_id = dataconfig.get('user_id') - path = dataconfig.get('path') - course_id = dataconfig.get('course_id') - lesson_id = dataconfig.get('chapter_id') - print(f"User {user_id} connected with path: {path}") - useruuid = username2uuid[user_id] - join_room(useruuid, namespace='/vscode') - if backboard_manager.get_backboard(useruuid) == None: - backboard_manager.add_backboard(useruuid,user_id, course_id, lesson_id, path) - - - def on_message(self, data): - print(f"Received from VSCode client: {data}") - dataconfig = data['config'] - realtime_response(dataconfig, data) - # emit('response', {'message': 'Config data received and connection established'}) - def on_disconnect(self, data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - -def realtime_response(config, realtime_action): - user_id = config['user_id'] - folder_path = config['path'] - useruuid = username2uuid[user_id] - bb = backboard_manager.get_backboard(useruuid) - assert type(bb) == Backboard - - bb.add_history(realtime_action) - - if realtime_action['type'] == 'workspaceFolders': - bb.file_tree = realtime_action['fileTree'] - - if realtime_action['type'] == 'activeFile': - file_path = realtime_action['filePath'] - assert type(file_path) == str - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - if realtime_action['type'] == 'paste': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.pasted_file_path = file_path - bb.pasted_content = realtime_action['content'] - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - if realtime_action['type'] == 'fileEdit': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - - - print("config"+str(config)) - print("realtime_action"+str(realtime_action)) - pass - - -''' -Agent and Chat -''' -agent_manager = AgentManager(app = app, socketio = socketio) -user_threads = {} -import threading -from concurrent.futures import ThreadPoolExecutor, as_completed - -# 初始化线程池 -executor = ThreadPoolExecutor(max_workers=10) -class AgentNamespace(Namespace): - def on_login(self, data): - data = json.loads(data) - user = data['username'] - course_id = data['course_id'] - chapter_id = data['chapter_id'] - user_uuid = username2uuid[user] - session['user_id'] = user_uuid - print(f'User connected with session user_id: {user_uuid}') - # 从markdown、markdown_prompts、score_prompts中各读取数据folder.md并进行new_agent - with open(f'books/markdown/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fmd,\ - open(f'books/markdown_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8')as fmdp,\ - open(f'books/score_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fsp: - markdown = fmd.read() - markdown_prompts = fmdp.read() - score_prompts = fsp.read() - user_uuid, agent = agent_manager.new_agent(course_id, chapter_id, markdown, markdown_prompts, score_prompts, id=user_uuid, - root_path=f'../../study/{user}/{course_id}/{chapter_id}') - print(user_uuid) - join_room(user_uuid, namespace='/agent') # 将该用户加入以user_id为名的room - backboard_manager.add_backboard(user_uuid, user, course_id, chapter_id, root_path=f'../../study/{user}/{course_id}/{chapter_id}') - - def on_language(self, language): - id = session.get('user_id') - agent_manager.change_language(id, language) - - def on_message(self, data): - print(f"Message from client: {data}") - id = session.get('user_id') - if (type(data)==str): - data = json.loads(data) - print(id) - if data['type'] == 'text': - res = agent_manager.invoke(id, data['data'], backboard_manager.get_backboard(id).get_info_prompt()) - print('=*='*20) - print(res.content) - reply = f"{res.content['speak']}" - with app.app_context(): - emit('message',reply, room=id, namespace='/agent') - emit('request_function',res.content['function'], room=id, namespace='/agent') - - if data['type'] == 'function': - agent_manager.function_call(id, data['data']) - - def on_initiative(self,data): - print("User active function call") - user_id = session['user_id'] - if data['name'] == 'sample_judge': - agent_manager.sample_judge(user_id, backboard_manager.get_backboard(user_id)) - if data['name'] == 'judge': - agent_manager.judge(user_id, backboard_manager.get_backboard(user_id)) - - - - def on_disconnect(self,data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - - -''' -Markdown to HTML -''' -# 配置文件路径 -MARKDOWN_DIR = 'books/markdown' # 存放 markdown 文件的文件夹 -STATIC_DIR = 'static' # 存放生成的 HTML 和图片资源的文件夹 -IMAGE_DIR = 'image' # 图片资源相对于 markdown 的位置 - - - -@app.route('/--markdown', methods=['GET']) -def convert_md(course_id, filename): - md_file_path = os.path.join(MARKDOWN_DIR,course_id, f'{filename}.md') - - if not os.path.exists(md_file_path): - return jsonify({'error': 'Markdown file not found'}), 404 - - # 读取 markdown 文件内容 - with open(md_file_path, 'r', encoding='utf-8') as file: - md_content = file.read() - - # 将 markdown 转换为 HTML - html_content = markdown.markdown(md_content) - # 插入 CSS 样式,限制图片最大宽度为 100%,高度自动调整 - html_with_styles = f""" - - - - - - - {html_content} - - - """ - # 保存 HTML 文件到 static 文件夹 - html_output_path = os.path.join(STATIC_DIR, f'{filename}.html') - with open(html_output_path, 'w', encoding='utf-8') as html_file: - html_file.write(html_with_styles) - - # 处理图片资源,将 image/xxx 文件夹拷贝到 static/image/xxx - image_source_dir = os.path.join(MARKDOWN_DIR,course_id, IMAGE_DIR, filename) - image_target_dir = os.path.join(STATIC_DIR, IMAGE_DIR, filename) - print(f"Copying image resources from {image_source_dir} to {image_target_dir}") - if os.path.exists(image_source_dir): - # 确保 static/image/xxx 目录存在 - if not os.path.exists(image_target_dir): - os.makedirs(image_target_dir) - - # 拷贝图片资源 - for image_file in os.listdir(image_source_dir): - full_image_file_path = os.path.join(image_source_dir, image_file) - if os.path.isfile(full_image_file_path): - shutil.copy(full_image_file_path, image_target_dir) - - return jsonify({'html_url': f'/static/{filename}.html'}) - -# 静态文件(HTML 和图片资源)的访问 -@app.route('/static/') -def serve_static(filename): - return send_from_directory(STATIC_DIR, filename) - - -''' -Vscode -''' -@app.route('/desktop///') -def desktop(user_id, course_id, chapter_id): - if 'user_id' not in session: - # return redirect(url_for('login')) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ user_id + "uuid is"+ session['user_id']) - username2uuid[user_id] = session['user_id'] - uuid2username[session['user_id']] = user_id - userid_recorder[user_id+'&'+course_id] = session['user_id'] - - # 在学习目录下创建一个名为 user_id_path 的文件夹 - path_dir = os.path.join(student_workspace_root_path, user_id, course_id,chapter_id) - os.makedirs(path_dir, exist_ok=True) - # 在此文件夹内部创建一个.config文件,并写入 user_id=user_id\n path=path - config_path = os.path.join(path_dir, '.config') - if GLOBAL_CONFIG['VSCODE_WEB_PATH']['is_wsl']: # 如果是在 WSL 中运行,则将路径转换为 WSL 路径 - path_dir = path_dir.replace('\\', '/') - path_dir = path_dir.replace(GLOBAL_CONFIG['VSCODE_WEB_PATH']['windows_path'] , GLOBAL_CONFIG['VSCODE_WEB_PATH']['wsl_path']) - with open(config_path, 'w', encoding='utf-8') as f: - tmpd = {'user_id': user_id, 'course_id': course_id, 'chapter_id': chapter_id, 'path': path_dir} - json.dump(tmpd, f) - print('---------------------') - print(config_path) - return render_template('desktop.html', vscode_web_url=VSCODE_WEB_URL, user_id=user_id, course_id=course_id, chapter_id=chapter_id, workspace_path=path_dir) - -@app.route('/desktop_nouser//') -def desktop_nouser(course_id, chapter_id): - if 'user_id' not in session: - return redirect(url_for('login')) - user_id = session['user_id'] - username = uuid2username[user_id] - return redirect(url_for('desktop', user_id=username, course_id=course_id, chapter_id=chapter_id)) - -@app.route('/vscode_data', methods=['POST']) -def vscode_data(): - data = request.json - config = data['config'] - realtime_response(config,data) - print(f"Received data from VSCode: {data}") - return jsonify({"status": "success", "received": data}) - - - -''' -Login - -''' -users_list = UserList() -course_list = CourseList() - - -@app.route('/register') -def register(): - return render_template('register.html') - -@app.route('/register_teacher') -def register_teacher(): - return render_template('register_teacher.html') - -@app.route('/register_teacher_post', methods=['POST']) -def register_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password, teacher=True) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - -@app.route('/register_post', methods=['POST']) -def register_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - - -@app.route('/login') -def login(): - return render_template('login.html') - if 'user_id' not in session: - return render_template('login.html') - else: - return redirect(url_for('/')) - -@app.route('/login_post', methods=['POST']) -def login_post(): - # 获取请求的 JSON 数据 - data = request.get_json() - - username = data.get('username') - password = data.get('password') - - pswd = users_list.get_user_pswd(username) - - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/login_teacher_post', methods=['POST']) -def login_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - pswd = users_list.get_user_pswd(username) - is_teacher = users_list.get_user_is_teacher(username) - if is_teacher is None or is_teacher == False: - return jsonify({'success': False, 'message': '用户名不存在或非教师账号'}) - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/teacherboard') -@require_role(roles="teacher") -def teacherboard(): - return render_template('teacherboard.html') - - -@app.route('/logout') -def logout(): - session.pop('user_id', None) - return redirect(url_for('login')) - -@app.route('/get_session') -def get_session(): - user_session = session.get('user_id', 'default_session') - return jsonify({"session": user_session}) - - -''' -DashBoard -''' -user_id2UserClass = {} -@app.route('/dashboard') -@require_role -def dashboard(): - user_id = session['user_id'] - username = uuid2username[user_id] - if (user_id not in user_id2UserClass): - user_id2UserClass[user_id] = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - user_course_data = [] - for course_id in user_id2UserClass[user_id].select_course: - course_brief_info = course_list.get_course_brief_info(course_id, load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR)) - user_course_data.append(course_brief_info) - return render_template('dashboard.html',user_data = user_id2UserClass[user_id].to_json_without_dialog(), user_course_data = json.dumps(user_course_data)) - -''' -Course -''' - -@app.route('/course/') -@require_role -def course(course_id): - c = load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR) - return render_template('course.html', course_id=course_id, course_data=c) - -@app.route('/select_course', methods=['POST']) -@require_role -def select_course(): - user = user_id2UserClass[session['user_id']] - data = request.get_json() - course_id = data.get('course_id') - if course_id: - user.select_new_course(course_id, load_course_from_json(course_id, COURSE_DATA_DIR)) - return jsonify({'success': True, 'message': '课程选择成功'}) - - -@app.route('/') -@require_role -def home_index(): - selected_courses=[] - if ('user_id' in session): - if (session['user_id'] not in user_id2UserClass): return redirect(url_for('login')) - user = user_id2UserClass[session['user_id']] - for course_id in user.select_course: - selected_courses.append(course_id) - - return render_template('index.html', courses_data = course_list, selected_courses =selected_courses) - -# 一些app辅助函数,主要提供给Agent与数据库的交互能力 - -class MyFunction: - def save_chapter_memory(self, id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal): - print("-=-=-=-=-=-=-=-") - print(id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - username = uuid2username[id] - u = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - u.save_chapter_memory(course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - -app.my_function = MyFunction() -if __name__ == '__main__': - socketio.on_namespace(VSCodeNamespace('/vscode')) - socketio.on_namespace(AgentNamespace('/agent')) - socketio.run(app, host='0.0.0.0', port=5551, debug=False,allow_unsafe_werkzeug=True) - diff --git a/Html/runs/run_20250911-060318_ec1mwg/code/backboardManager.py b/Html/runs/run_20250911-060318_ec1mwg/code/backboardManager.py deleted file mode 100644 index 7de5f19..0000000 --- a/Html/runs/run_20250911-060318_ec1mwg/code/backboardManager.py +++ /dev/null @@ -1,80 +0,0 @@ - - - -import time -import os - -class Backboard: - def __init__(self, user_uuid, username, course_id, lesson_id, root_path): - self.user_uuid = user_uuid - self.username = username - self.course_id = course_id - self.lesson_id = lesson_id - self.root_path = root_path - self.create_time = time.time() - self.enter_chapter_time = time.time() - self.history = [] - self.file_tree = "[]" - self.active_file_path = "" - self.active_file_content = "" - self.pasted_file_path = "" - self.pasted_content = "" - - - def next_chapter(self): - self.enter_chapter_time = time.time() - - def get_info_prompt(self): - - five_history = "" - for h in self.history[-5:]: - five_history += h['type'] + "\n" + h.get('filePath', '') + "\n\n" - - endl = "\n" - return (f"###Global Info:###{endl}" - f"Here are some info about now user's IDE, refer to it when you need to handle some code.{endl}" - f"- User's total study time is {self.get_deltatime_mmss(self.create_time, time.time())}{endl}" - f"- User's current chapter study time is {self.get_deltatime_mmss(self.enter_chapter_time, time.time())}{endl}" - f"- Activated file path: {self.active_file_path}{endl}" - f"```{endl}" - f"{self.active_file_content[-10:]}{endl}" - f"```{endl}" - f"- Last five action:{five_history}{endl}" - f"- File tree: {self.file_tree}{endl}") - # f"- Activated file content (current editing 10 lines): {endl}" - def add_history(self, realtime_action): - if(realtime_action['type']=='config'):return - if len(self.history)!=0: - if (self.history[-1]['type']=='fileEdit'): - if(self.history[-1]['filePath'] == realtime_action['filePath']): - self.history[-1]['content'] = realtime_action['content'] - return - self.history.append(realtime_action) - - - def get_deltatime_mmss(self, start_time, end_time): - elapsed_time = end_time - start_time - hours = int(elapsed_time // 3600) - minutes = int((elapsed_time % 3600) // 60) - seconds = int(elapsed_time % 60) - return f"{hours:02d}:{minutes:02d}:{seconds:02d}" - - - def get_active_file_reletive_path(self): - relative_path = os.path.relpath(self.active_file_path, self.root_path) - return relative_path - - - -class BackBoardManager: - def __init__(self): - self.backboards = {} # user_uuid: Backboard - - def add_backboard(self, user_uuid, username, course_id, lesson_id, root_path): - self.backboards[user_uuid] = Backboard(user_uuid,username, course_id, lesson_id, root_path) - - def get_backboard(self, user_uuid) -> Backboard: - return self.backboards[user_uuid] - - - diff --git a/Html/runs/run_20250911-060318_ec1mwg/code/bootstrap.py b/Html/runs/run_20250911-060318_ec1mwg/code/bootstrap.py deleted file mode 100644 index bcb15ce..0000000 --- a/Html/runs/run_20250911-060318_ec1mwg/code/bootstrap.py +++ /dev/null @@ -1,31 +0,0 @@ -from pathlib import Path -import sys, os - -def bootstrap_paths(): - """ - 让 'AlgoriAgent'(位于 repo_root/AlgoriAgent)可被 import; - 并提供 STUDENT_WORKSPACE_ROOT 的默认值(repo_root/study)。 - 适配当前工厂位置:repo_root/Html/apps/__init__.py - """ - here = Path(__file__).resolve() - # repo_root = .../Html/apps/../../ => parents[2] - repo_root = here.parents[2] - - # 兜底:如果目录结构变化,尝试向上搜索包含 AlgoriAgent 的目录作为 repo_root - if not (repo_root / "AlgoriAgent").exists(): - for p in here.parents: - if (p / "AlgoriAgent").is_dir(): - repo_root = p - break - - # 确保仓库根在 sys.path(这样 'AlgoriAgent' 顶层包可被发现) - repo_root_str = str(repo_root) - if repo_root_str not in sys.path: - sys.path.insert(0, repo_root_str) - - # 可选:如果你还有其它顶层包,也可在此处继续插入 - - # 默认学习工作区目录(也可放到 config.ini / 环境变量覆盖) - os.environ.setdefault("STUDENT_WORKSPACE_ROOT", str(repo_root / "study")) - - return repo_root # 方便调试/日志 \ No newline at end of file diff --git a/Html/runs/run_20250911-060318_ec1mwg/code/wsgi.py b/Html/runs/run_20250911-060318_ec1mwg/code/wsgi.py deleted file mode 100644 index bbcbe5f..0000000 --- a/Html/runs/run_20250911-060318_ec1mwg/code/wsgi.py +++ /dev/null @@ -1,6 +0,0 @@ -# wsgi.py -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -# 提供一个可被 WSGI/进程管理器导入的 app 对象 -app = create_app() diff --git a/Html/runs/run_20250911-060318_ec1mwg/logging.chat b/Html/runs/run_20250911-060318_ec1mwg/logging.chat deleted file mode 100644 index e69de29..0000000 diff --git a/Html/runs/run_20250911-060318_ec1mwg/logging.log b/Html/runs/run_20250911-060318_ec1mwg/logging.log deleted file mode 100644 index 0b0e011..0000000 --- a/Html/runs/run_20250911-060318_ec1mwg/logging.log +++ /dev/null @@ -1 +0,0 @@ -2025-09-11 06:03:22.442 | INFO | agentscope.models:read_model_configs:186 - Load configs for model wrapper: openai_cfg diff --git a/Html/runs/run_20250911-060514_w6745q/.config b/Html/runs/run_20250911-060514_w6745q/.config deleted file mode 100644 index 3bef57f..0000000 --- a/Html/runs/run_20250911-060514_w6745q/.config +++ /dev/null @@ -1,7 +0,0 @@ -{ - "project": "oBdhre", - "name": "w6745q", - "run_id": "run_20250911-060514_w6745q", - "timestamp": "2025-09-11 06:05:14", - "pid": 31981 -} \ No newline at end of file diff --git a/Html/runs/run_20250911-060514_w6745q/agentscope.db b/Html/runs/run_20250911-060514_w6745q/agentscope.db deleted file mode 100644 index 666055b77679cda29c14fcf23b4ef1d039c5b52a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI%L2KJE6bEoS4Q(k)+glI2yjv3-0%NB!Hs&O1YUav`W0U1F<0V=#BsNLx(sSu$ z>=W&q?4#^B$!*yt2YT5l`~^0a^z(#~{ zkyg6w!t)u0!@f%5aeaJcfD9*Q_b$ozCY8>~CFA6|{Z2V!N;Z^cIq}eS$>x3HY|^=j z7lokrf1)Z$x@_R^N~@apn7OPMkZ(I<*1WJCw@v3GWy2n6&RcIQ0~zlR_x8^$%be!% zmxb7@7V;}H+K5#l(wSbZKXKY!mys6ROyi|!%aN@+%REpi?;B-K4PC3&{>iCzQnNB+ zwbW!z4iA{x(V_2L+5VJ1vMJeN;5l68yJ9?OZyl-TNCEp4P{^H8$cTGExdq$9ANE6@ zA@`ZUhb>is+Y=S?%$C1fnN{muZU1a!nMRV%#qFbMT;y3hf|KlJ)00Izz00bZa0SG_<0uX=z1a@EGHy1PL*Z=?k diff --git a/Html/runs/run_20250911-060514_w6745q/code/app.py b/Html/runs/run_20250911-060514_w6745q/code/app.py deleted file mode 100644 index c7f31f7..0000000 --- a/Html/runs/run_20250911-060514_w6745q/code/app.py +++ /dev/null @@ -1,21 +0,0 @@ -# app.py 0.1.1 rise to factory mode -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -from apps.extensions import socketio - -# 工厂创建 app,工厂里已经做了:加载配置/注册蓝图/注册 namespaces -app = create_app() - -if __name__ == "__main__": - # 仅本地开发用;生产不要用 werkzeug 自带的开发服务器 - socketio.run( - app, - host="0.0.0.0", - port=5551, - debug=True, # 开发期打开 - allow_unsafe_werkzeug=True, # 避免 dev server 的安全限制提示 - # ssl_context=('server.crt', 'server.key') - ) - - diff --git a/Html/runs/run_20250911-060514_w6745q/code/app_back.py b/Html/runs/run_20250911-060514_w6745q/code/app_back.py deleted file mode 100644 index 246853c..0000000 --- a/Html/runs/run_20250911-060514_w6745q/code/app_back.py +++ /dev/null @@ -1,480 +0,0 @@ -from bootstrap import bootstrap_paths -bootstrap_paths() -from functools import wraps -from flask import Flask, redirect, session, request, jsonify, render_template, send_from_directory, url_for -from flask_cors import CORS -from flask_socketio import SocketIO, join_room, emit, Namespace -import markdown -import os -import uuid -import shutil -import sys -import json -from apps.auth.decorators import require_role -parent_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) -sys.path.insert(0, parent_dir) -student_workspace_root_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../study')) -current_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '.')) -sys.path.insert(0, current_dir) -from AlgoriAgent.projects.algoriAgent.agent_manager import AgentManager - - -import configparser - -from db.user_list import UserList -from db.user import User, load_user_from_json, create_user_json -from db.course_list import CourseList -from db.course import Course, load_course_from_json -GLOBAL_CONFIG = configparser.ConfigParser() -GLOBAL_CONFIG.read('config.ini') -VSCODE_WEB_URL = GLOBAL_CONFIG['VSCODE_WEB']['url'] -USER_DATA_DIR = GLOBAL_CONFIG['USER_DATA']['dir'] -COURSE_DATA_DIR = GLOBAL_CONFIG['COURSE_DATA']['dir'] - -app = Flask(__name__) -socketio = SocketIO(app, cors_allowed_origins="*",ping_timeout=60, ping_interval=5) -# socketio = SocketIO(app, cors_allowed_origins="http://localhost:9888") # 设置跨域支持 -import logging -app.secret_key = 'cakebaker' -app.logger.setLevel(logging.DEBUG) -# 配置 CORS -CORS(app, resources={r"/*": {"origins": VSCODE_WEB_URL},}, supports_credentials=True) - - -userid_recorder = {} # user_id&path -> session['user_id'] - -''' -Backboard -''' -from backboardManager import BackBoardManager, Backboard - -backboard_manager = BackBoardManager() -uuid2username = {} -username2uuid = {} - - - -# 定义命名空间:用于和 VSCode 插件交流 -class VSCodeNamespace(Namespace): - def on_login(self,data): - print("VSCode client connected") - print(data) - dataconfig = data['config'] - user_id = dataconfig.get('user_id') - path = dataconfig.get('path') - course_id = dataconfig.get('course_id') - lesson_id = dataconfig.get('chapter_id') - print(f"User {user_id} connected with path: {path}") - useruuid = username2uuid[user_id] - join_room(useruuid, namespace='/vscode') - if backboard_manager.get_backboard(useruuid) == None: - backboard_manager.add_backboard(useruuid,user_id, course_id, lesson_id, path) - - - def on_message(self, data): - print(f"Received from VSCode client: {data}") - dataconfig = data['config'] - realtime_response(dataconfig, data) - # emit('response', {'message': 'Config data received and connection established'}) - def on_disconnect(self, data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - -def realtime_response(config, realtime_action): - user_id = config['user_id'] - folder_path = config['path'] - useruuid = username2uuid[user_id] - bb = backboard_manager.get_backboard(useruuid) - assert type(bb) == Backboard - - bb.add_history(realtime_action) - - if realtime_action['type'] == 'workspaceFolders': - bb.file_tree = realtime_action['fileTree'] - - if realtime_action['type'] == 'activeFile': - file_path = realtime_action['filePath'] - assert type(file_path) == str - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - if realtime_action['type'] == 'paste': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.pasted_file_path = file_path - bb.pasted_content = realtime_action['content'] - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - if realtime_action['type'] == 'fileEdit': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - - - print("config"+str(config)) - print("realtime_action"+str(realtime_action)) - pass - - -''' -Agent and Chat -''' -agent_manager = AgentManager(app = app, socketio = socketio) -user_threads = {} -import threading -from concurrent.futures import ThreadPoolExecutor, as_completed - -# 初始化线程池 -executor = ThreadPoolExecutor(max_workers=10) -class AgentNamespace(Namespace): - def on_login(self, data): - data = json.loads(data) - user = data['username'] - course_id = data['course_id'] - chapter_id = data['chapter_id'] - user_uuid = username2uuid[user] - session['user_id'] = user_uuid - print(f'User connected with session user_id: {user_uuid}') - # 从markdown、markdown_prompts、score_prompts中各读取数据folder.md并进行new_agent - with open(f'books/markdown/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fmd,\ - open(f'books/markdown_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8')as fmdp,\ - open(f'books/score_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fsp: - markdown = fmd.read() - markdown_prompts = fmdp.read() - score_prompts = fsp.read() - user_uuid, agent = agent_manager.new_agent(course_id, chapter_id, markdown, markdown_prompts, score_prompts, id=user_uuid, - root_path=f'../../study/{user}/{course_id}/{chapter_id}') - print(user_uuid) - join_room(user_uuid, namespace='/agent') # 将该用户加入以user_id为名的room - backboard_manager.add_backboard(user_uuid, user, course_id, chapter_id, root_path=f'../../study/{user}/{course_id}/{chapter_id}') - - def on_language(self, language): - id = session.get('user_id') - agent_manager.change_language(id, language) - - def on_message(self, data): - print(f"Message from client: {data}") - id = session.get('user_id') - if (type(data)==str): - data = json.loads(data) - print(id) - if data['type'] == 'text': - res = agent_manager.invoke(id, data['data'], backboard_manager.get_backboard(id).get_info_prompt()) - print('=*='*20) - print(res.content) - reply = f"{res.content['speak']}" - with app.app_context(): - emit('message',reply, room=id, namespace='/agent') - emit('request_function',res.content['function'], room=id, namespace='/agent') - - if data['type'] == 'function': - agent_manager.function_call(id, data['data']) - - def on_initiative(self,data): - print("User active function call") - user_id = session['user_id'] - if data['name'] == 'sample_judge': - agent_manager.sample_judge(user_id, backboard_manager.get_backboard(user_id)) - if data['name'] == 'judge': - agent_manager.judge(user_id, backboard_manager.get_backboard(user_id)) - - - - def on_disconnect(self,data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - - -''' -Markdown to HTML -''' -# 配置文件路径 -MARKDOWN_DIR = 'books/markdown' # 存放 markdown 文件的文件夹 -STATIC_DIR = 'static' # 存放生成的 HTML 和图片资源的文件夹 -IMAGE_DIR = 'image' # 图片资源相对于 markdown 的位置 - - - -@app.route('/--markdown', methods=['GET']) -def convert_md(course_id, filename): - md_file_path = os.path.join(MARKDOWN_DIR,course_id, f'{filename}.md') - - if not os.path.exists(md_file_path): - return jsonify({'error': 'Markdown file not found'}), 404 - - # 读取 markdown 文件内容 - with open(md_file_path, 'r', encoding='utf-8') as file: - md_content = file.read() - - # 将 markdown 转换为 HTML - html_content = markdown.markdown(md_content) - # 插入 CSS 样式,限制图片最大宽度为 100%,高度自动调整 - html_with_styles = f""" - - - - - - - {html_content} - - - """ - # 保存 HTML 文件到 static 文件夹 - html_output_path = os.path.join(STATIC_DIR, f'{filename}.html') - with open(html_output_path, 'w', encoding='utf-8') as html_file: - html_file.write(html_with_styles) - - # 处理图片资源,将 image/xxx 文件夹拷贝到 static/image/xxx - image_source_dir = os.path.join(MARKDOWN_DIR,course_id, IMAGE_DIR, filename) - image_target_dir = os.path.join(STATIC_DIR, IMAGE_DIR, filename) - print(f"Copying image resources from {image_source_dir} to {image_target_dir}") - if os.path.exists(image_source_dir): - # 确保 static/image/xxx 目录存在 - if not os.path.exists(image_target_dir): - os.makedirs(image_target_dir) - - # 拷贝图片资源 - for image_file in os.listdir(image_source_dir): - full_image_file_path = os.path.join(image_source_dir, image_file) - if os.path.isfile(full_image_file_path): - shutil.copy(full_image_file_path, image_target_dir) - - return jsonify({'html_url': f'/static/{filename}.html'}) - -# 静态文件(HTML 和图片资源)的访问 -@app.route('/static/') -def serve_static(filename): - return send_from_directory(STATIC_DIR, filename) - - -''' -Vscode -''' -@app.route('/desktop///') -def desktop(user_id, course_id, chapter_id): - if 'user_id' not in session: - # return redirect(url_for('login')) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ user_id + "uuid is"+ session['user_id']) - username2uuid[user_id] = session['user_id'] - uuid2username[session['user_id']] = user_id - userid_recorder[user_id+'&'+course_id] = session['user_id'] - - # 在学习目录下创建一个名为 user_id_path 的文件夹 - path_dir = os.path.join(student_workspace_root_path, user_id, course_id,chapter_id) - os.makedirs(path_dir, exist_ok=True) - # 在此文件夹内部创建一个.config文件,并写入 user_id=user_id\n path=path - config_path = os.path.join(path_dir, '.config') - if GLOBAL_CONFIG['VSCODE_WEB_PATH']['is_wsl']: # 如果是在 WSL 中运行,则将路径转换为 WSL 路径 - path_dir = path_dir.replace('\\', '/') - path_dir = path_dir.replace(GLOBAL_CONFIG['VSCODE_WEB_PATH']['windows_path'] , GLOBAL_CONFIG['VSCODE_WEB_PATH']['wsl_path']) - with open(config_path, 'w', encoding='utf-8') as f: - tmpd = {'user_id': user_id, 'course_id': course_id, 'chapter_id': chapter_id, 'path': path_dir} - json.dump(tmpd, f) - print('---------------------') - print(config_path) - return render_template('desktop.html', vscode_web_url=VSCODE_WEB_URL, user_id=user_id, course_id=course_id, chapter_id=chapter_id, workspace_path=path_dir) - -@app.route('/desktop_nouser//') -def desktop_nouser(course_id, chapter_id): - if 'user_id' not in session: - return redirect(url_for('login')) - user_id = session['user_id'] - username = uuid2username[user_id] - return redirect(url_for('desktop', user_id=username, course_id=course_id, chapter_id=chapter_id)) - -@app.route('/vscode_data', methods=['POST']) -def vscode_data(): - data = request.json - config = data['config'] - realtime_response(config,data) - print(f"Received data from VSCode: {data}") - return jsonify({"status": "success", "received": data}) - - - -''' -Login - -''' -users_list = UserList() -course_list = CourseList() - - -@app.route('/register') -def register(): - return render_template('register.html') - -@app.route('/register_teacher') -def register_teacher(): - return render_template('register_teacher.html') - -@app.route('/register_teacher_post', methods=['POST']) -def register_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password, teacher=True) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - -@app.route('/register_post', methods=['POST']) -def register_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - - -@app.route('/login') -def login(): - return render_template('login.html') - if 'user_id' not in session: - return render_template('login.html') - else: - return redirect(url_for('/')) - -@app.route('/login_post', methods=['POST']) -def login_post(): - # 获取请求的 JSON 数据 - data = request.get_json() - - username = data.get('username') - password = data.get('password') - - pswd = users_list.get_user_pswd(username) - - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/login_teacher_post', methods=['POST']) -def login_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - pswd = users_list.get_user_pswd(username) - is_teacher = users_list.get_user_is_teacher(username) - if is_teacher is None or is_teacher == False: - return jsonify({'success': False, 'message': '用户名不存在或非教师账号'}) - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/teacherboard') -@require_role(roles="teacher") -def teacherboard(): - return render_template('teacherboard.html') - - -@app.route('/logout') -def logout(): - session.pop('user_id', None) - return redirect(url_for('login')) - -@app.route('/get_session') -def get_session(): - user_session = session.get('user_id', 'default_session') - return jsonify({"session": user_session}) - - -''' -DashBoard -''' -user_id2UserClass = {} -@app.route('/dashboard') -@require_role -def dashboard(): - user_id = session['user_id'] - username = uuid2username[user_id] - if (user_id not in user_id2UserClass): - user_id2UserClass[user_id] = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - user_course_data = [] - for course_id in user_id2UserClass[user_id].select_course: - course_brief_info = course_list.get_course_brief_info(course_id, load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR)) - user_course_data.append(course_brief_info) - return render_template('dashboard.html',user_data = user_id2UserClass[user_id].to_json_without_dialog(), user_course_data = json.dumps(user_course_data)) - -''' -Course -''' - -@app.route('/course/') -@require_role -def course(course_id): - c = load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR) - return render_template('course.html', course_id=course_id, course_data=c) - -@app.route('/select_course', methods=['POST']) -@require_role -def select_course(): - user = user_id2UserClass[session['user_id']] - data = request.get_json() - course_id = data.get('course_id') - if course_id: - user.select_new_course(course_id, load_course_from_json(course_id, COURSE_DATA_DIR)) - return jsonify({'success': True, 'message': '课程选择成功'}) - - -@app.route('/') -@require_role -def home_index(): - selected_courses=[] - if ('user_id' in session): - if (session['user_id'] not in user_id2UserClass): return redirect(url_for('login')) - user = user_id2UserClass[session['user_id']] - for course_id in user.select_course: - selected_courses.append(course_id) - - return render_template('index.html', courses_data = course_list, selected_courses =selected_courses) - -# 一些app辅助函数,主要提供给Agent与数据库的交互能力 - -class MyFunction: - def save_chapter_memory(self, id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal): - print("-=-=-=-=-=-=-=-") - print(id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - username = uuid2username[id] - u = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - u.save_chapter_memory(course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - -app.my_function = MyFunction() -if __name__ == '__main__': - socketio.on_namespace(VSCodeNamespace('/vscode')) - socketio.on_namespace(AgentNamespace('/agent')) - socketio.run(app, host='0.0.0.0', port=5551, debug=False,allow_unsafe_werkzeug=True) - diff --git a/Html/runs/run_20250911-060514_w6745q/code/backboardManager.py b/Html/runs/run_20250911-060514_w6745q/code/backboardManager.py deleted file mode 100644 index 7de5f19..0000000 --- a/Html/runs/run_20250911-060514_w6745q/code/backboardManager.py +++ /dev/null @@ -1,80 +0,0 @@ - - - -import time -import os - -class Backboard: - def __init__(self, user_uuid, username, course_id, lesson_id, root_path): - self.user_uuid = user_uuid - self.username = username - self.course_id = course_id - self.lesson_id = lesson_id - self.root_path = root_path - self.create_time = time.time() - self.enter_chapter_time = time.time() - self.history = [] - self.file_tree = "[]" - self.active_file_path = "" - self.active_file_content = "" - self.pasted_file_path = "" - self.pasted_content = "" - - - def next_chapter(self): - self.enter_chapter_time = time.time() - - def get_info_prompt(self): - - five_history = "" - for h in self.history[-5:]: - five_history += h['type'] + "\n" + h.get('filePath', '') + "\n\n" - - endl = "\n" - return (f"###Global Info:###{endl}" - f"Here are some info about now user's IDE, refer to it when you need to handle some code.{endl}" - f"- User's total study time is {self.get_deltatime_mmss(self.create_time, time.time())}{endl}" - f"- User's current chapter study time is {self.get_deltatime_mmss(self.enter_chapter_time, time.time())}{endl}" - f"- Activated file path: {self.active_file_path}{endl}" - f"```{endl}" - f"{self.active_file_content[-10:]}{endl}" - f"```{endl}" - f"- Last five action:{five_history}{endl}" - f"- File tree: {self.file_tree}{endl}") - # f"- Activated file content (current editing 10 lines): {endl}" - def add_history(self, realtime_action): - if(realtime_action['type']=='config'):return - if len(self.history)!=0: - if (self.history[-1]['type']=='fileEdit'): - if(self.history[-1]['filePath'] == realtime_action['filePath']): - self.history[-1]['content'] = realtime_action['content'] - return - self.history.append(realtime_action) - - - def get_deltatime_mmss(self, start_time, end_time): - elapsed_time = end_time - start_time - hours = int(elapsed_time // 3600) - minutes = int((elapsed_time % 3600) // 60) - seconds = int(elapsed_time % 60) - return f"{hours:02d}:{minutes:02d}:{seconds:02d}" - - - def get_active_file_reletive_path(self): - relative_path = os.path.relpath(self.active_file_path, self.root_path) - return relative_path - - - -class BackBoardManager: - def __init__(self): - self.backboards = {} # user_uuid: Backboard - - def add_backboard(self, user_uuid, username, course_id, lesson_id, root_path): - self.backboards[user_uuid] = Backboard(user_uuid,username, course_id, lesson_id, root_path) - - def get_backboard(self, user_uuid) -> Backboard: - return self.backboards[user_uuid] - - - diff --git a/Html/runs/run_20250911-060514_w6745q/code/bootstrap.py b/Html/runs/run_20250911-060514_w6745q/code/bootstrap.py deleted file mode 100644 index bcb15ce..0000000 --- a/Html/runs/run_20250911-060514_w6745q/code/bootstrap.py +++ /dev/null @@ -1,31 +0,0 @@ -from pathlib import Path -import sys, os - -def bootstrap_paths(): - """ - 让 'AlgoriAgent'(位于 repo_root/AlgoriAgent)可被 import; - 并提供 STUDENT_WORKSPACE_ROOT 的默认值(repo_root/study)。 - 适配当前工厂位置:repo_root/Html/apps/__init__.py - """ - here = Path(__file__).resolve() - # repo_root = .../Html/apps/../../ => parents[2] - repo_root = here.parents[2] - - # 兜底:如果目录结构变化,尝试向上搜索包含 AlgoriAgent 的目录作为 repo_root - if not (repo_root / "AlgoriAgent").exists(): - for p in here.parents: - if (p / "AlgoriAgent").is_dir(): - repo_root = p - break - - # 确保仓库根在 sys.path(这样 'AlgoriAgent' 顶层包可被发现) - repo_root_str = str(repo_root) - if repo_root_str not in sys.path: - sys.path.insert(0, repo_root_str) - - # 可选:如果你还有其它顶层包,也可在此处继续插入 - - # 默认学习工作区目录(也可放到 config.ini / 环境变量覆盖) - os.environ.setdefault("STUDENT_WORKSPACE_ROOT", str(repo_root / "study")) - - return repo_root # 方便调试/日志 \ No newline at end of file diff --git a/Html/runs/run_20250911-060514_w6745q/code/wsgi.py b/Html/runs/run_20250911-060514_w6745q/code/wsgi.py deleted file mode 100644 index bbcbe5f..0000000 --- a/Html/runs/run_20250911-060514_w6745q/code/wsgi.py +++ /dev/null @@ -1,6 +0,0 @@ -# wsgi.py -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -# 提供一个可被 WSGI/进程管理器导入的 app 对象 -app = create_app() diff --git a/Html/runs/run_20250911-060514_w6745q/logging.chat b/Html/runs/run_20250911-060514_w6745q/logging.chat deleted file mode 100644 index e69de29..0000000 diff --git a/Html/runs/run_20250911-060514_w6745q/logging.log b/Html/runs/run_20250911-060514_w6745q/logging.log deleted file mode 100644 index ca01c6c..0000000 --- a/Html/runs/run_20250911-060514_w6745q/logging.log +++ /dev/null @@ -1 +0,0 @@ -2025-09-11 06:05:18.576 | INFO | agentscope.models:read_model_configs:186 - Load configs for model wrapper: openai_cfg diff --git a/Html/runs/run_20250911-060518_fd3vqd/.config b/Html/runs/run_20250911-060518_fd3vqd/.config deleted file mode 100644 index 056f8c8..0000000 --- a/Html/runs/run_20250911-060518_fd3vqd/.config +++ /dev/null @@ -1,7 +0,0 @@ -{ - "project": "07lbwx", - "name": "fd3vqd", - "run_id": "run_20250911-060518_fd3vqd", - "timestamp": "2025-09-11 06:05:18", - "pid": 32015 -} \ No newline at end of file diff --git a/Html/runs/run_20250911-060518_fd3vqd/agentscope.db b/Html/runs/run_20250911-060518_fd3vqd/agentscope.db deleted file mode 100644 index 666055b77679cda29c14fcf23b4ef1d039c5b52a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI%L2KJE6bEoS4Q(k)+glI2yjv3-0%NB!Hs&O1YUav`W0U1F<0V=#BsNLx(sSu$ z>=W&q?4#^B$!*yt2YT5l`~^0a^z(#~{ zkyg6w!t)u0!@f%5aeaJcfD9*Q_b$ozCY8>~CFA6|{Z2V!N;Z^cIq}eS$>x3HY|^=j z7lokrf1)Z$x@_R^N~@apn7OPMkZ(I<*1WJCw@v3GWy2n6&RcIQ0~zlR_x8^$%be!% zmxb7@7V;}H+K5#l(wSbZKXKY!mys6ROyi|!%aN@+%REpi?;B-K4PC3&{>iCzQnNB+ zwbW!z4iA{x(V_2L+5VJ1vMJeN;5l68yJ9?OZyl-TNCEp4P{^H8$cTGExdq$9ANE6@ zA@`ZUhb>is+Y=S?%$C1fnN{muZU1a!nMRV%#qFbMT;y3hf|KlJ)00Izz00bZa0SG_<0uX=z1a@EGHy1PL*Z=?k diff --git a/Html/runs/run_20250911-060518_fd3vqd/code/app.py b/Html/runs/run_20250911-060518_fd3vqd/code/app.py deleted file mode 100644 index c7f31f7..0000000 --- a/Html/runs/run_20250911-060518_fd3vqd/code/app.py +++ /dev/null @@ -1,21 +0,0 @@ -# app.py 0.1.1 rise to factory mode -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -from apps.extensions import socketio - -# 工厂创建 app,工厂里已经做了:加载配置/注册蓝图/注册 namespaces -app = create_app() - -if __name__ == "__main__": - # 仅本地开发用;生产不要用 werkzeug 自带的开发服务器 - socketio.run( - app, - host="0.0.0.0", - port=5551, - debug=True, # 开发期打开 - allow_unsafe_werkzeug=True, # 避免 dev server 的安全限制提示 - # ssl_context=('server.crt', 'server.key') - ) - - diff --git a/Html/runs/run_20250911-060518_fd3vqd/code/app_back.py b/Html/runs/run_20250911-060518_fd3vqd/code/app_back.py deleted file mode 100644 index 246853c..0000000 --- a/Html/runs/run_20250911-060518_fd3vqd/code/app_back.py +++ /dev/null @@ -1,480 +0,0 @@ -from bootstrap import bootstrap_paths -bootstrap_paths() -from functools import wraps -from flask import Flask, redirect, session, request, jsonify, render_template, send_from_directory, url_for -from flask_cors import CORS -from flask_socketio import SocketIO, join_room, emit, Namespace -import markdown -import os -import uuid -import shutil -import sys -import json -from apps.auth.decorators import require_role -parent_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) -sys.path.insert(0, parent_dir) -student_workspace_root_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../study')) -current_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '.')) -sys.path.insert(0, current_dir) -from AlgoriAgent.projects.algoriAgent.agent_manager import AgentManager - - -import configparser - -from db.user_list import UserList -from db.user import User, load_user_from_json, create_user_json -from db.course_list import CourseList -from db.course import Course, load_course_from_json -GLOBAL_CONFIG = configparser.ConfigParser() -GLOBAL_CONFIG.read('config.ini') -VSCODE_WEB_URL = GLOBAL_CONFIG['VSCODE_WEB']['url'] -USER_DATA_DIR = GLOBAL_CONFIG['USER_DATA']['dir'] -COURSE_DATA_DIR = GLOBAL_CONFIG['COURSE_DATA']['dir'] - -app = Flask(__name__) -socketio = SocketIO(app, cors_allowed_origins="*",ping_timeout=60, ping_interval=5) -# socketio = SocketIO(app, cors_allowed_origins="http://localhost:9888") # 设置跨域支持 -import logging -app.secret_key = 'cakebaker' -app.logger.setLevel(logging.DEBUG) -# 配置 CORS -CORS(app, resources={r"/*": {"origins": VSCODE_WEB_URL},}, supports_credentials=True) - - -userid_recorder = {} # user_id&path -> session['user_id'] - -''' -Backboard -''' -from backboardManager import BackBoardManager, Backboard - -backboard_manager = BackBoardManager() -uuid2username = {} -username2uuid = {} - - - -# 定义命名空间:用于和 VSCode 插件交流 -class VSCodeNamespace(Namespace): - def on_login(self,data): - print("VSCode client connected") - print(data) - dataconfig = data['config'] - user_id = dataconfig.get('user_id') - path = dataconfig.get('path') - course_id = dataconfig.get('course_id') - lesson_id = dataconfig.get('chapter_id') - print(f"User {user_id} connected with path: {path}") - useruuid = username2uuid[user_id] - join_room(useruuid, namespace='/vscode') - if backboard_manager.get_backboard(useruuid) == None: - backboard_manager.add_backboard(useruuid,user_id, course_id, lesson_id, path) - - - def on_message(self, data): - print(f"Received from VSCode client: {data}") - dataconfig = data['config'] - realtime_response(dataconfig, data) - # emit('response', {'message': 'Config data received and connection established'}) - def on_disconnect(self, data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - -def realtime_response(config, realtime_action): - user_id = config['user_id'] - folder_path = config['path'] - useruuid = username2uuid[user_id] - bb = backboard_manager.get_backboard(useruuid) - assert type(bb) == Backboard - - bb.add_history(realtime_action) - - if realtime_action['type'] == 'workspaceFolders': - bb.file_tree = realtime_action['fileTree'] - - if realtime_action['type'] == 'activeFile': - file_path = realtime_action['filePath'] - assert type(file_path) == str - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - if realtime_action['type'] == 'paste': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.pasted_file_path = file_path - bb.pasted_content = realtime_action['content'] - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - if realtime_action['type'] == 'fileEdit': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - - - print("config"+str(config)) - print("realtime_action"+str(realtime_action)) - pass - - -''' -Agent and Chat -''' -agent_manager = AgentManager(app = app, socketio = socketio) -user_threads = {} -import threading -from concurrent.futures import ThreadPoolExecutor, as_completed - -# 初始化线程池 -executor = ThreadPoolExecutor(max_workers=10) -class AgentNamespace(Namespace): - def on_login(self, data): - data = json.loads(data) - user = data['username'] - course_id = data['course_id'] - chapter_id = data['chapter_id'] - user_uuid = username2uuid[user] - session['user_id'] = user_uuid - print(f'User connected with session user_id: {user_uuid}') - # 从markdown、markdown_prompts、score_prompts中各读取数据folder.md并进行new_agent - with open(f'books/markdown/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fmd,\ - open(f'books/markdown_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8')as fmdp,\ - open(f'books/score_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fsp: - markdown = fmd.read() - markdown_prompts = fmdp.read() - score_prompts = fsp.read() - user_uuid, agent = agent_manager.new_agent(course_id, chapter_id, markdown, markdown_prompts, score_prompts, id=user_uuid, - root_path=f'../../study/{user}/{course_id}/{chapter_id}') - print(user_uuid) - join_room(user_uuid, namespace='/agent') # 将该用户加入以user_id为名的room - backboard_manager.add_backboard(user_uuid, user, course_id, chapter_id, root_path=f'../../study/{user}/{course_id}/{chapter_id}') - - def on_language(self, language): - id = session.get('user_id') - agent_manager.change_language(id, language) - - def on_message(self, data): - print(f"Message from client: {data}") - id = session.get('user_id') - if (type(data)==str): - data = json.loads(data) - print(id) - if data['type'] == 'text': - res = agent_manager.invoke(id, data['data'], backboard_manager.get_backboard(id).get_info_prompt()) - print('=*='*20) - print(res.content) - reply = f"{res.content['speak']}" - with app.app_context(): - emit('message',reply, room=id, namespace='/agent') - emit('request_function',res.content['function'], room=id, namespace='/agent') - - if data['type'] == 'function': - agent_manager.function_call(id, data['data']) - - def on_initiative(self,data): - print("User active function call") - user_id = session['user_id'] - if data['name'] == 'sample_judge': - agent_manager.sample_judge(user_id, backboard_manager.get_backboard(user_id)) - if data['name'] == 'judge': - agent_manager.judge(user_id, backboard_manager.get_backboard(user_id)) - - - - def on_disconnect(self,data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - - -''' -Markdown to HTML -''' -# 配置文件路径 -MARKDOWN_DIR = 'books/markdown' # 存放 markdown 文件的文件夹 -STATIC_DIR = 'static' # 存放生成的 HTML 和图片资源的文件夹 -IMAGE_DIR = 'image' # 图片资源相对于 markdown 的位置 - - - -@app.route('/--markdown', methods=['GET']) -def convert_md(course_id, filename): - md_file_path = os.path.join(MARKDOWN_DIR,course_id, f'{filename}.md') - - if not os.path.exists(md_file_path): - return jsonify({'error': 'Markdown file not found'}), 404 - - # 读取 markdown 文件内容 - with open(md_file_path, 'r', encoding='utf-8') as file: - md_content = file.read() - - # 将 markdown 转换为 HTML - html_content = markdown.markdown(md_content) - # 插入 CSS 样式,限制图片最大宽度为 100%,高度自动调整 - html_with_styles = f""" - - - - - - - {html_content} - - - """ - # 保存 HTML 文件到 static 文件夹 - html_output_path = os.path.join(STATIC_DIR, f'{filename}.html') - with open(html_output_path, 'w', encoding='utf-8') as html_file: - html_file.write(html_with_styles) - - # 处理图片资源,将 image/xxx 文件夹拷贝到 static/image/xxx - image_source_dir = os.path.join(MARKDOWN_DIR,course_id, IMAGE_DIR, filename) - image_target_dir = os.path.join(STATIC_DIR, IMAGE_DIR, filename) - print(f"Copying image resources from {image_source_dir} to {image_target_dir}") - if os.path.exists(image_source_dir): - # 确保 static/image/xxx 目录存在 - if not os.path.exists(image_target_dir): - os.makedirs(image_target_dir) - - # 拷贝图片资源 - for image_file in os.listdir(image_source_dir): - full_image_file_path = os.path.join(image_source_dir, image_file) - if os.path.isfile(full_image_file_path): - shutil.copy(full_image_file_path, image_target_dir) - - return jsonify({'html_url': f'/static/{filename}.html'}) - -# 静态文件(HTML 和图片资源)的访问 -@app.route('/static/') -def serve_static(filename): - return send_from_directory(STATIC_DIR, filename) - - -''' -Vscode -''' -@app.route('/desktop///') -def desktop(user_id, course_id, chapter_id): - if 'user_id' not in session: - # return redirect(url_for('login')) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ user_id + "uuid is"+ session['user_id']) - username2uuid[user_id] = session['user_id'] - uuid2username[session['user_id']] = user_id - userid_recorder[user_id+'&'+course_id] = session['user_id'] - - # 在学习目录下创建一个名为 user_id_path 的文件夹 - path_dir = os.path.join(student_workspace_root_path, user_id, course_id,chapter_id) - os.makedirs(path_dir, exist_ok=True) - # 在此文件夹内部创建一个.config文件,并写入 user_id=user_id\n path=path - config_path = os.path.join(path_dir, '.config') - if GLOBAL_CONFIG['VSCODE_WEB_PATH']['is_wsl']: # 如果是在 WSL 中运行,则将路径转换为 WSL 路径 - path_dir = path_dir.replace('\\', '/') - path_dir = path_dir.replace(GLOBAL_CONFIG['VSCODE_WEB_PATH']['windows_path'] , GLOBAL_CONFIG['VSCODE_WEB_PATH']['wsl_path']) - with open(config_path, 'w', encoding='utf-8') as f: - tmpd = {'user_id': user_id, 'course_id': course_id, 'chapter_id': chapter_id, 'path': path_dir} - json.dump(tmpd, f) - print('---------------------') - print(config_path) - return render_template('desktop.html', vscode_web_url=VSCODE_WEB_URL, user_id=user_id, course_id=course_id, chapter_id=chapter_id, workspace_path=path_dir) - -@app.route('/desktop_nouser//') -def desktop_nouser(course_id, chapter_id): - if 'user_id' not in session: - return redirect(url_for('login')) - user_id = session['user_id'] - username = uuid2username[user_id] - return redirect(url_for('desktop', user_id=username, course_id=course_id, chapter_id=chapter_id)) - -@app.route('/vscode_data', methods=['POST']) -def vscode_data(): - data = request.json - config = data['config'] - realtime_response(config,data) - print(f"Received data from VSCode: {data}") - return jsonify({"status": "success", "received": data}) - - - -''' -Login - -''' -users_list = UserList() -course_list = CourseList() - - -@app.route('/register') -def register(): - return render_template('register.html') - -@app.route('/register_teacher') -def register_teacher(): - return render_template('register_teacher.html') - -@app.route('/register_teacher_post', methods=['POST']) -def register_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password, teacher=True) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - -@app.route('/register_post', methods=['POST']) -def register_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - - -@app.route('/login') -def login(): - return render_template('login.html') - if 'user_id' not in session: - return render_template('login.html') - else: - return redirect(url_for('/')) - -@app.route('/login_post', methods=['POST']) -def login_post(): - # 获取请求的 JSON 数据 - data = request.get_json() - - username = data.get('username') - password = data.get('password') - - pswd = users_list.get_user_pswd(username) - - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/login_teacher_post', methods=['POST']) -def login_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - pswd = users_list.get_user_pswd(username) - is_teacher = users_list.get_user_is_teacher(username) - if is_teacher is None or is_teacher == False: - return jsonify({'success': False, 'message': '用户名不存在或非教师账号'}) - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/teacherboard') -@require_role(roles="teacher") -def teacherboard(): - return render_template('teacherboard.html') - - -@app.route('/logout') -def logout(): - session.pop('user_id', None) - return redirect(url_for('login')) - -@app.route('/get_session') -def get_session(): - user_session = session.get('user_id', 'default_session') - return jsonify({"session": user_session}) - - -''' -DashBoard -''' -user_id2UserClass = {} -@app.route('/dashboard') -@require_role -def dashboard(): - user_id = session['user_id'] - username = uuid2username[user_id] - if (user_id not in user_id2UserClass): - user_id2UserClass[user_id] = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - user_course_data = [] - for course_id in user_id2UserClass[user_id].select_course: - course_brief_info = course_list.get_course_brief_info(course_id, load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR)) - user_course_data.append(course_brief_info) - return render_template('dashboard.html',user_data = user_id2UserClass[user_id].to_json_without_dialog(), user_course_data = json.dumps(user_course_data)) - -''' -Course -''' - -@app.route('/course/') -@require_role -def course(course_id): - c = load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR) - return render_template('course.html', course_id=course_id, course_data=c) - -@app.route('/select_course', methods=['POST']) -@require_role -def select_course(): - user = user_id2UserClass[session['user_id']] - data = request.get_json() - course_id = data.get('course_id') - if course_id: - user.select_new_course(course_id, load_course_from_json(course_id, COURSE_DATA_DIR)) - return jsonify({'success': True, 'message': '课程选择成功'}) - - -@app.route('/') -@require_role -def home_index(): - selected_courses=[] - if ('user_id' in session): - if (session['user_id'] not in user_id2UserClass): return redirect(url_for('login')) - user = user_id2UserClass[session['user_id']] - for course_id in user.select_course: - selected_courses.append(course_id) - - return render_template('index.html', courses_data = course_list, selected_courses =selected_courses) - -# 一些app辅助函数,主要提供给Agent与数据库的交互能力 - -class MyFunction: - def save_chapter_memory(self, id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal): - print("-=-=-=-=-=-=-=-") - print(id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - username = uuid2username[id] - u = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - u.save_chapter_memory(course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - -app.my_function = MyFunction() -if __name__ == '__main__': - socketio.on_namespace(VSCodeNamespace('/vscode')) - socketio.on_namespace(AgentNamespace('/agent')) - socketio.run(app, host='0.0.0.0', port=5551, debug=False,allow_unsafe_werkzeug=True) - diff --git a/Html/runs/run_20250911-060518_fd3vqd/code/backboardManager.py b/Html/runs/run_20250911-060518_fd3vqd/code/backboardManager.py deleted file mode 100644 index 7de5f19..0000000 --- a/Html/runs/run_20250911-060518_fd3vqd/code/backboardManager.py +++ /dev/null @@ -1,80 +0,0 @@ - - - -import time -import os - -class Backboard: - def __init__(self, user_uuid, username, course_id, lesson_id, root_path): - self.user_uuid = user_uuid - self.username = username - self.course_id = course_id - self.lesson_id = lesson_id - self.root_path = root_path - self.create_time = time.time() - self.enter_chapter_time = time.time() - self.history = [] - self.file_tree = "[]" - self.active_file_path = "" - self.active_file_content = "" - self.pasted_file_path = "" - self.pasted_content = "" - - - def next_chapter(self): - self.enter_chapter_time = time.time() - - def get_info_prompt(self): - - five_history = "" - for h in self.history[-5:]: - five_history += h['type'] + "\n" + h.get('filePath', '') + "\n\n" - - endl = "\n" - return (f"###Global Info:###{endl}" - f"Here are some info about now user's IDE, refer to it when you need to handle some code.{endl}" - f"- User's total study time is {self.get_deltatime_mmss(self.create_time, time.time())}{endl}" - f"- User's current chapter study time is {self.get_deltatime_mmss(self.enter_chapter_time, time.time())}{endl}" - f"- Activated file path: {self.active_file_path}{endl}" - f"```{endl}" - f"{self.active_file_content[-10:]}{endl}" - f"```{endl}" - f"- Last five action:{five_history}{endl}" - f"- File tree: {self.file_tree}{endl}") - # f"- Activated file content (current editing 10 lines): {endl}" - def add_history(self, realtime_action): - if(realtime_action['type']=='config'):return - if len(self.history)!=0: - if (self.history[-1]['type']=='fileEdit'): - if(self.history[-1]['filePath'] == realtime_action['filePath']): - self.history[-1]['content'] = realtime_action['content'] - return - self.history.append(realtime_action) - - - def get_deltatime_mmss(self, start_time, end_time): - elapsed_time = end_time - start_time - hours = int(elapsed_time // 3600) - minutes = int((elapsed_time % 3600) // 60) - seconds = int(elapsed_time % 60) - return f"{hours:02d}:{minutes:02d}:{seconds:02d}" - - - def get_active_file_reletive_path(self): - relative_path = os.path.relpath(self.active_file_path, self.root_path) - return relative_path - - - -class BackBoardManager: - def __init__(self): - self.backboards = {} # user_uuid: Backboard - - def add_backboard(self, user_uuid, username, course_id, lesson_id, root_path): - self.backboards[user_uuid] = Backboard(user_uuid,username, course_id, lesson_id, root_path) - - def get_backboard(self, user_uuid) -> Backboard: - return self.backboards[user_uuid] - - - diff --git a/Html/runs/run_20250911-060518_fd3vqd/code/bootstrap.py b/Html/runs/run_20250911-060518_fd3vqd/code/bootstrap.py deleted file mode 100644 index bcb15ce..0000000 --- a/Html/runs/run_20250911-060518_fd3vqd/code/bootstrap.py +++ /dev/null @@ -1,31 +0,0 @@ -from pathlib import Path -import sys, os - -def bootstrap_paths(): - """ - 让 'AlgoriAgent'(位于 repo_root/AlgoriAgent)可被 import; - 并提供 STUDENT_WORKSPACE_ROOT 的默认值(repo_root/study)。 - 适配当前工厂位置:repo_root/Html/apps/__init__.py - """ - here = Path(__file__).resolve() - # repo_root = .../Html/apps/../../ => parents[2] - repo_root = here.parents[2] - - # 兜底:如果目录结构变化,尝试向上搜索包含 AlgoriAgent 的目录作为 repo_root - if not (repo_root / "AlgoriAgent").exists(): - for p in here.parents: - if (p / "AlgoriAgent").is_dir(): - repo_root = p - break - - # 确保仓库根在 sys.path(这样 'AlgoriAgent' 顶层包可被发现) - repo_root_str = str(repo_root) - if repo_root_str not in sys.path: - sys.path.insert(0, repo_root_str) - - # 可选:如果你还有其它顶层包,也可在此处继续插入 - - # 默认学习工作区目录(也可放到 config.ini / 环境变量覆盖) - os.environ.setdefault("STUDENT_WORKSPACE_ROOT", str(repo_root / "study")) - - return repo_root # 方便调试/日志 \ No newline at end of file diff --git a/Html/runs/run_20250911-060518_fd3vqd/code/wsgi.py b/Html/runs/run_20250911-060518_fd3vqd/code/wsgi.py deleted file mode 100644 index bbcbe5f..0000000 --- a/Html/runs/run_20250911-060518_fd3vqd/code/wsgi.py +++ /dev/null @@ -1,6 +0,0 @@ -# wsgi.py -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -# 提供一个可被 WSGI/进程管理器导入的 app 对象 -app = create_app() diff --git a/Html/runs/run_20250911-060518_fd3vqd/logging.chat b/Html/runs/run_20250911-060518_fd3vqd/logging.chat deleted file mode 100644 index e69de29..0000000 diff --git a/Html/runs/run_20250911-060518_fd3vqd/logging.log b/Html/runs/run_20250911-060518_fd3vqd/logging.log deleted file mode 100644 index fff9daa..0000000 --- a/Html/runs/run_20250911-060518_fd3vqd/logging.log +++ /dev/null @@ -1 +0,0 @@ -2025-09-11 06:05:22.338 | INFO | agentscope.models:read_model_configs:186 - Load configs for model wrapper: openai_cfg diff --git a/Html/runs/run_20250911-060940_yzij8b/.config b/Html/runs/run_20250911-060940_yzij8b/.config deleted file mode 100644 index 50f9780..0000000 --- a/Html/runs/run_20250911-060940_yzij8b/.config +++ /dev/null @@ -1,7 +0,0 @@ -{ - "project": "HYVODY", - "name": "yzij8b", - "run_id": "run_20250911-060940_yzij8b", - "timestamp": "2025-09-11 06:09:40", - "pid": 32244 -} \ No newline at end of file diff --git a/Html/runs/run_20250911-060940_yzij8b/agentscope.db b/Html/runs/run_20250911-060940_yzij8b/agentscope.db deleted file mode 100644 index 666055b77679cda29c14fcf23b4ef1d039c5b52a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI%L2KJE6bEoS4Q(k)+glI2yjv3-0%NB!Hs&O1YUav`W0U1F<0V=#BsNLx(sSu$ z>=W&q?4#^B$!*yt2YT5l`~^0a^z(#~{ zkyg6w!t)u0!@f%5aeaJcfD9*Q_b$ozCY8>~CFA6|{Z2V!N;Z^cIq}eS$>x3HY|^=j z7lokrf1)Z$x@_R^N~@apn7OPMkZ(I<*1WJCw@v3GWy2n6&RcIQ0~zlR_x8^$%be!% zmxb7@7V;}H+K5#l(wSbZKXKY!mys6ROyi|!%aN@+%REpi?;B-K4PC3&{>iCzQnNB+ zwbW!z4iA{x(V_2L+5VJ1vMJeN;5l68yJ9?OZyl-TNCEp4P{^H8$cTGExdq$9ANE6@ zA@`ZUhb>is+Y=S?%$C1fnN{muZU1a!nMRV%#qFbMT;y3hf|KlJ)00Izz00bZa0SG_<0uX=z1a@EGHy1PL*Z=?k diff --git a/Html/runs/run_20250911-060940_yzij8b/code/app.py b/Html/runs/run_20250911-060940_yzij8b/code/app.py deleted file mode 100644 index c7f31f7..0000000 --- a/Html/runs/run_20250911-060940_yzij8b/code/app.py +++ /dev/null @@ -1,21 +0,0 @@ -# app.py 0.1.1 rise to factory mode -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -from apps.extensions import socketio - -# 工厂创建 app,工厂里已经做了:加载配置/注册蓝图/注册 namespaces -app = create_app() - -if __name__ == "__main__": - # 仅本地开发用;生产不要用 werkzeug 自带的开发服务器 - socketio.run( - app, - host="0.0.0.0", - port=5551, - debug=True, # 开发期打开 - allow_unsafe_werkzeug=True, # 避免 dev server 的安全限制提示 - # ssl_context=('server.crt', 'server.key') - ) - - diff --git a/Html/runs/run_20250911-060940_yzij8b/code/app_back.py b/Html/runs/run_20250911-060940_yzij8b/code/app_back.py deleted file mode 100644 index 246853c..0000000 --- a/Html/runs/run_20250911-060940_yzij8b/code/app_back.py +++ /dev/null @@ -1,480 +0,0 @@ -from bootstrap import bootstrap_paths -bootstrap_paths() -from functools import wraps -from flask import Flask, redirect, session, request, jsonify, render_template, send_from_directory, url_for -from flask_cors import CORS -from flask_socketio import SocketIO, join_room, emit, Namespace -import markdown -import os -import uuid -import shutil -import sys -import json -from apps.auth.decorators import require_role -parent_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) -sys.path.insert(0, parent_dir) -student_workspace_root_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../study')) -current_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '.')) -sys.path.insert(0, current_dir) -from AlgoriAgent.projects.algoriAgent.agent_manager import AgentManager - - -import configparser - -from db.user_list import UserList -from db.user import User, load_user_from_json, create_user_json -from db.course_list import CourseList -from db.course import Course, load_course_from_json -GLOBAL_CONFIG = configparser.ConfigParser() -GLOBAL_CONFIG.read('config.ini') -VSCODE_WEB_URL = GLOBAL_CONFIG['VSCODE_WEB']['url'] -USER_DATA_DIR = GLOBAL_CONFIG['USER_DATA']['dir'] -COURSE_DATA_DIR = GLOBAL_CONFIG['COURSE_DATA']['dir'] - -app = Flask(__name__) -socketio = SocketIO(app, cors_allowed_origins="*",ping_timeout=60, ping_interval=5) -# socketio = SocketIO(app, cors_allowed_origins="http://localhost:9888") # 设置跨域支持 -import logging -app.secret_key = 'cakebaker' -app.logger.setLevel(logging.DEBUG) -# 配置 CORS -CORS(app, resources={r"/*": {"origins": VSCODE_WEB_URL},}, supports_credentials=True) - - -userid_recorder = {} # user_id&path -> session['user_id'] - -''' -Backboard -''' -from backboardManager import BackBoardManager, Backboard - -backboard_manager = BackBoardManager() -uuid2username = {} -username2uuid = {} - - - -# 定义命名空间:用于和 VSCode 插件交流 -class VSCodeNamespace(Namespace): - def on_login(self,data): - print("VSCode client connected") - print(data) - dataconfig = data['config'] - user_id = dataconfig.get('user_id') - path = dataconfig.get('path') - course_id = dataconfig.get('course_id') - lesson_id = dataconfig.get('chapter_id') - print(f"User {user_id} connected with path: {path}") - useruuid = username2uuid[user_id] - join_room(useruuid, namespace='/vscode') - if backboard_manager.get_backboard(useruuid) == None: - backboard_manager.add_backboard(useruuid,user_id, course_id, lesson_id, path) - - - def on_message(self, data): - print(f"Received from VSCode client: {data}") - dataconfig = data['config'] - realtime_response(dataconfig, data) - # emit('response', {'message': 'Config data received and connection established'}) - def on_disconnect(self, data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - -def realtime_response(config, realtime_action): - user_id = config['user_id'] - folder_path = config['path'] - useruuid = username2uuid[user_id] - bb = backboard_manager.get_backboard(useruuid) - assert type(bb) == Backboard - - bb.add_history(realtime_action) - - if realtime_action['type'] == 'workspaceFolders': - bb.file_tree = realtime_action['fileTree'] - - if realtime_action['type'] == 'activeFile': - file_path = realtime_action['filePath'] - assert type(file_path) == str - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - if realtime_action['type'] == 'paste': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.pasted_file_path = file_path - bb.pasted_content = realtime_action['content'] - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - if realtime_action['type'] == 'fileEdit': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - - - print("config"+str(config)) - print("realtime_action"+str(realtime_action)) - pass - - -''' -Agent and Chat -''' -agent_manager = AgentManager(app = app, socketio = socketio) -user_threads = {} -import threading -from concurrent.futures import ThreadPoolExecutor, as_completed - -# 初始化线程池 -executor = ThreadPoolExecutor(max_workers=10) -class AgentNamespace(Namespace): - def on_login(self, data): - data = json.loads(data) - user = data['username'] - course_id = data['course_id'] - chapter_id = data['chapter_id'] - user_uuid = username2uuid[user] - session['user_id'] = user_uuid - print(f'User connected with session user_id: {user_uuid}') - # 从markdown、markdown_prompts、score_prompts中各读取数据folder.md并进行new_agent - with open(f'books/markdown/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fmd,\ - open(f'books/markdown_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8')as fmdp,\ - open(f'books/score_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fsp: - markdown = fmd.read() - markdown_prompts = fmdp.read() - score_prompts = fsp.read() - user_uuid, agent = agent_manager.new_agent(course_id, chapter_id, markdown, markdown_prompts, score_prompts, id=user_uuid, - root_path=f'../../study/{user}/{course_id}/{chapter_id}') - print(user_uuid) - join_room(user_uuid, namespace='/agent') # 将该用户加入以user_id为名的room - backboard_manager.add_backboard(user_uuid, user, course_id, chapter_id, root_path=f'../../study/{user}/{course_id}/{chapter_id}') - - def on_language(self, language): - id = session.get('user_id') - agent_manager.change_language(id, language) - - def on_message(self, data): - print(f"Message from client: {data}") - id = session.get('user_id') - if (type(data)==str): - data = json.loads(data) - print(id) - if data['type'] == 'text': - res = agent_manager.invoke(id, data['data'], backboard_manager.get_backboard(id).get_info_prompt()) - print('=*='*20) - print(res.content) - reply = f"{res.content['speak']}" - with app.app_context(): - emit('message',reply, room=id, namespace='/agent') - emit('request_function',res.content['function'], room=id, namespace='/agent') - - if data['type'] == 'function': - agent_manager.function_call(id, data['data']) - - def on_initiative(self,data): - print("User active function call") - user_id = session['user_id'] - if data['name'] == 'sample_judge': - agent_manager.sample_judge(user_id, backboard_manager.get_backboard(user_id)) - if data['name'] == 'judge': - agent_manager.judge(user_id, backboard_manager.get_backboard(user_id)) - - - - def on_disconnect(self,data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - - -''' -Markdown to HTML -''' -# 配置文件路径 -MARKDOWN_DIR = 'books/markdown' # 存放 markdown 文件的文件夹 -STATIC_DIR = 'static' # 存放生成的 HTML 和图片资源的文件夹 -IMAGE_DIR = 'image' # 图片资源相对于 markdown 的位置 - - - -@app.route('/--markdown', methods=['GET']) -def convert_md(course_id, filename): - md_file_path = os.path.join(MARKDOWN_DIR,course_id, f'{filename}.md') - - if not os.path.exists(md_file_path): - return jsonify({'error': 'Markdown file not found'}), 404 - - # 读取 markdown 文件内容 - with open(md_file_path, 'r', encoding='utf-8') as file: - md_content = file.read() - - # 将 markdown 转换为 HTML - html_content = markdown.markdown(md_content) - # 插入 CSS 样式,限制图片最大宽度为 100%,高度自动调整 - html_with_styles = f""" - - - - - - - {html_content} - - - """ - # 保存 HTML 文件到 static 文件夹 - html_output_path = os.path.join(STATIC_DIR, f'{filename}.html') - with open(html_output_path, 'w', encoding='utf-8') as html_file: - html_file.write(html_with_styles) - - # 处理图片资源,将 image/xxx 文件夹拷贝到 static/image/xxx - image_source_dir = os.path.join(MARKDOWN_DIR,course_id, IMAGE_DIR, filename) - image_target_dir = os.path.join(STATIC_DIR, IMAGE_DIR, filename) - print(f"Copying image resources from {image_source_dir} to {image_target_dir}") - if os.path.exists(image_source_dir): - # 确保 static/image/xxx 目录存在 - if not os.path.exists(image_target_dir): - os.makedirs(image_target_dir) - - # 拷贝图片资源 - for image_file in os.listdir(image_source_dir): - full_image_file_path = os.path.join(image_source_dir, image_file) - if os.path.isfile(full_image_file_path): - shutil.copy(full_image_file_path, image_target_dir) - - return jsonify({'html_url': f'/static/{filename}.html'}) - -# 静态文件(HTML 和图片资源)的访问 -@app.route('/static/') -def serve_static(filename): - return send_from_directory(STATIC_DIR, filename) - - -''' -Vscode -''' -@app.route('/desktop///') -def desktop(user_id, course_id, chapter_id): - if 'user_id' not in session: - # return redirect(url_for('login')) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ user_id + "uuid is"+ session['user_id']) - username2uuid[user_id] = session['user_id'] - uuid2username[session['user_id']] = user_id - userid_recorder[user_id+'&'+course_id] = session['user_id'] - - # 在学习目录下创建一个名为 user_id_path 的文件夹 - path_dir = os.path.join(student_workspace_root_path, user_id, course_id,chapter_id) - os.makedirs(path_dir, exist_ok=True) - # 在此文件夹内部创建一个.config文件,并写入 user_id=user_id\n path=path - config_path = os.path.join(path_dir, '.config') - if GLOBAL_CONFIG['VSCODE_WEB_PATH']['is_wsl']: # 如果是在 WSL 中运行,则将路径转换为 WSL 路径 - path_dir = path_dir.replace('\\', '/') - path_dir = path_dir.replace(GLOBAL_CONFIG['VSCODE_WEB_PATH']['windows_path'] , GLOBAL_CONFIG['VSCODE_WEB_PATH']['wsl_path']) - with open(config_path, 'w', encoding='utf-8') as f: - tmpd = {'user_id': user_id, 'course_id': course_id, 'chapter_id': chapter_id, 'path': path_dir} - json.dump(tmpd, f) - print('---------------------') - print(config_path) - return render_template('desktop.html', vscode_web_url=VSCODE_WEB_URL, user_id=user_id, course_id=course_id, chapter_id=chapter_id, workspace_path=path_dir) - -@app.route('/desktop_nouser//') -def desktop_nouser(course_id, chapter_id): - if 'user_id' not in session: - return redirect(url_for('login')) - user_id = session['user_id'] - username = uuid2username[user_id] - return redirect(url_for('desktop', user_id=username, course_id=course_id, chapter_id=chapter_id)) - -@app.route('/vscode_data', methods=['POST']) -def vscode_data(): - data = request.json - config = data['config'] - realtime_response(config,data) - print(f"Received data from VSCode: {data}") - return jsonify({"status": "success", "received": data}) - - - -''' -Login - -''' -users_list = UserList() -course_list = CourseList() - - -@app.route('/register') -def register(): - return render_template('register.html') - -@app.route('/register_teacher') -def register_teacher(): - return render_template('register_teacher.html') - -@app.route('/register_teacher_post', methods=['POST']) -def register_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password, teacher=True) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - -@app.route('/register_post', methods=['POST']) -def register_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - - -@app.route('/login') -def login(): - return render_template('login.html') - if 'user_id' not in session: - return render_template('login.html') - else: - return redirect(url_for('/')) - -@app.route('/login_post', methods=['POST']) -def login_post(): - # 获取请求的 JSON 数据 - data = request.get_json() - - username = data.get('username') - password = data.get('password') - - pswd = users_list.get_user_pswd(username) - - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/login_teacher_post', methods=['POST']) -def login_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - pswd = users_list.get_user_pswd(username) - is_teacher = users_list.get_user_is_teacher(username) - if is_teacher is None or is_teacher == False: - return jsonify({'success': False, 'message': '用户名不存在或非教师账号'}) - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/teacherboard') -@require_role(roles="teacher") -def teacherboard(): - return render_template('teacherboard.html') - - -@app.route('/logout') -def logout(): - session.pop('user_id', None) - return redirect(url_for('login')) - -@app.route('/get_session') -def get_session(): - user_session = session.get('user_id', 'default_session') - return jsonify({"session": user_session}) - - -''' -DashBoard -''' -user_id2UserClass = {} -@app.route('/dashboard') -@require_role -def dashboard(): - user_id = session['user_id'] - username = uuid2username[user_id] - if (user_id not in user_id2UserClass): - user_id2UserClass[user_id] = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - user_course_data = [] - for course_id in user_id2UserClass[user_id].select_course: - course_brief_info = course_list.get_course_brief_info(course_id, load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR)) - user_course_data.append(course_brief_info) - return render_template('dashboard.html',user_data = user_id2UserClass[user_id].to_json_without_dialog(), user_course_data = json.dumps(user_course_data)) - -''' -Course -''' - -@app.route('/course/') -@require_role -def course(course_id): - c = load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR) - return render_template('course.html', course_id=course_id, course_data=c) - -@app.route('/select_course', methods=['POST']) -@require_role -def select_course(): - user = user_id2UserClass[session['user_id']] - data = request.get_json() - course_id = data.get('course_id') - if course_id: - user.select_new_course(course_id, load_course_from_json(course_id, COURSE_DATA_DIR)) - return jsonify({'success': True, 'message': '课程选择成功'}) - - -@app.route('/') -@require_role -def home_index(): - selected_courses=[] - if ('user_id' in session): - if (session['user_id'] not in user_id2UserClass): return redirect(url_for('login')) - user = user_id2UserClass[session['user_id']] - for course_id in user.select_course: - selected_courses.append(course_id) - - return render_template('index.html', courses_data = course_list, selected_courses =selected_courses) - -# 一些app辅助函数,主要提供给Agent与数据库的交互能力 - -class MyFunction: - def save_chapter_memory(self, id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal): - print("-=-=-=-=-=-=-=-") - print(id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - username = uuid2username[id] - u = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - u.save_chapter_memory(course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - -app.my_function = MyFunction() -if __name__ == '__main__': - socketio.on_namespace(VSCodeNamespace('/vscode')) - socketio.on_namespace(AgentNamespace('/agent')) - socketio.run(app, host='0.0.0.0', port=5551, debug=False,allow_unsafe_werkzeug=True) - diff --git a/Html/runs/run_20250911-060940_yzij8b/code/backboardManager.py b/Html/runs/run_20250911-060940_yzij8b/code/backboardManager.py deleted file mode 100644 index 7de5f19..0000000 --- a/Html/runs/run_20250911-060940_yzij8b/code/backboardManager.py +++ /dev/null @@ -1,80 +0,0 @@ - - - -import time -import os - -class Backboard: - def __init__(self, user_uuid, username, course_id, lesson_id, root_path): - self.user_uuid = user_uuid - self.username = username - self.course_id = course_id - self.lesson_id = lesson_id - self.root_path = root_path - self.create_time = time.time() - self.enter_chapter_time = time.time() - self.history = [] - self.file_tree = "[]" - self.active_file_path = "" - self.active_file_content = "" - self.pasted_file_path = "" - self.pasted_content = "" - - - def next_chapter(self): - self.enter_chapter_time = time.time() - - def get_info_prompt(self): - - five_history = "" - for h in self.history[-5:]: - five_history += h['type'] + "\n" + h.get('filePath', '') + "\n\n" - - endl = "\n" - return (f"###Global Info:###{endl}" - f"Here are some info about now user's IDE, refer to it when you need to handle some code.{endl}" - f"- User's total study time is {self.get_deltatime_mmss(self.create_time, time.time())}{endl}" - f"- User's current chapter study time is {self.get_deltatime_mmss(self.enter_chapter_time, time.time())}{endl}" - f"- Activated file path: {self.active_file_path}{endl}" - f"```{endl}" - f"{self.active_file_content[-10:]}{endl}" - f"```{endl}" - f"- Last five action:{five_history}{endl}" - f"- File tree: {self.file_tree}{endl}") - # f"- Activated file content (current editing 10 lines): {endl}" - def add_history(self, realtime_action): - if(realtime_action['type']=='config'):return - if len(self.history)!=0: - if (self.history[-1]['type']=='fileEdit'): - if(self.history[-1]['filePath'] == realtime_action['filePath']): - self.history[-1]['content'] = realtime_action['content'] - return - self.history.append(realtime_action) - - - def get_deltatime_mmss(self, start_time, end_time): - elapsed_time = end_time - start_time - hours = int(elapsed_time // 3600) - minutes = int((elapsed_time % 3600) // 60) - seconds = int(elapsed_time % 60) - return f"{hours:02d}:{minutes:02d}:{seconds:02d}" - - - def get_active_file_reletive_path(self): - relative_path = os.path.relpath(self.active_file_path, self.root_path) - return relative_path - - - -class BackBoardManager: - def __init__(self): - self.backboards = {} # user_uuid: Backboard - - def add_backboard(self, user_uuid, username, course_id, lesson_id, root_path): - self.backboards[user_uuid] = Backboard(user_uuid,username, course_id, lesson_id, root_path) - - def get_backboard(self, user_uuid) -> Backboard: - return self.backboards[user_uuid] - - - diff --git a/Html/runs/run_20250911-060940_yzij8b/code/bootstrap.py b/Html/runs/run_20250911-060940_yzij8b/code/bootstrap.py deleted file mode 100644 index bcb15ce..0000000 --- a/Html/runs/run_20250911-060940_yzij8b/code/bootstrap.py +++ /dev/null @@ -1,31 +0,0 @@ -from pathlib import Path -import sys, os - -def bootstrap_paths(): - """ - 让 'AlgoriAgent'(位于 repo_root/AlgoriAgent)可被 import; - 并提供 STUDENT_WORKSPACE_ROOT 的默认值(repo_root/study)。 - 适配当前工厂位置:repo_root/Html/apps/__init__.py - """ - here = Path(__file__).resolve() - # repo_root = .../Html/apps/../../ => parents[2] - repo_root = here.parents[2] - - # 兜底:如果目录结构变化,尝试向上搜索包含 AlgoriAgent 的目录作为 repo_root - if not (repo_root / "AlgoriAgent").exists(): - for p in here.parents: - if (p / "AlgoriAgent").is_dir(): - repo_root = p - break - - # 确保仓库根在 sys.path(这样 'AlgoriAgent' 顶层包可被发现) - repo_root_str = str(repo_root) - if repo_root_str not in sys.path: - sys.path.insert(0, repo_root_str) - - # 可选:如果你还有其它顶层包,也可在此处继续插入 - - # 默认学习工作区目录(也可放到 config.ini / 环境变量覆盖) - os.environ.setdefault("STUDENT_WORKSPACE_ROOT", str(repo_root / "study")) - - return repo_root # 方便调试/日志 \ No newline at end of file diff --git a/Html/runs/run_20250911-060940_yzij8b/code/wsgi.py b/Html/runs/run_20250911-060940_yzij8b/code/wsgi.py deleted file mode 100644 index bbcbe5f..0000000 --- a/Html/runs/run_20250911-060940_yzij8b/code/wsgi.py +++ /dev/null @@ -1,6 +0,0 @@ -# wsgi.py -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -# 提供一个可被 WSGI/进程管理器导入的 app 对象 -app = create_app() diff --git a/Html/runs/run_20250911-060940_yzij8b/logging.chat b/Html/runs/run_20250911-060940_yzij8b/logging.chat deleted file mode 100644 index e69de29..0000000 diff --git a/Html/runs/run_20250911-060940_yzij8b/logging.log b/Html/runs/run_20250911-060940_yzij8b/logging.log deleted file mode 100644 index f0a59fe..0000000 --- a/Html/runs/run_20250911-060940_yzij8b/logging.log +++ /dev/null @@ -1 +0,0 @@ -2025-09-11 06:09:44.417 | INFO | agentscope.models:read_model_configs:186 - Load configs for model wrapper: openai_cfg diff --git a/Html/runs/run_20250911-060944_a5y9ow/.config b/Html/runs/run_20250911-060944_a5y9ow/.config deleted file mode 100644 index 6fe38f8..0000000 --- a/Html/runs/run_20250911-060944_a5y9ow/.config +++ /dev/null @@ -1,7 +0,0 @@ -{ - "project": "YmYwoX", - "name": "a5y9ow", - "run_id": "run_20250911-060944_a5y9ow", - "timestamp": "2025-09-11 06:09:44", - "pid": 32262 -} \ No newline at end of file diff --git a/Html/runs/run_20250911-060944_a5y9ow/agentscope.db b/Html/runs/run_20250911-060944_a5y9ow/agentscope.db deleted file mode 100644 index 666055b77679cda29c14fcf23b4ef1d039c5b52a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI%L2KJE6bEoS4Q(k)+glI2yjv3-0%NB!Hs&O1YUav`W0U1F<0V=#BsNLx(sSu$ z>=W&q?4#^B$!*yt2YT5l`~^0a^z(#~{ zkyg6w!t)u0!@f%5aeaJcfD9*Q_b$ozCY8>~CFA6|{Z2V!N;Z^cIq}eS$>x3HY|^=j z7lokrf1)Z$x@_R^N~@apn7OPMkZ(I<*1WJCw@v3GWy2n6&RcIQ0~zlR_x8^$%be!% zmxb7@7V;}H+K5#l(wSbZKXKY!mys6ROyi|!%aN@+%REpi?;B-K4PC3&{>iCzQnNB+ zwbW!z4iA{x(V_2L+5VJ1vMJeN;5l68yJ9?OZyl-TNCEp4P{^H8$cTGExdq$9ANE6@ zA@`ZUhb>is+Y=S?%$C1fnN{muZU1a!nMRV%#qFbMT;y3hf|KlJ)00Izz00bZa0SG_<0uX=z1a@EGHy1PL*Z=?k diff --git a/Html/runs/run_20250911-060944_a5y9ow/code/app.py b/Html/runs/run_20250911-060944_a5y9ow/code/app.py deleted file mode 100644 index c7f31f7..0000000 --- a/Html/runs/run_20250911-060944_a5y9ow/code/app.py +++ /dev/null @@ -1,21 +0,0 @@ -# app.py 0.1.1 rise to factory mode -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -from apps.extensions import socketio - -# 工厂创建 app,工厂里已经做了:加载配置/注册蓝图/注册 namespaces -app = create_app() - -if __name__ == "__main__": - # 仅本地开发用;生产不要用 werkzeug 自带的开发服务器 - socketio.run( - app, - host="0.0.0.0", - port=5551, - debug=True, # 开发期打开 - allow_unsafe_werkzeug=True, # 避免 dev server 的安全限制提示 - # ssl_context=('server.crt', 'server.key') - ) - - diff --git a/Html/runs/run_20250911-060944_a5y9ow/code/app_back.py b/Html/runs/run_20250911-060944_a5y9ow/code/app_back.py deleted file mode 100644 index 246853c..0000000 --- a/Html/runs/run_20250911-060944_a5y9ow/code/app_back.py +++ /dev/null @@ -1,480 +0,0 @@ -from bootstrap import bootstrap_paths -bootstrap_paths() -from functools import wraps -from flask import Flask, redirect, session, request, jsonify, render_template, send_from_directory, url_for -from flask_cors import CORS -from flask_socketio import SocketIO, join_room, emit, Namespace -import markdown -import os -import uuid -import shutil -import sys -import json -from apps.auth.decorators import require_role -parent_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) -sys.path.insert(0, parent_dir) -student_workspace_root_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../study')) -current_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '.')) -sys.path.insert(0, current_dir) -from AlgoriAgent.projects.algoriAgent.agent_manager import AgentManager - - -import configparser - -from db.user_list import UserList -from db.user import User, load_user_from_json, create_user_json -from db.course_list import CourseList -from db.course import Course, load_course_from_json -GLOBAL_CONFIG = configparser.ConfigParser() -GLOBAL_CONFIG.read('config.ini') -VSCODE_WEB_URL = GLOBAL_CONFIG['VSCODE_WEB']['url'] -USER_DATA_DIR = GLOBAL_CONFIG['USER_DATA']['dir'] -COURSE_DATA_DIR = GLOBAL_CONFIG['COURSE_DATA']['dir'] - -app = Flask(__name__) -socketio = SocketIO(app, cors_allowed_origins="*",ping_timeout=60, ping_interval=5) -# socketio = SocketIO(app, cors_allowed_origins="http://localhost:9888") # 设置跨域支持 -import logging -app.secret_key = 'cakebaker' -app.logger.setLevel(logging.DEBUG) -# 配置 CORS -CORS(app, resources={r"/*": {"origins": VSCODE_WEB_URL},}, supports_credentials=True) - - -userid_recorder = {} # user_id&path -> session['user_id'] - -''' -Backboard -''' -from backboardManager import BackBoardManager, Backboard - -backboard_manager = BackBoardManager() -uuid2username = {} -username2uuid = {} - - - -# 定义命名空间:用于和 VSCode 插件交流 -class VSCodeNamespace(Namespace): - def on_login(self,data): - print("VSCode client connected") - print(data) - dataconfig = data['config'] - user_id = dataconfig.get('user_id') - path = dataconfig.get('path') - course_id = dataconfig.get('course_id') - lesson_id = dataconfig.get('chapter_id') - print(f"User {user_id} connected with path: {path}") - useruuid = username2uuid[user_id] - join_room(useruuid, namespace='/vscode') - if backboard_manager.get_backboard(useruuid) == None: - backboard_manager.add_backboard(useruuid,user_id, course_id, lesson_id, path) - - - def on_message(self, data): - print(f"Received from VSCode client: {data}") - dataconfig = data['config'] - realtime_response(dataconfig, data) - # emit('response', {'message': 'Config data received and connection established'}) - def on_disconnect(self, data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - -def realtime_response(config, realtime_action): - user_id = config['user_id'] - folder_path = config['path'] - useruuid = username2uuid[user_id] - bb = backboard_manager.get_backboard(useruuid) - assert type(bb) == Backboard - - bb.add_history(realtime_action) - - if realtime_action['type'] == 'workspaceFolders': - bb.file_tree = realtime_action['fileTree'] - - if realtime_action['type'] == 'activeFile': - file_path = realtime_action['filePath'] - assert type(file_path) == str - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - if realtime_action['type'] == 'paste': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.pasted_file_path = file_path - bb.pasted_content = realtime_action['content'] - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - if realtime_action['type'] == 'fileEdit': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - - - print("config"+str(config)) - print("realtime_action"+str(realtime_action)) - pass - - -''' -Agent and Chat -''' -agent_manager = AgentManager(app = app, socketio = socketio) -user_threads = {} -import threading -from concurrent.futures import ThreadPoolExecutor, as_completed - -# 初始化线程池 -executor = ThreadPoolExecutor(max_workers=10) -class AgentNamespace(Namespace): - def on_login(self, data): - data = json.loads(data) - user = data['username'] - course_id = data['course_id'] - chapter_id = data['chapter_id'] - user_uuid = username2uuid[user] - session['user_id'] = user_uuid - print(f'User connected with session user_id: {user_uuid}') - # 从markdown、markdown_prompts、score_prompts中各读取数据folder.md并进行new_agent - with open(f'books/markdown/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fmd,\ - open(f'books/markdown_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8')as fmdp,\ - open(f'books/score_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fsp: - markdown = fmd.read() - markdown_prompts = fmdp.read() - score_prompts = fsp.read() - user_uuid, agent = agent_manager.new_agent(course_id, chapter_id, markdown, markdown_prompts, score_prompts, id=user_uuid, - root_path=f'../../study/{user}/{course_id}/{chapter_id}') - print(user_uuid) - join_room(user_uuid, namespace='/agent') # 将该用户加入以user_id为名的room - backboard_manager.add_backboard(user_uuid, user, course_id, chapter_id, root_path=f'../../study/{user}/{course_id}/{chapter_id}') - - def on_language(self, language): - id = session.get('user_id') - agent_manager.change_language(id, language) - - def on_message(self, data): - print(f"Message from client: {data}") - id = session.get('user_id') - if (type(data)==str): - data = json.loads(data) - print(id) - if data['type'] == 'text': - res = agent_manager.invoke(id, data['data'], backboard_manager.get_backboard(id).get_info_prompt()) - print('=*='*20) - print(res.content) - reply = f"{res.content['speak']}" - with app.app_context(): - emit('message',reply, room=id, namespace='/agent') - emit('request_function',res.content['function'], room=id, namespace='/agent') - - if data['type'] == 'function': - agent_manager.function_call(id, data['data']) - - def on_initiative(self,data): - print("User active function call") - user_id = session['user_id'] - if data['name'] == 'sample_judge': - agent_manager.sample_judge(user_id, backboard_manager.get_backboard(user_id)) - if data['name'] == 'judge': - agent_manager.judge(user_id, backboard_manager.get_backboard(user_id)) - - - - def on_disconnect(self,data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - - -''' -Markdown to HTML -''' -# 配置文件路径 -MARKDOWN_DIR = 'books/markdown' # 存放 markdown 文件的文件夹 -STATIC_DIR = 'static' # 存放生成的 HTML 和图片资源的文件夹 -IMAGE_DIR = 'image' # 图片资源相对于 markdown 的位置 - - - -@app.route('/--markdown', methods=['GET']) -def convert_md(course_id, filename): - md_file_path = os.path.join(MARKDOWN_DIR,course_id, f'{filename}.md') - - if not os.path.exists(md_file_path): - return jsonify({'error': 'Markdown file not found'}), 404 - - # 读取 markdown 文件内容 - with open(md_file_path, 'r', encoding='utf-8') as file: - md_content = file.read() - - # 将 markdown 转换为 HTML - html_content = markdown.markdown(md_content) - # 插入 CSS 样式,限制图片最大宽度为 100%,高度自动调整 - html_with_styles = f""" - - - - - - - {html_content} - - - """ - # 保存 HTML 文件到 static 文件夹 - html_output_path = os.path.join(STATIC_DIR, f'{filename}.html') - with open(html_output_path, 'w', encoding='utf-8') as html_file: - html_file.write(html_with_styles) - - # 处理图片资源,将 image/xxx 文件夹拷贝到 static/image/xxx - image_source_dir = os.path.join(MARKDOWN_DIR,course_id, IMAGE_DIR, filename) - image_target_dir = os.path.join(STATIC_DIR, IMAGE_DIR, filename) - print(f"Copying image resources from {image_source_dir} to {image_target_dir}") - if os.path.exists(image_source_dir): - # 确保 static/image/xxx 目录存在 - if not os.path.exists(image_target_dir): - os.makedirs(image_target_dir) - - # 拷贝图片资源 - for image_file in os.listdir(image_source_dir): - full_image_file_path = os.path.join(image_source_dir, image_file) - if os.path.isfile(full_image_file_path): - shutil.copy(full_image_file_path, image_target_dir) - - return jsonify({'html_url': f'/static/{filename}.html'}) - -# 静态文件(HTML 和图片资源)的访问 -@app.route('/static/') -def serve_static(filename): - return send_from_directory(STATIC_DIR, filename) - - -''' -Vscode -''' -@app.route('/desktop///') -def desktop(user_id, course_id, chapter_id): - if 'user_id' not in session: - # return redirect(url_for('login')) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ user_id + "uuid is"+ session['user_id']) - username2uuid[user_id] = session['user_id'] - uuid2username[session['user_id']] = user_id - userid_recorder[user_id+'&'+course_id] = session['user_id'] - - # 在学习目录下创建一个名为 user_id_path 的文件夹 - path_dir = os.path.join(student_workspace_root_path, user_id, course_id,chapter_id) - os.makedirs(path_dir, exist_ok=True) - # 在此文件夹内部创建一个.config文件,并写入 user_id=user_id\n path=path - config_path = os.path.join(path_dir, '.config') - if GLOBAL_CONFIG['VSCODE_WEB_PATH']['is_wsl']: # 如果是在 WSL 中运行,则将路径转换为 WSL 路径 - path_dir = path_dir.replace('\\', '/') - path_dir = path_dir.replace(GLOBAL_CONFIG['VSCODE_WEB_PATH']['windows_path'] , GLOBAL_CONFIG['VSCODE_WEB_PATH']['wsl_path']) - with open(config_path, 'w', encoding='utf-8') as f: - tmpd = {'user_id': user_id, 'course_id': course_id, 'chapter_id': chapter_id, 'path': path_dir} - json.dump(tmpd, f) - print('---------------------') - print(config_path) - return render_template('desktop.html', vscode_web_url=VSCODE_WEB_URL, user_id=user_id, course_id=course_id, chapter_id=chapter_id, workspace_path=path_dir) - -@app.route('/desktop_nouser//') -def desktop_nouser(course_id, chapter_id): - if 'user_id' not in session: - return redirect(url_for('login')) - user_id = session['user_id'] - username = uuid2username[user_id] - return redirect(url_for('desktop', user_id=username, course_id=course_id, chapter_id=chapter_id)) - -@app.route('/vscode_data', methods=['POST']) -def vscode_data(): - data = request.json - config = data['config'] - realtime_response(config,data) - print(f"Received data from VSCode: {data}") - return jsonify({"status": "success", "received": data}) - - - -''' -Login - -''' -users_list = UserList() -course_list = CourseList() - - -@app.route('/register') -def register(): - return render_template('register.html') - -@app.route('/register_teacher') -def register_teacher(): - return render_template('register_teacher.html') - -@app.route('/register_teacher_post', methods=['POST']) -def register_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password, teacher=True) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - -@app.route('/register_post', methods=['POST']) -def register_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - - -@app.route('/login') -def login(): - return render_template('login.html') - if 'user_id' not in session: - return render_template('login.html') - else: - return redirect(url_for('/')) - -@app.route('/login_post', methods=['POST']) -def login_post(): - # 获取请求的 JSON 数据 - data = request.get_json() - - username = data.get('username') - password = data.get('password') - - pswd = users_list.get_user_pswd(username) - - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/login_teacher_post', methods=['POST']) -def login_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - pswd = users_list.get_user_pswd(username) - is_teacher = users_list.get_user_is_teacher(username) - if is_teacher is None or is_teacher == False: - return jsonify({'success': False, 'message': '用户名不存在或非教师账号'}) - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/teacherboard') -@require_role(roles="teacher") -def teacherboard(): - return render_template('teacherboard.html') - - -@app.route('/logout') -def logout(): - session.pop('user_id', None) - return redirect(url_for('login')) - -@app.route('/get_session') -def get_session(): - user_session = session.get('user_id', 'default_session') - return jsonify({"session": user_session}) - - -''' -DashBoard -''' -user_id2UserClass = {} -@app.route('/dashboard') -@require_role -def dashboard(): - user_id = session['user_id'] - username = uuid2username[user_id] - if (user_id not in user_id2UserClass): - user_id2UserClass[user_id] = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - user_course_data = [] - for course_id in user_id2UserClass[user_id].select_course: - course_brief_info = course_list.get_course_brief_info(course_id, load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR)) - user_course_data.append(course_brief_info) - return render_template('dashboard.html',user_data = user_id2UserClass[user_id].to_json_without_dialog(), user_course_data = json.dumps(user_course_data)) - -''' -Course -''' - -@app.route('/course/') -@require_role -def course(course_id): - c = load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR) - return render_template('course.html', course_id=course_id, course_data=c) - -@app.route('/select_course', methods=['POST']) -@require_role -def select_course(): - user = user_id2UserClass[session['user_id']] - data = request.get_json() - course_id = data.get('course_id') - if course_id: - user.select_new_course(course_id, load_course_from_json(course_id, COURSE_DATA_DIR)) - return jsonify({'success': True, 'message': '课程选择成功'}) - - -@app.route('/') -@require_role -def home_index(): - selected_courses=[] - if ('user_id' in session): - if (session['user_id'] not in user_id2UserClass): return redirect(url_for('login')) - user = user_id2UserClass[session['user_id']] - for course_id in user.select_course: - selected_courses.append(course_id) - - return render_template('index.html', courses_data = course_list, selected_courses =selected_courses) - -# 一些app辅助函数,主要提供给Agent与数据库的交互能力 - -class MyFunction: - def save_chapter_memory(self, id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal): - print("-=-=-=-=-=-=-=-") - print(id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - username = uuid2username[id] - u = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - u.save_chapter_memory(course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - -app.my_function = MyFunction() -if __name__ == '__main__': - socketio.on_namespace(VSCodeNamespace('/vscode')) - socketio.on_namespace(AgentNamespace('/agent')) - socketio.run(app, host='0.0.0.0', port=5551, debug=False,allow_unsafe_werkzeug=True) - diff --git a/Html/runs/run_20250911-060944_a5y9ow/code/backboardManager.py b/Html/runs/run_20250911-060944_a5y9ow/code/backboardManager.py deleted file mode 100644 index 7de5f19..0000000 --- a/Html/runs/run_20250911-060944_a5y9ow/code/backboardManager.py +++ /dev/null @@ -1,80 +0,0 @@ - - - -import time -import os - -class Backboard: - def __init__(self, user_uuid, username, course_id, lesson_id, root_path): - self.user_uuid = user_uuid - self.username = username - self.course_id = course_id - self.lesson_id = lesson_id - self.root_path = root_path - self.create_time = time.time() - self.enter_chapter_time = time.time() - self.history = [] - self.file_tree = "[]" - self.active_file_path = "" - self.active_file_content = "" - self.pasted_file_path = "" - self.pasted_content = "" - - - def next_chapter(self): - self.enter_chapter_time = time.time() - - def get_info_prompt(self): - - five_history = "" - for h in self.history[-5:]: - five_history += h['type'] + "\n" + h.get('filePath', '') + "\n\n" - - endl = "\n" - return (f"###Global Info:###{endl}" - f"Here are some info about now user's IDE, refer to it when you need to handle some code.{endl}" - f"- User's total study time is {self.get_deltatime_mmss(self.create_time, time.time())}{endl}" - f"- User's current chapter study time is {self.get_deltatime_mmss(self.enter_chapter_time, time.time())}{endl}" - f"- Activated file path: {self.active_file_path}{endl}" - f"```{endl}" - f"{self.active_file_content[-10:]}{endl}" - f"```{endl}" - f"- Last five action:{five_history}{endl}" - f"- File tree: {self.file_tree}{endl}") - # f"- Activated file content (current editing 10 lines): {endl}" - def add_history(self, realtime_action): - if(realtime_action['type']=='config'):return - if len(self.history)!=0: - if (self.history[-1]['type']=='fileEdit'): - if(self.history[-1]['filePath'] == realtime_action['filePath']): - self.history[-1]['content'] = realtime_action['content'] - return - self.history.append(realtime_action) - - - def get_deltatime_mmss(self, start_time, end_time): - elapsed_time = end_time - start_time - hours = int(elapsed_time // 3600) - minutes = int((elapsed_time % 3600) // 60) - seconds = int(elapsed_time % 60) - return f"{hours:02d}:{minutes:02d}:{seconds:02d}" - - - def get_active_file_reletive_path(self): - relative_path = os.path.relpath(self.active_file_path, self.root_path) - return relative_path - - - -class BackBoardManager: - def __init__(self): - self.backboards = {} # user_uuid: Backboard - - def add_backboard(self, user_uuid, username, course_id, lesson_id, root_path): - self.backboards[user_uuid] = Backboard(user_uuid,username, course_id, lesson_id, root_path) - - def get_backboard(self, user_uuid) -> Backboard: - return self.backboards[user_uuid] - - - diff --git a/Html/runs/run_20250911-060944_a5y9ow/code/bootstrap.py b/Html/runs/run_20250911-060944_a5y9ow/code/bootstrap.py deleted file mode 100644 index bcb15ce..0000000 --- a/Html/runs/run_20250911-060944_a5y9ow/code/bootstrap.py +++ /dev/null @@ -1,31 +0,0 @@ -from pathlib import Path -import sys, os - -def bootstrap_paths(): - """ - 让 'AlgoriAgent'(位于 repo_root/AlgoriAgent)可被 import; - 并提供 STUDENT_WORKSPACE_ROOT 的默认值(repo_root/study)。 - 适配当前工厂位置:repo_root/Html/apps/__init__.py - """ - here = Path(__file__).resolve() - # repo_root = .../Html/apps/../../ => parents[2] - repo_root = here.parents[2] - - # 兜底:如果目录结构变化,尝试向上搜索包含 AlgoriAgent 的目录作为 repo_root - if not (repo_root / "AlgoriAgent").exists(): - for p in here.parents: - if (p / "AlgoriAgent").is_dir(): - repo_root = p - break - - # 确保仓库根在 sys.path(这样 'AlgoriAgent' 顶层包可被发现) - repo_root_str = str(repo_root) - if repo_root_str not in sys.path: - sys.path.insert(0, repo_root_str) - - # 可选:如果你还有其它顶层包,也可在此处继续插入 - - # 默认学习工作区目录(也可放到 config.ini / 环境变量覆盖) - os.environ.setdefault("STUDENT_WORKSPACE_ROOT", str(repo_root / "study")) - - return repo_root # 方便调试/日志 \ No newline at end of file diff --git a/Html/runs/run_20250911-060944_a5y9ow/code/wsgi.py b/Html/runs/run_20250911-060944_a5y9ow/code/wsgi.py deleted file mode 100644 index bbcbe5f..0000000 --- a/Html/runs/run_20250911-060944_a5y9ow/code/wsgi.py +++ /dev/null @@ -1,6 +0,0 @@ -# wsgi.py -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -# 提供一个可被 WSGI/进程管理器导入的 app 对象 -app = create_app() diff --git a/Html/runs/run_20250911-060944_a5y9ow/logging.chat b/Html/runs/run_20250911-060944_a5y9ow/logging.chat deleted file mode 100644 index e69de29..0000000 diff --git a/Html/runs/run_20250911-060944_a5y9ow/logging.log b/Html/runs/run_20250911-060944_a5y9ow/logging.log deleted file mode 100644 index 0e43266..0000000 --- a/Html/runs/run_20250911-060944_a5y9ow/logging.log +++ /dev/null @@ -1 +0,0 @@ -2025-09-11 06:09:48.149 | INFO | agentscope.models:read_model_configs:186 - Load configs for model wrapper: openai_cfg diff --git a/Html/runs/run_20250911-074447_ax0g50/.config b/Html/runs/run_20250911-074447_ax0g50/.config deleted file mode 100644 index 00d8e12..0000000 --- a/Html/runs/run_20250911-074447_ax0g50/.config +++ /dev/null @@ -1,7 +0,0 @@ -{ - "project": "fnrJ6o", - "name": "ax0g50", - "run_id": "run_20250911-074447_ax0g50", - "timestamp": "2025-09-11 07:44:47", - "pid": 1602 -} \ No newline at end of file diff --git a/Html/runs/run_20250911-074447_ax0g50/agentscope.db b/Html/runs/run_20250911-074447_ax0g50/agentscope.db deleted file mode 100644 index 666055b77679cda29c14fcf23b4ef1d039c5b52a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI%L2KJE6bEoS4Q(k)+glI2yjv3-0%NB!Hs&O1YUav`W0U1F<0V=#BsNLx(sSu$ z>=W&q?4#^B$!*yt2YT5l`~^0a^z(#~{ zkyg6w!t)u0!@f%5aeaJcfD9*Q_b$ozCY8>~CFA6|{Z2V!N;Z^cIq}eS$>x3HY|^=j z7lokrf1)Z$x@_R^N~@apn7OPMkZ(I<*1WJCw@v3GWy2n6&RcIQ0~zlR_x8^$%be!% zmxb7@7V;}H+K5#l(wSbZKXKY!mys6ROyi|!%aN@+%REpi?;B-K4PC3&{>iCzQnNB+ zwbW!z4iA{x(V_2L+5VJ1vMJeN;5l68yJ9?OZyl-TNCEp4P{^H8$cTGExdq$9ANE6@ zA@`ZUhb>is+Y=S?%$C1fnN{muZU1a!nMRV%#qFbMT;y3hf|KlJ)00Izz00bZa0SG_<0uX=z1a@EGHy1PL*Z=?k diff --git a/Html/runs/run_20250911-074447_ax0g50/code/app.py b/Html/runs/run_20250911-074447_ax0g50/code/app.py deleted file mode 100644 index c7f31f7..0000000 --- a/Html/runs/run_20250911-074447_ax0g50/code/app.py +++ /dev/null @@ -1,21 +0,0 @@ -# app.py 0.1.1 rise to factory mode -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -from apps.extensions import socketio - -# 工厂创建 app,工厂里已经做了:加载配置/注册蓝图/注册 namespaces -app = create_app() - -if __name__ == "__main__": - # 仅本地开发用;生产不要用 werkzeug 自带的开发服务器 - socketio.run( - app, - host="0.0.0.0", - port=5551, - debug=True, # 开发期打开 - allow_unsafe_werkzeug=True, # 避免 dev server 的安全限制提示 - # ssl_context=('server.crt', 'server.key') - ) - - diff --git a/Html/runs/run_20250911-074447_ax0g50/code/app_back.py b/Html/runs/run_20250911-074447_ax0g50/code/app_back.py deleted file mode 100644 index 246853c..0000000 --- a/Html/runs/run_20250911-074447_ax0g50/code/app_back.py +++ /dev/null @@ -1,480 +0,0 @@ -from bootstrap import bootstrap_paths -bootstrap_paths() -from functools import wraps -from flask import Flask, redirect, session, request, jsonify, render_template, send_from_directory, url_for -from flask_cors import CORS -from flask_socketio import SocketIO, join_room, emit, Namespace -import markdown -import os -import uuid -import shutil -import sys -import json -from apps.auth.decorators import require_role -parent_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) -sys.path.insert(0, parent_dir) -student_workspace_root_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../study')) -current_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '.')) -sys.path.insert(0, current_dir) -from AlgoriAgent.projects.algoriAgent.agent_manager import AgentManager - - -import configparser - -from db.user_list import UserList -from db.user import User, load_user_from_json, create_user_json -from db.course_list import CourseList -from db.course import Course, load_course_from_json -GLOBAL_CONFIG = configparser.ConfigParser() -GLOBAL_CONFIG.read('config.ini') -VSCODE_WEB_URL = GLOBAL_CONFIG['VSCODE_WEB']['url'] -USER_DATA_DIR = GLOBAL_CONFIG['USER_DATA']['dir'] -COURSE_DATA_DIR = GLOBAL_CONFIG['COURSE_DATA']['dir'] - -app = Flask(__name__) -socketio = SocketIO(app, cors_allowed_origins="*",ping_timeout=60, ping_interval=5) -# socketio = SocketIO(app, cors_allowed_origins="http://localhost:9888") # 设置跨域支持 -import logging -app.secret_key = 'cakebaker' -app.logger.setLevel(logging.DEBUG) -# 配置 CORS -CORS(app, resources={r"/*": {"origins": VSCODE_WEB_URL},}, supports_credentials=True) - - -userid_recorder = {} # user_id&path -> session['user_id'] - -''' -Backboard -''' -from backboardManager import BackBoardManager, Backboard - -backboard_manager = BackBoardManager() -uuid2username = {} -username2uuid = {} - - - -# 定义命名空间:用于和 VSCode 插件交流 -class VSCodeNamespace(Namespace): - def on_login(self,data): - print("VSCode client connected") - print(data) - dataconfig = data['config'] - user_id = dataconfig.get('user_id') - path = dataconfig.get('path') - course_id = dataconfig.get('course_id') - lesson_id = dataconfig.get('chapter_id') - print(f"User {user_id} connected with path: {path}") - useruuid = username2uuid[user_id] - join_room(useruuid, namespace='/vscode') - if backboard_manager.get_backboard(useruuid) == None: - backboard_manager.add_backboard(useruuid,user_id, course_id, lesson_id, path) - - - def on_message(self, data): - print(f"Received from VSCode client: {data}") - dataconfig = data['config'] - realtime_response(dataconfig, data) - # emit('response', {'message': 'Config data received and connection established'}) - def on_disconnect(self, data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - -def realtime_response(config, realtime_action): - user_id = config['user_id'] - folder_path = config['path'] - useruuid = username2uuid[user_id] - bb = backboard_manager.get_backboard(useruuid) - assert type(bb) == Backboard - - bb.add_history(realtime_action) - - if realtime_action['type'] == 'workspaceFolders': - bb.file_tree = realtime_action['fileTree'] - - if realtime_action['type'] == 'activeFile': - file_path = realtime_action['filePath'] - assert type(file_path) == str - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - if realtime_action['type'] == 'paste': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.pasted_file_path = file_path - bb.pasted_content = realtime_action['content'] - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - if realtime_action['type'] == 'fileEdit': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - - - print("config"+str(config)) - print("realtime_action"+str(realtime_action)) - pass - - -''' -Agent and Chat -''' -agent_manager = AgentManager(app = app, socketio = socketio) -user_threads = {} -import threading -from concurrent.futures import ThreadPoolExecutor, as_completed - -# 初始化线程池 -executor = ThreadPoolExecutor(max_workers=10) -class AgentNamespace(Namespace): - def on_login(self, data): - data = json.loads(data) - user = data['username'] - course_id = data['course_id'] - chapter_id = data['chapter_id'] - user_uuid = username2uuid[user] - session['user_id'] = user_uuid - print(f'User connected with session user_id: {user_uuid}') - # 从markdown、markdown_prompts、score_prompts中各读取数据folder.md并进行new_agent - with open(f'books/markdown/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fmd,\ - open(f'books/markdown_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8')as fmdp,\ - open(f'books/score_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fsp: - markdown = fmd.read() - markdown_prompts = fmdp.read() - score_prompts = fsp.read() - user_uuid, agent = agent_manager.new_agent(course_id, chapter_id, markdown, markdown_prompts, score_prompts, id=user_uuid, - root_path=f'../../study/{user}/{course_id}/{chapter_id}') - print(user_uuid) - join_room(user_uuid, namespace='/agent') # 将该用户加入以user_id为名的room - backboard_manager.add_backboard(user_uuid, user, course_id, chapter_id, root_path=f'../../study/{user}/{course_id}/{chapter_id}') - - def on_language(self, language): - id = session.get('user_id') - agent_manager.change_language(id, language) - - def on_message(self, data): - print(f"Message from client: {data}") - id = session.get('user_id') - if (type(data)==str): - data = json.loads(data) - print(id) - if data['type'] == 'text': - res = agent_manager.invoke(id, data['data'], backboard_manager.get_backboard(id).get_info_prompt()) - print('=*='*20) - print(res.content) - reply = f"{res.content['speak']}" - with app.app_context(): - emit('message',reply, room=id, namespace='/agent') - emit('request_function',res.content['function'], room=id, namespace='/agent') - - if data['type'] == 'function': - agent_manager.function_call(id, data['data']) - - def on_initiative(self,data): - print("User active function call") - user_id = session['user_id'] - if data['name'] == 'sample_judge': - agent_manager.sample_judge(user_id, backboard_manager.get_backboard(user_id)) - if data['name'] == 'judge': - agent_manager.judge(user_id, backboard_manager.get_backboard(user_id)) - - - - def on_disconnect(self,data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - - -''' -Markdown to HTML -''' -# 配置文件路径 -MARKDOWN_DIR = 'books/markdown' # 存放 markdown 文件的文件夹 -STATIC_DIR = 'static' # 存放生成的 HTML 和图片资源的文件夹 -IMAGE_DIR = 'image' # 图片资源相对于 markdown 的位置 - - - -@app.route('/--markdown', methods=['GET']) -def convert_md(course_id, filename): - md_file_path = os.path.join(MARKDOWN_DIR,course_id, f'{filename}.md') - - if not os.path.exists(md_file_path): - return jsonify({'error': 'Markdown file not found'}), 404 - - # 读取 markdown 文件内容 - with open(md_file_path, 'r', encoding='utf-8') as file: - md_content = file.read() - - # 将 markdown 转换为 HTML - html_content = markdown.markdown(md_content) - # 插入 CSS 样式,限制图片最大宽度为 100%,高度自动调整 - html_with_styles = f""" - - - - - - - {html_content} - - - """ - # 保存 HTML 文件到 static 文件夹 - html_output_path = os.path.join(STATIC_DIR, f'{filename}.html') - with open(html_output_path, 'w', encoding='utf-8') as html_file: - html_file.write(html_with_styles) - - # 处理图片资源,将 image/xxx 文件夹拷贝到 static/image/xxx - image_source_dir = os.path.join(MARKDOWN_DIR,course_id, IMAGE_DIR, filename) - image_target_dir = os.path.join(STATIC_DIR, IMAGE_DIR, filename) - print(f"Copying image resources from {image_source_dir} to {image_target_dir}") - if os.path.exists(image_source_dir): - # 确保 static/image/xxx 目录存在 - if not os.path.exists(image_target_dir): - os.makedirs(image_target_dir) - - # 拷贝图片资源 - for image_file in os.listdir(image_source_dir): - full_image_file_path = os.path.join(image_source_dir, image_file) - if os.path.isfile(full_image_file_path): - shutil.copy(full_image_file_path, image_target_dir) - - return jsonify({'html_url': f'/static/{filename}.html'}) - -# 静态文件(HTML 和图片资源)的访问 -@app.route('/static/') -def serve_static(filename): - return send_from_directory(STATIC_DIR, filename) - - -''' -Vscode -''' -@app.route('/desktop///') -def desktop(user_id, course_id, chapter_id): - if 'user_id' not in session: - # return redirect(url_for('login')) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ user_id + "uuid is"+ session['user_id']) - username2uuid[user_id] = session['user_id'] - uuid2username[session['user_id']] = user_id - userid_recorder[user_id+'&'+course_id] = session['user_id'] - - # 在学习目录下创建一个名为 user_id_path 的文件夹 - path_dir = os.path.join(student_workspace_root_path, user_id, course_id,chapter_id) - os.makedirs(path_dir, exist_ok=True) - # 在此文件夹内部创建一个.config文件,并写入 user_id=user_id\n path=path - config_path = os.path.join(path_dir, '.config') - if GLOBAL_CONFIG['VSCODE_WEB_PATH']['is_wsl']: # 如果是在 WSL 中运行,则将路径转换为 WSL 路径 - path_dir = path_dir.replace('\\', '/') - path_dir = path_dir.replace(GLOBAL_CONFIG['VSCODE_WEB_PATH']['windows_path'] , GLOBAL_CONFIG['VSCODE_WEB_PATH']['wsl_path']) - with open(config_path, 'w', encoding='utf-8') as f: - tmpd = {'user_id': user_id, 'course_id': course_id, 'chapter_id': chapter_id, 'path': path_dir} - json.dump(tmpd, f) - print('---------------------') - print(config_path) - return render_template('desktop.html', vscode_web_url=VSCODE_WEB_URL, user_id=user_id, course_id=course_id, chapter_id=chapter_id, workspace_path=path_dir) - -@app.route('/desktop_nouser//') -def desktop_nouser(course_id, chapter_id): - if 'user_id' not in session: - return redirect(url_for('login')) - user_id = session['user_id'] - username = uuid2username[user_id] - return redirect(url_for('desktop', user_id=username, course_id=course_id, chapter_id=chapter_id)) - -@app.route('/vscode_data', methods=['POST']) -def vscode_data(): - data = request.json - config = data['config'] - realtime_response(config,data) - print(f"Received data from VSCode: {data}") - return jsonify({"status": "success", "received": data}) - - - -''' -Login - -''' -users_list = UserList() -course_list = CourseList() - - -@app.route('/register') -def register(): - return render_template('register.html') - -@app.route('/register_teacher') -def register_teacher(): - return render_template('register_teacher.html') - -@app.route('/register_teacher_post', methods=['POST']) -def register_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password, teacher=True) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - -@app.route('/register_post', methods=['POST']) -def register_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - - -@app.route('/login') -def login(): - return render_template('login.html') - if 'user_id' not in session: - return render_template('login.html') - else: - return redirect(url_for('/')) - -@app.route('/login_post', methods=['POST']) -def login_post(): - # 获取请求的 JSON 数据 - data = request.get_json() - - username = data.get('username') - password = data.get('password') - - pswd = users_list.get_user_pswd(username) - - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/login_teacher_post', methods=['POST']) -def login_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - pswd = users_list.get_user_pswd(username) - is_teacher = users_list.get_user_is_teacher(username) - if is_teacher is None or is_teacher == False: - return jsonify({'success': False, 'message': '用户名不存在或非教师账号'}) - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/teacherboard') -@require_role(roles="teacher") -def teacherboard(): - return render_template('teacherboard.html') - - -@app.route('/logout') -def logout(): - session.pop('user_id', None) - return redirect(url_for('login')) - -@app.route('/get_session') -def get_session(): - user_session = session.get('user_id', 'default_session') - return jsonify({"session": user_session}) - - -''' -DashBoard -''' -user_id2UserClass = {} -@app.route('/dashboard') -@require_role -def dashboard(): - user_id = session['user_id'] - username = uuid2username[user_id] - if (user_id not in user_id2UserClass): - user_id2UserClass[user_id] = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - user_course_data = [] - for course_id in user_id2UserClass[user_id].select_course: - course_brief_info = course_list.get_course_brief_info(course_id, load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR)) - user_course_data.append(course_brief_info) - return render_template('dashboard.html',user_data = user_id2UserClass[user_id].to_json_without_dialog(), user_course_data = json.dumps(user_course_data)) - -''' -Course -''' - -@app.route('/course/') -@require_role -def course(course_id): - c = load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR) - return render_template('course.html', course_id=course_id, course_data=c) - -@app.route('/select_course', methods=['POST']) -@require_role -def select_course(): - user = user_id2UserClass[session['user_id']] - data = request.get_json() - course_id = data.get('course_id') - if course_id: - user.select_new_course(course_id, load_course_from_json(course_id, COURSE_DATA_DIR)) - return jsonify({'success': True, 'message': '课程选择成功'}) - - -@app.route('/') -@require_role -def home_index(): - selected_courses=[] - if ('user_id' in session): - if (session['user_id'] not in user_id2UserClass): return redirect(url_for('login')) - user = user_id2UserClass[session['user_id']] - for course_id in user.select_course: - selected_courses.append(course_id) - - return render_template('index.html', courses_data = course_list, selected_courses =selected_courses) - -# 一些app辅助函数,主要提供给Agent与数据库的交互能力 - -class MyFunction: - def save_chapter_memory(self, id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal): - print("-=-=-=-=-=-=-=-") - print(id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - username = uuid2username[id] - u = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - u.save_chapter_memory(course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - -app.my_function = MyFunction() -if __name__ == '__main__': - socketio.on_namespace(VSCodeNamespace('/vscode')) - socketio.on_namespace(AgentNamespace('/agent')) - socketio.run(app, host='0.0.0.0', port=5551, debug=False,allow_unsafe_werkzeug=True) - diff --git a/Html/runs/run_20250911-074447_ax0g50/code/backboardManager.py b/Html/runs/run_20250911-074447_ax0g50/code/backboardManager.py deleted file mode 100644 index 7de5f19..0000000 --- a/Html/runs/run_20250911-074447_ax0g50/code/backboardManager.py +++ /dev/null @@ -1,80 +0,0 @@ - - - -import time -import os - -class Backboard: - def __init__(self, user_uuid, username, course_id, lesson_id, root_path): - self.user_uuid = user_uuid - self.username = username - self.course_id = course_id - self.lesson_id = lesson_id - self.root_path = root_path - self.create_time = time.time() - self.enter_chapter_time = time.time() - self.history = [] - self.file_tree = "[]" - self.active_file_path = "" - self.active_file_content = "" - self.pasted_file_path = "" - self.pasted_content = "" - - - def next_chapter(self): - self.enter_chapter_time = time.time() - - def get_info_prompt(self): - - five_history = "" - for h in self.history[-5:]: - five_history += h['type'] + "\n" + h.get('filePath', '') + "\n\n" - - endl = "\n" - return (f"###Global Info:###{endl}" - f"Here are some info about now user's IDE, refer to it when you need to handle some code.{endl}" - f"- User's total study time is {self.get_deltatime_mmss(self.create_time, time.time())}{endl}" - f"- User's current chapter study time is {self.get_deltatime_mmss(self.enter_chapter_time, time.time())}{endl}" - f"- Activated file path: {self.active_file_path}{endl}" - f"```{endl}" - f"{self.active_file_content[-10:]}{endl}" - f"```{endl}" - f"- Last five action:{five_history}{endl}" - f"- File tree: {self.file_tree}{endl}") - # f"- Activated file content (current editing 10 lines): {endl}" - def add_history(self, realtime_action): - if(realtime_action['type']=='config'):return - if len(self.history)!=0: - if (self.history[-1]['type']=='fileEdit'): - if(self.history[-1]['filePath'] == realtime_action['filePath']): - self.history[-1]['content'] = realtime_action['content'] - return - self.history.append(realtime_action) - - - def get_deltatime_mmss(self, start_time, end_time): - elapsed_time = end_time - start_time - hours = int(elapsed_time // 3600) - minutes = int((elapsed_time % 3600) // 60) - seconds = int(elapsed_time % 60) - return f"{hours:02d}:{minutes:02d}:{seconds:02d}" - - - def get_active_file_reletive_path(self): - relative_path = os.path.relpath(self.active_file_path, self.root_path) - return relative_path - - - -class BackBoardManager: - def __init__(self): - self.backboards = {} # user_uuid: Backboard - - def add_backboard(self, user_uuid, username, course_id, lesson_id, root_path): - self.backboards[user_uuid] = Backboard(user_uuid,username, course_id, lesson_id, root_path) - - def get_backboard(self, user_uuid) -> Backboard: - return self.backboards[user_uuid] - - - diff --git a/Html/runs/run_20250911-074447_ax0g50/code/bootstrap.py b/Html/runs/run_20250911-074447_ax0g50/code/bootstrap.py deleted file mode 100644 index bcb15ce..0000000 --- a/Html/runs/run_20250911-074447_ax0g50/code/bootstrap.py +++ /dev/null @@ -1,31 +0,0 @@ -from pathlib import Path -import sys, os - -def bootstrap_paths(): - """ - 让 'AlgoriAgent'(位于 repo_root/AlgoriAgent)可被 import; - 并提供 STUDENT_WORKSPACE_ROOT 的默认值(repo_root/study)。 - 适配当前工厂位置:repo_root/Html/apps/__init__.py - """ - here = Path(__file__).resolve() - # repo_root = .../Html/apps/../../ => parents[2] - repo_root = here.parents[2] - - # 兜底:如果目录结构变化,尝试向上搜索包含 AlgoriAgent 的目录作为 repo_root - if not (repo_root / "AlgoriAgent").exists(): - for p in here.parents: - if (p / "AlgoriAgent").is_dir(): - repo_root = p - break - - # 确保仓库根在 sys.path(这样 'AlgoriAgent' 顶层包可被发现) - repo_root_str = str(repo_root) - if repo_root_str not in sys.path: - sys.path.insert(0, repo_root_str) - - # 可选:如果你还有其它顶层包,也可在此处继续插入 - - # 默认学习工作区目录(也可放到 config.ini / 环境变量覆盖) - os.environ.setdefault("STUDENT_WORKSPACE_ROOT", str(repo_root / "study")) - - return repo_root # 方便调试/日志 \ No newline at end of file diff --git a/Html/runs/run_20250911-074447_ax0g50/code/wsgi.py b/Html/runs/run_20250911-074447_ax0g50/code/wsgi.py deleted file mode 100644 index bbcbe5f..0000000 --- a/Html/runs/run_20250911-074447_ax0g50/code/wsgi.py +++ /dev/null @@ -1,6 +0,0 @@ -# wsgi.py -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -# 提供一个可被 WSGI/进程管理器导入的 app 对象 -app = create_app() diff --git a/Html/runs/run_20250911-074447_ax0g50/logging.chat b/Html/runs/run_20250911-074447_ax0g50/logging.chat deleted file mode 100644 index e69de29..0000000 diff --git a/Html/runs/run_20250911-074447_ax0g50/logging.log b/Html/runs/run_20250911-074447_ax0g50/logging.log deleted file mode 100644 index 9748939..0000000 --- a/Html/runs/run_20250911-074447_ax0g50/logging.log +++ /dev/null @@ -1 +0,0 @@ -2025-09-11 07:44:54.725 | INFO | agentscope.models:read_model_configs:186 - Load configs for model wrapper: openai_cfg diff --git a/Html/runs/run_20250911-074454_2y1m70/.config b/Html/runs/run_20250911-074454_2y1m70/.config deleted file mode 100644 index a5339d1..0000000 --- a/Html/runs/run_20250911-074454_2y1m70/.config +++ /dev/null @@ -1,7 +0,0 @@ -{ - "project": "DJv2j4", - "name": "2y1m70", - "run_id": "run_20250911-074454_2y1m70", - "timestamp": "2025-09-11 07:44:54", - "pid": 1638 -} \ No newline at end of file diff --git a/Html/runs/run_20250911-074454_2y1m70/agentscope.db b/Html/runs/run_20250911-074454_2y1m70/agentscope.db deleted file mode 100644 index 666055b77679cda29c14fcf23b4ef1d039c5b52a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI%L2KJE6bEoS4Q(k)+glI2yjv3-0%NB!Hs&O1YUav`W0U1F<0V=#BsNLx(sSu$ z>=W&q?4#^B$!*yt2YT5l`~^0a^z(#~{ zkyg6w!t)u0!@f%5aeaJcfD9*Q_b$ozCY8>~CFA6|{Z2V!N;Z^cIq}eS$>x3HY|^=j z7lokrf1)Z$x@_R^N~@apn7OPMkZ(I<*1WJCw@v3GWy2n6&RcIQ0~zlR_x8^$%be!% zmxb7@7V;}H+K5#l(wSbZKXKY!mys6ROyi|!%aN@+%REpi?;B-K4PC3&{>iCzQnNB+ zwbW!z4iA{x(V_2L+5VJ1vMJeN;5l68yJ9?OZyl-TNCEp4P{^H8$cTGExdq$9ANE6@ zA@`ZUhb>is+Y=S?%$C1fnN{muZU1a!nMRV%#qFbMT;y3hf|KlJ)00Izz00bZa0SG_<0uX=z1a@EGHy1PL*Z=?k diff --git a/Html/runs/run_20250911-074454_2y1m70/code/app.py b/Html/runs/run_20250911-074454_2y1m70/code/app.py deleted file mode 100644 index c7f31f7..0000000 --- a/Html/runs/run_20250911-074454_2y1m70/code/app.py +++ /dev/null @@ -1,21 +0,0 @@ -# app.py 0.1.1 rise to factory mode -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -from apps.extensions import socketio - -# 工厂创建 app,工厂里已经做了:加载配置/注册蓝图/注册 namespaces -app = create_app() - -if __name__ == "__main__": - # 仅本地开发用;生产不要用 werkzeug 自带的开发服务器 - socketio.run( - app, - host="0.0.0.0", - port=5551, - debug=True, # 开发期打开 - allow_unsafe_werkzeug=True, # 避免 dev server 的安全限制提示 - # ssl_context=('server.crt', 'server.key') - ) - - diff --git a/Html/runs/run_20250911-074454_2y1m70/code/app_back.py b/Html/runs/run_20250911-074454_2y1m70/code/app_back.py deleted file mode 100644 index 246853c..0000000 --- a/Html/runs/run_20250911-074454_2y1m70/code/app_back.py +++ /dev/null @@ -1,480 +0,0 @@ -from bootstrap import bootstrap_paths -bootstrap_paths() -from functools import wraps -from flask import Flask, redirect, session, request, jsonify, render_template, send_from_directory, url_for -from flask_cors import CORS -from flask_socketio import SocketIO, join_room, emit, Namespace -import markdown -import os -import uuid -import shutil -import sys -import json -from apps.auth.decorators import require_role -parent_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) -sys.path.insert(0, parent_dir) -student_workspace_root_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../study')) -current_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '.')) -sys.path.insert(0, current_dir) -from AlgoriAgent.projects.algoriAgent.agent_manager import AgentManager - - -import configparser - -from db.user_list import UserList -from db.user import User, load_user_from_json, create_user_json -from db.course_list import CourseList -from db.course import Course, load_course_from_json -GLOBAL_CONFIG = configparser.ConfigParser() -GLOBAL_CONFIG.read('config.ini') -VSCODE_WEB_URL = GLOBAL_CONFIG['VSCODE_WEB']['url'] -USER_DATA_DIR = GLOBAL_CONFIG['USER_DATA']['dir'] -COURSE_DATA_DIR = GLOBAL_CONFIG['COURSE_DATA']['dir'] - -app = Flask(__name__) -socketio = SocketIO(app, cors_allowed_origins="*",ping_timeout=60, ping_interval=5) -# socketio = SocketIO(app, cors_allowed_origins="http://localhost:9888") # 设置跨域支持 -import logging -app.secret_key = 'cakebaker' -app.logger.setLevel(logging.DEBUG) -# 配置 CORS -CORS(app, resources={r"/*": {"origins": VSCODE_WEB_URL},}, supports_credentials=True) - - -userid_recorder = {} # user_id&path -> session['user_id'] - -''' -Backboard -''' -from backboardManager import BackBoardManager, Backboard - -backboard_manager = BackBoardManager() -uuid2username = {} -username2uuid = {} - - - -# 定义命名空间:用于和 VSCode 插件交流 -class VSCodeNamespace(Namespace): - def on_login(self,data): - print("VSCode client connected") - print(data) - dataconfig = data['config'] - user_id = dataconfig.get('user_id') - path = dataconfig.get('path') - course_id = dataconfig.get('course_id') - lesson_id = dataconfig.get('chapter_id') - print(f"User {user_id} connected with path: {path}") - useruuid = username2uuid[user_id] - join_room(useruuid, namespace='/vscode') - if backboard_manager.get_backboard(useruuid) == None: - backboard_manager.add_backboard(useruuid,user_id, course_id, lesson_id, path) - - - def on_message(self, data): - print(f"Received from VSCode client: {data}") - dataconfig = data['config'] - realtime_response(dataconfig, data) - # emit('response', {'message': 'Config data received and connection established'}) - def on_disconnect(self, data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - -def realtime_response(config, realtime_action): - user_id = config['user_id'] - folder_path = config['path'] - useruuid = username2uuid[user_id] - bb = backboard_manager.get_backboard(useruuid) - assert type(bb) == Backboard - - bb.add_history(realtime_action) - - if realtime_action['type'] == 'workspaceFolders': - bb.file_tree = realtime_action['fileTree'] - - if realtime_action['type'] == 'activeFile': - file_path = realtime_action['filePath'] - assert type(file_path) == str - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - if realtime_action['type'] == 'paste': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.pasted_file_path = file_path - bb.pasted_content = realtime_action['content'] - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - if realtime_action['type'] == 'fileEdit': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - - - print("config"+str(config)) - print("realtime_action"+str(realtime_action)) - pass - - -''' -Agent and Chat -''' -agent_manager = AgentManager(app = app, socketio = socketio) -user_threads = {} -import threading -from concurrent.futures import ThreadPoolExecutor, as_completed - -# 初始化线程池 -executor = ThreadPoolExecutor(max_workers=10) -class AgentNamespace(Namespace): - def on_login(self, data): - data = json.loads(data) - user = data['username'] - course_id = data['course_id'] - chapter_id = data['chapter_id'] - user_uuid = username2uuid[user] - session['user_id'] = user_uuid - print(f'User connected with session user_id: {user_uuid}') - # 从markdown、markdown_prompts、score_prompts中各读取数据folder.md并进行new_agent - with open(f'books/markdown/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fmd,\ - open(f'books/markdown_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8')as fmdp,\ - open(f'books/score_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fsp: - markdown = fmd.read() - markdown_prompts = fmdp.read() - score_prompts = fsp.read() - user_uuid, agent = agent_manager.new_agent(course_id, chapter_id, markdown, markdown_prompts, score_prompts, id=user_uuid, - root_path=f'../../study/{user}/{course_id}/{chapter_id}') - print(user_uuid) - join_room(user_uuid, namespace='/agent') # 将该用户加入以user_id为名的room - backboard_manager.add_backboard(user_uuid, user, course_id, chapter_id, root_path=f'../../study/{user}/{course_id}/{chapter_id}') - - def on_language(self, language): - id = session.get('user_id') - agent_manager.change_language(id, language) - - def on_message(self, data): - print(f"Message from client: {data}") - id = session.get('user_id') - if (type(data)==str): - data = json.loads(data) - print(id) - if data['type'] == 'text': - res = agent_manager.invoke(id, data['data'], backboard_manager.get_backboard(id).get_info_prompt()) - print('=*='*20) - print(res.content) - reply = f"{res.content['speak']}" - with app.app_context(): - emit('message',reply, room=id, namespace='/agent') - emit('request_function',res.content['function'], room=id, namespace='/agent') - - if data['type'] == 'function': - agent_manager.function_call(id, data['data']) - - def on_initiative(self,data): - print("User active function call") - user_id = session['user_id'] - if data['name'] == 'sample_judge': - agent_manager.sample_judge(user_id, backboard_manager.get_backboard(user_id)) - if data['name'] == 'judge': - agent_manager.judge(user_id, backboard_manager.get_backboard(user_id)) - - - - def on_disconnect(self,data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - - -''' -Markdown to HTML -''' -# 配置文件路径 -MARKDOWN_DIR = 'books/markdown' # 存放 markdown 文件的文件夹 -STATIC_DIR = 'static' # 存放生成的 HTML 和图片资源的文件夹 -IMAGE_DIR = 'image' # 图片资源相对于 markdown 的位置 - - - -@app.route('/--markdown', methods=['GET']) -def convert_md(course_id, filename): - md_file_path = os.path.join(MARKDOWN_DIR,course_id, f'{filename}.md') - - if not os.path.exists(md_file_path): - return jsonify({'error': 'Markdown file not found'}), 404 - - # 读取 markdown 文件内容 - with open(md_file_path, 'r', encoding='utf-8') as file: - md_content = file.read() - - # 将 markdown 转换为 HTML - html_content = markdown.markdown(md_content) - # 插入 CSS 样式,限制图片最大宽度为 100%,高度自动调整 - html_with_styles = f""" - - - - - - - {html_content} - - - """ - # 保存 HTML 文件到 static 文件夹 - html_output_path = os.path.join(STATIC_DIR, f'{filename}.html') - with open(html_output_path, 'w', encoding='utf-8') as html_file: - html_file.write(html_with_styles) - - # 处理图片资源,将 image/xxx 文件夹拷贝到 static/image/xxx - image_source_dir = os.path.join(MARKDOWN_DIR,course_id, IMAGE_DIR, filename) - image_target_dir = os.path.join(STATIC_DIR, IMAGE_DIR, filename) - print(f"Copying image resources from {image_source_dir} to {image_target_dir}") - if os.path.exists(image_source_dir): - # 确保 static/image/xxx 目录存在 - if not os.path.exists(image_target_dir): - os.makedirs(image_target_dir) - - # 拷贝图片资源 - for image_file in os.listdir(image_source_dir): - full_image_file_path = os.path.join(image_source_dir, image_file) - if os.path.isfile(full_image_file_path): - shutil.copy(full_image_file_path, image_target_dir) - - return jsonify({'html_url': f'/static/{filename}.html'}) - -# 静态文件(HTML 和图片资源)的访问 -@app.route('/static/') -def serve_static(filename): - return send_from_directory(STATIC_DIR, filename) - - -''' -Vscode -''' -@app.route('/desktop///') -def desktop(user_id, course_id, chapter_id): - if 'user_id' not in session: - # return redirect(url_for('login')) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ user_id + "uuid is"+ session['user_id']) - username2uuid[user_id] = session['user_id'] - uuid2username[session['user_id']] = user_id - userid_recorder[user_id+'&'+course_id] = session['user_id'] - - # 在学习目录下创建一个名为 user_id_path 的文件夹 - path_dir = os.path.join(student_workspace_root_path, user_id, course_id,chapter_id) - os.makedirs(path_dir, exist_ok=True) - # 在此文件夹内部创建一个.config文件,并写入 user_id=user_id\n path=path - config_path = os.path.join(path_dir, '.config') - if GLOBAL_CONFIG['VSCODE_WEB_PATH']['is_wsl']: # 如果是在 WSL 中运行,则将路径转换为 WSL 路径 - path_dir = path_dir.replace('\\', '/') - path_dir = path_dir.replace(GLOBAL_CONFIG['VSCODE_WEB_PATH']['windows_path'] , GLOBAL_CONFIG['VSCODE_WEB_PATH']['wsl_path']) - with open(config_path, 'w', encoding='utf-8') as f: - tmpd = {'user_id': user_id, 'course_id': course_id, 'chapter_id': chapter_id, 'path': path_dir} - json.dump(tmpd, f) - print('---------------------') - print(config_path) - return render_template('desktop.html', vscode_web_url=VSCODE_WEB_URL, user_id=user_id, course_id=course_id, chapter_id=chapter_id, workspace_path=path_dir) - -@app.route('/desktop_nouser//') -def desktop_nouser(course_id, chapter_id): - if 'user_id' not in session: - return redirect(url_for('login')) - user_id = session['user_id'] - username = uuid2username[user_id] - return redirect(url_for('desktop', user_id=username, course_id=course_id, chapter_id=chapter_id)) - -@app.route('/vscode_data', methods=['POST']) -def vscode_data(): - data = request.json - config = data['config'] - realtime_response(config,data) - print(f"Received data from VSCode: {data}") - return jsonify({"status": "success", "received": data}) - - - -''' -Login - -''' -users_list = UserList() -course_list = CourseList() - - -@app.route('/register') -def register(): - return render_template('register.html') - -@app.route('/register_teacher') -def register_teacher(): - return render_template('register_teacher.html') - -@app.route('/register_teacher_post', methods=['POST']) -def register_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password, teacher=True) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - -@app.route('/register_post', methods=['POST']) -def register_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - - -@app.route('/login') -def login(): - return render_template('login.html') - if 'user_id' not in session: - return render_template('login.html') - else: - return redirect(url_for('/')) - -@app.route('/login_post', methods=['POST']) -def login_post(): - # 获取请求的 JSON 数据 - data = request.get_json() - - username = data.get('username') - password = data.get('password') - - pswd = users_list.get_user_pswd(username) - - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/login_teacher_post', methods=['POST']) -def login_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - pswd = users_list.get_user_pswd(username) - is_teacher = users_list.get_user_is_teacher(username) - if is_teacher is None or is_teacher == False: - return jsonify({'success': False, 'message': '用户名不存在或非教师账号'}) - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/teacherboard') -@require_role(roles="teacher") -def teacherboard(): - return render_template('teacherboard.html') - - -@app.route('/logout') -def logout(): - session.pop('user_id', None) - return redirect(url_for('login')) - -@app.route('/get_session') -def get_session(): - user_session = session.get('user_id', 'default_session') - return jsonify({"session": user_session}) - - -''' -DashBoard -''' -user_id2UserClass = {} -@app.route('/dashboard') -@require_role -def dashboard(): - user_id = session['user_id'] - username = uuid2username[user_id] - if (user_id not in user_id2UserClass): - user_id2UserClass[user_id] = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - user_course_data = [] - for course_id in user_id2UserClass[user_id].select_course: - course_brief_info = course_list.get_course_brief_info(course_id, load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR)) - user_course_data.append(course_brief_info) - return render_template('dashboard.html',user_data = user_id2UserClass[user_id].to_json_without_dialog(), user_course_data = json.dumps(user_course_data)) - -''' -Course -''' - -@app.route('/course/') -@require_role -def course(course_id): - c = load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR) - return render_template('course.html', course_id=course_id, course_data=c) - -@app.route('/select_course', methods=['POST']) -@require_role -def select_course(): - user = user_id2UserClass[session['user_id']] - data = request.get_json() - course_id = data.get('course_id') - if course_id: - user.select_new_course(course_id, load_course_from_json(course_id, COURSE_DATA_DIR)) - return jsonify({'success': True, 'message': '课程选择成功'}) - - -@app.route('/') -@require_role -def home_index(): - selected_courses=[] - if ('user_id' in session): - if (session['user_id'] not in user_id2UserClass): return redirect(url_for('login')) - user = user_id2UserClass[session['user_id']] - for course_id in user.select_course: - selected_courses.append(course_id) - - return render_template('index.html', courses_data = course_list, selected_courses =selected_courses) - -# 一些app辅助函数,主要提供给Agent与数据库的交互能力 - -class MyFunction: - def save_chapter_memory(self, id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal): - print("-=-=-=-=-=-=-=-") - print(id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - username = uuid2username[id] - u = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - u.save_chapter_memory(course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - -app.my_function = MyFunction() -if __name__ == '__main__': - socketio.on_namespace(VSCodeNamespace('/vscode')) - socketio.on_namespace(AgentNamespace('/agent')) - socketio.run(app, host='0.0.0.0', port=5551, debug=False,allow_unsafe_werkzeug=True) - diff --git a/Html/runs/run_20250911-074454_2y1m70/code/backboardManager.py b/Html/runs/run_20250911-074454_2y1m70/code/backboardManager.py deleted file mode 100644 index 7de5f19..0000000 --- a/Html/runs/run_20250911-074454_2y1m70/code/backboardManager.py +++ /dev/null @@ -1,80 +0,0 @@ - - - -import time -import os - -class Backboard: - def __init__(self, user_uuid, username, course_id, lesson_id, root_path): - self.user_uuid = user_uuid - self.username = username - self.course_id = course_id - self.lesson_id = lesson_id - self.root_path = root_path - self.create_time = time.time() - self.enter_chapter_time = time.time() - self.history = [] - self.file_tree = "[]" - self.active_file_path = "" - self.active_file_content = "" - self.pasted_file_path = "" - self.pasted_content = "" - - - def next_chapter(self): - self.enter_chapter_time = time.time() - - def get_info_prompt(self): - - five_history = "" - for h in self.history[-5:]: - five_history += h['type'] + "\n" + h.get('filePath', '') + "\n\n" - - endl = "\n" - return (f"###Global Info:###{endl}" - f"Here are some info about now user's IDE, refer to it when you need to handle some code.{endl}" - f"- User's total study time is {self.get_deltatime_mmss(self.create_time, time.time())}{endl}" - f"- User's current chapter study time is {self.get_deltatime_mmss(self.enter_chapter_time, time.time())}{endl}" - f"- Activated file path: {self.active_file_path}{endl}" - f"```{endl}" - f"{self.active_file_content[-10:]}{endl}" - f"```{endl}" - f"- Last five action:{five_history}{endl}" - f"- File tree: {self.file_tree}{endl}") - # f"- Activated file content (current editing 10 lines): {endl}" - def add_history(self, realtime_action): - if(realtime_action['type']=='config'):return - if len(self.history)!=0: - if (self.history[-1]['type']=='fileEdit'): - if(self.history[-1]['filePath'] == realtime_action['filePath']): - self.history[-1]['content'] = realtime_action['content'] - return - self.history.append(realtime_action) - - - def get_deltatime_mmss(self, start_time, end_time): - elapsed_time = end_time - start_time - hours = int(elapsed_time // 3600) - minutes = int((elapsed_time % 3600) // 60) - seconds = int(elapsed_time % 60) - return f"{hours:02d}:{minutes:02d}:{seconds:02d}" - - - def get_active_file_reletive_path(self): - relative_path = os.path.relpath(self.active_file_path, self.root_path) - return relative_path - - - -class BackBoardManager: - def __init__(self): - self.backboards = {} # user_uuid: Backboard - - def add_backboard(self, user_uuid, username, course_id, lesson_id, root_path): - self.backboards[user_uuid] = Backboard(user_uuid,username, course_id, lesson_id, root_path) - - def get_backboard(self, user_uuid) -> Backboard: - return self.backboards[user_uuid] - - - diff --git a/Html/runs/run_20250911-074454_2y1m70/code/bootstrap.py b/Html/runs/run_20250911-074454_2y1m70/code/bootstrap.py deleted file mode 100644 index bcb15ce..0000000 --- a/Html/runs/run_20250911-074454_2y1m70/code/bootstrap.py +++ /dev/null @@ -1,31 +0,0 @@ -from pathlib import Path -import sys, os - -def bootstrap_paths(): - """ - 让 'AlgoriAgent'(位于 repo_root/AlgoriAgent)可被 import; - 并提供 STUDENT_WORKSPACE_ROOT 的默认值(repo_root/study)。 - 适配当前工厂位置:repo_root/Html/apps/__init__.py - """ - here = Path(__file__).resolve() - # repo_root = .../Html/apps/../../ => parents[2] - repo_root = here.parents[2] - - # 兜底:如果目录结构变化,尝试向上搜索包含 AlgoriAgent 的目录作为 repo_root - if not (repo_root / "AlgoriAgent").exists(): - for p in here.parents: - if (p / "AlgoriAgent").is_dir(): - repo_root = p - break - - # 确保仓库根在 sys.path(这样 'AlgoriAgent' 顶层包可被发现) - repo_root_str = str(repo_root) - if repo_root_str not in sys.path: - sys.path.insert(0, repo_root_str) - - # 可选:如果你还有其它顶层包,也可在此处继续插入 - - # 默认学习工作区目录(也可放到 config.ini / 环境变量覆盖) - os.environ.setdefault("STUDENT_WORKSPACE_ROOT", str(repo_root / "study")) - - return repo_root # 方便调试/日志 \ No newline at end of file diff --git a/Html/runs/run_20250911-074454_2y1m70/code/wsgi.py b/Html/runs/run_20250911-074454_2y1m70/code/wsgi.py deleted file mode 100644 index bbcbe5f..0000000 --- a/Html/runs/run_20250911-074454_2y1m70/code/wsgi.py +++ /dev/null @@ -1,6 +0,0 @@ -# wsgi.py -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -# 提供一个可被 WSGI/进程管理器导入的 app 对象 -app = create_app() diff --git a/Html/runs/run_20250911-074454_2y1m70/logging.chat b/Html/runs/run_20250911-074454_2y1m70/logging.chat deleted file mode 100644 index e69de29..0000000 diff --git a/Html/runs/run_20250911-074454_2y1m70/logging.log b/Html/runs/run_20250911-074454_2y1m70/logging.log deleted file mode 100644 index b2e97b5..0000000 --- a/Html/runs/run_20250911-074454_2y1m70/logging.log +++ /dev/null @@ -1 +0,0 @@ -2025-09-11 07:44:58.551 | INFO | agentscope.models:read_model_configs:186 - Load configs for model wrapper: openai_cfg diff --git a/Html/runs/run_20250911-074554_cwc4d6/.config b/Html/runs/run_20250911-074554_cwc4d6/.config deleted file mode 100644 index 5628897..0000000 --- a/Html/runs/run_20250911-074554_cwc4d6/.config +++ /dev/null @@ -1,7 +0,0 @@ -{ - "project": "1FlEIP", - "name": "cwc4d6", - "run_id": "run_20250911-074554_cwc4d6", - "timestamp": "2025-09-11 07:45:54", - "pid": 1982 -} \ No newline at end of file diff --git a/Html/runs/run_20250911-074554_cwc4d6/agentscope.db b/Html/runs/run_20250911-074554_cwc4d6/agentscope.db deleted file mode 100644 index 666055b77679cda29c14fcf23b4ef1d039c5b52a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI%L2KJE6bEoS4Q(k)+glI2yjv3-0%NB!Hs&O1YUav`W0U1F<0V=#BsNLx(sSu$ z>=W&q?4#^B$!*yt2YT5l`~^0a^z(#~{ zkyg6w!t)u0!@f%5aeaJcfD9*Q_b$ozCY8>~CFA6|{Z2V!N;Z^cIq}eS$>x3HY|^=j z7lokrf1)Z$x@_R^N~@apn7OPMkZ(I<*1WJCw@v3GWy2n6&RcIQ0~zlR_x8^$%be!% zmxb7@7V;}H+K5#l(wSbZKXKY!mys6ROyi|!%aN@+%REpi?;B-K4PC3&{>iCzQnNB+ zwbW!z4iA{x(V_2L+5VJ1vMJeN;5l68yJ9?OZyl-TNCEp4P{^H8$cTGExdq$9ANE6@ zA@`ZUhb>is+Y=S?%$C1fnN{muZU1a!nMRV%#qFbMT;y3hf|KlJ)00Izz00bZa0SG_<0uX=z1a@EGHy1PL*Z=?k diff --git a/Html/runs/run_20250911-074554_cwc4d6/code/app.py b/Html/runs/run_20250911-074554_cwc4d6/code/app.py deleted file mode 100644 index c7f31f7..0000000 --- a/Html/runs/run_20250911-074554_cwc4d6/code/app.py +++ /dev/null @@ -1,21 +0,0 @@ -# app.py 0.1.1 rise to factory mode -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -from apps.extensions import socketio - -# 工厂创建 app,工厂里已经做了:加载配置/注册蓝图/注册 namespaces -app = create_app() - -if __name__ == "__main__": - # 仅本地开发用;生产不要用 werkzeug 自带的开发服务器 - socketio.run( - app, - host="0.0.0.0", - port=5551, - debug=True, # 开发期打开 - allow_unsafe_werkzeug=True, # 避免 dev server 的安全限制提示 - # ssl_context=('server.crt', 'server.key') - ) - - diff --git a/Html/runs/run_20250911-074554_cwc4d6/code/app_back.py b/Html/runs/run_20250911-074554_cwc4d6/code/app_back.py deleted file mode 100644 index 246853c..0000000 --- a/Html/runs/run_20250911-074554_cwc4d6/code/app_back.py +++ /dev/null @@ -1,480 +0,0 @@ -from bootstrap import bootstrap_paths -bootstrap_paths() -from functools import wraps -from flask import Flask, redirect, session, request, jsonify, render_template, send_from_directory, url_for -from flask_cors import CORS -from flask_socketio import SocketIO, join_room, emit, Namespace -import markdown -import os -import uuid -import shutil -import sys -import json -from apps.auth.decorators import require_role -parent_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) -sys.path.insert(0, parent_dir) -student_workspace_root_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../study')) -current_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '.')) -sys.path.insert(0, current_dir) -from AlgoriAgent.projects.algoriAgent.agent_manager import AgentManager - - -import configparser - -from db.user_list import UserList -from db.user import User, load_user_from_json, create_user_json -from db.course_list import CourseList -from db.course import Course, load_course_from_json -GLOBAL_CONFIG = configparser.ConfigParser() -GLOBAL_CONFIG.read('config.ini') -VSCODE_WEB_URL = GLOBAL_CONFIG['VSCODE_WEB']['url'] -USER_DATA_DIR = GLOBAL_CONFIG['USER_DATA']['dir'] -COURSE_DATA_DIR = GLOBAL_CONFIG['COURSE_DATA']['dir'] - -app = Flask(__name__) -socketio = SocketIO(app, cors_allowed_origins="*",ping_timeout=60, ping_interval=5) -# socketio = SocketIO(app, cors_allowed_origins="http://localhost:9888") # 设置跨域支持 -import logging -app.secret_key = 'cakebaker' -app.logger.setLevel(logging.DEBUG) -# 配置 CORS -CORS(app, resources={r"/*": {"origins": VSCODE_WEB_URL},}, supports_credentials=True) - - -userid_recorder = {} # user_id&path -> session['user_id'] - -''' -Backboard -''' -from backboardManager import BackBoardManager, Backboard - -backboard_manager = BackBoardManager() -uuid2username = {} -username2uuid = {} - - - -# 定义命名空间:用于和 VSCode 插件交流 -class VSCodeNamespace(Namespace): - def on_login(self,data): - print("VSCode client connected") - print(data) - dataconfig = data['config'] - user_id = dataconfig.get('user_id') - path = dataconfig.get('path') - course_id = dataconfig.get('course_id') - lesson_id = dataconfig.get('chapter_id') - print(f"User {user_id} connected with path: {path}") - useruuid = username2uuid[user_id] - join_room(useruuid, namespace='/vscode') - if backboard_manager.get_backboard(useruuid) == None: - backboard_manager.add_backboard(useruuid,user_id, course_id, lesson_id, path) - - - def on_message(self, data): - print(f"Received from VSCode client: {data}") - dataconfig = data['config'] - realtime_response(dataconfig, data) - # emit('response', {'message': 'Config data received and connection established'}) - def on_disconnect(self, data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - -def realtime_response(config, realtime_action): - user_id = config['user_id'] - folder_path = config['path'] - useruuid = username2uuid[user_id] - bb = backboard_manager.get_backboard(useruuid) - assert type(bb) == Backboard - - bb.add_history(realtime_action) - - if realtime_action['type'] == 'workspaceFolders': - bb.file_tree = realtime_action['fileTree'] - - if realtime_action['type'] == 'activeFile': - file_path = realtime_action['filePath'] - assert type(file_path) == str - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - if realtime_action['type'] == 'paste': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.pasted_file_path = file_path - bb.pasted_content = realtime_action['content'] - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - if realtime_action['type'] == 'fileEdit': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - - - print("config"+str(config)) - print("realtime_action"+str(realtime_action)) - pass - - -''' -Agent and Chat -''' -agent_manager = AgentManager(app = app, socketio = socketio) -user_threads = {} -import threading -from concurrent.futures import ThreadPoolExecutor, as_completed - -# 初始化线程池 -executor = ThreadPoolExecutor(max_workers=10) -class AgentNamespace(Namespace): - def on_login(self, data): - data = json.loads(data) - user = data['username'] - course_id = data['course_id'] - chapter_id = data['chapter_id'] - user_uuid = username2uuid[user] - session['user_id'] = user_uuid - print(f'User connected with session user_id: {user_uuid}') - # 从markdown、markdown_prompts、score_prompts中各读取数据folder.md并进行new_agent - with open(f'books/markdown/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fmd,\ - open(f'books/markdown_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8')as fmdp,\ - open(f'books/score_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fsp: - markdown = fmd.read() - markdown_prompts = fmdp.read() - score_prompts = fsp.read() - user_uuid, agent = agent_manager.new_agent(course_id, chapter_id, markdown, markdown_prompts, score_prompts, id=user_uuid, - root_path=f'../../study/{user}/{course_id}/{chapter_id}') - print(user_uuid) - join_room(user_uuid, namespace='/agent') # 将该用户加入以user_id为名的room - backboard_manager.add_backboard(user_uuid, user, course_id, chapter_id, root_path=f'../../study/{user}/{course_id}/{chapter_id}') - - def on_language(self, language): - id = session.get('user_id') - agent_manager.change_language(id, language) - - def on_message(self, data): - print(f"Message from client: {data}") - id = session.get('user_id') - if (type(data)==str): - data = json.loads(data) - print(id) - if data['type'] == 'text': - res = agent_manager.invoke(id, data['data'], backboard_manager.get_backboard(id).get_info_prompt()) - print('=*='*20) - print(res.content) - reply = f"{res.content['speak']}" - with app.app_context(): - emit('message',reply, room=id, namespace='/agent') - emit('request_function',res.content['function'], room=id, namespace='/agent') - - if data['type'] == 'function': - agent_manager.function_call(id, data['data']) - - def on_initiative(self,data): - print("User active function call") - user_id = session['user_id'] - if data['name'] == 'sample_judge': - agent_manager.sample_judge(user_id, backboard_manager.get_backboard(user_id)) - if data['name'] == 'judge': - agent_manager.judge(user_id, backboard_manager.get_backboard(user_id)) - - - - def on_disconnect(self,data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - - -''' -Markdown to HTML -''' -# 配置文件路径 -MARKDOWN_DIR = 'books/markdown' # 存放 markdown 文件的文件夹 -STATIC_DIR = 'static' # 存放生成的 HTML 和图片资源的文件夹 -IMAGE_DIR = 'image' # 图片资源相对于 markdown 的位置 - - - -@app.route('/--markdown', methods=['GET']) -def convert_md(course_id, filename): - md_file_path = os.path.join(MARKDOWN_DIR,course_id, f'{filename}.md') - - if not os.path.exists(md_file_path): - return jsonify({'error': 'Markdown file not found'}), 404 - - # 读取 markdown 文件内容 - with open(md_file_path, 'r', encoding='utf-8') as file: - md_content = file.read() - - # 将 markdown 转换为 HTML - html_content = markdown.markdown(md_content) - # 插入 CSS 样式,限制图片最大宽度为 100%,高度自动调整 - html_with_styles = f""" - - - - - - - {html_content} - - - """ - # 保存 HTML 文件到 static 文件夹 - html_output_path = os.path.join(STATIC_DIR, f'{filename}.html') - with open(html_output_path, 'w', encoding='utf-8') as html_file: - html_file.write(html_with_styles) - - # 处理图片资源,将 image/xxx 文件夹拷贝到 static/image/xxx - image_source_dir = os.path.join(MARKDOWN_DIR,course_id, IMAGE_DIR, filename) - image_target_dir = os.path.join(STATIC_DIR, IMAGE_DIR, filename) - print(f"Copying image resources from {image_source_dir} to {image_target_dir}") - if os.path.exists(image_source_dir): - # 确保 static/image/xxx 目录存在 - if not os.path.exists(image_target_dir): - os.makedirs(image_target_dir) - - # 拷贝图片资源 - for image_file in os.listdir(image_source_dir): - full_image_file_path = os.path.join(image_source_dir, image_file) - if os.path.isfile(full_image_file_path): - shutil.copy(full_image_file_path, image_target_dir) - - return jsonify({'html_url': f'/static/{filename}.html'}) - -# 静态文件(HTML 和图片资源)的访问 -@app.route('/static/') -def serve_static(filename): - return send_from_directory(STATIC_DIR, filename) - - -''' -Vscode -''' -@app.route('/desktop///') -def desktop(user_id, course_id, chapter_id): - if 'user_id' not in session: - # return redirect(url_for('login')) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ user_id + "uuid is"+ session['user_id']) - username2uuid[user_id] = session['user_id'] - uuid2username[session['user_id']] = user_id - userid_recorder[user_id+'&'+course_id] = session['user_id'] - - # 在学习目录下创建一个名为 user_id_path 的文件夹 - path_dir = os.path.join(student_workspace_root_path, user_id, course_id,chapter_id) - os.makedirs(path_dir, exist_ok=True) - # 在此文件夹内部创建一个.config文件,并写入 user_id=user_id\n path=path - config_path = os.path.join(path_dir, '.config') - if GLOBAL_CONFIG['VSCODE_WEB_PATH']['is_wsl']: # 如果是在 WSL 中运行,则将路径转换为 WSL 路径 - path_dir = path_dir.replace('\\', '/') - path_dir = path_dir.replace(GLOBAL_CONFIG['VSCODE_WEB_PATH']['windows_path'] , GLOBAL_CONFIG['VSCODE_WEB_PATH']['wsl_path']) - with open(config_path, 'w', encoding='utf-8') as f: - tmpd = {'user_id': user_id, 'course_id': course_id, 'chapter_id': chapter_id, 'path': path_dir} - json.dump(tmpd, f) - print('---------------------') - print(config_path) - return render_template('desktop.html', vscode_web_url=VSCODE_WEB_URL, user_id=user_id, course_id=course_id, chapter_id=chapter_id, workspace_path=path_dir) - -@app.route('/desktop_nouser//') -def desktop_nouser(course_id, chapter_id): - if 'user_id' not in session: - return redirect(url_for('login')) - user_id = session['user_id'] - username = uuid2username[user_id] - return redirect(url_for('desktop', user_id=username, course_id=course_id, chapter_id=chapter_id)) - -@app.route('/vscode_data', methods=['POST']) -def vscode_data(): - data = request.json - config = data['config'] - realtime_response(config,data) - print(f"Received data from VSCode: {data}") - return jsonify({"status": "success", "received": data}) - - - -''' -Login - -''' -users_list = UserList() -course_list = CourseList() - - -@app.route('/register') -def register(): - return render_template('register.html') - -@app.route('/register_teacher') -def register_teacher(): - return render_template('register_teacher.html') - -@app.route('/register_teacher_post', methods=['POST']) -def register_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password, teacher=True) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - -@app.route('/register_post', methods=['POST']) -def register_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - - -@app.route('/login') -def login(): - return render_template('login.html') - if 'user_id' not in session: - return render_template('login.html') - else: - return redirect(url_for('/')) - -@app.route('/login_post', methods=['POST']) -def login_post(): - # 获取请求的 JSON 数据 - data = request.get_json() - - username = data.get('username') - password = data.get('password') - - pswd = users_list.get_user_pswd(username) - - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/login_teacher_post', methods=['POST']) -def login_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - pswd = users_list.get_user_pswd(username) - is_teacher = users_list.get_user_is_teacher(username) - if is_teacher is None or is_teacher == False: - return jsonify({'success': False, 'message': '用户名不存在或非教师账号'}) - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/teacherboard') -@require_role(roles="teacher") -def teacherboard(): - return render_template('teacherboard.html') - - -@app.route('/logout') -def logout(): - session.pop('user_id', None) - return redirect(url_for('login')) - -@app.route('/get_session') -def get_session(): - user_session = session.get('user_id', 'default_session') - return jsonify({"session": user_session}) - - -''' -DashBoard -''' -user_id2UserClass = {} -@app.route('/dashboard') -@require_role -def dashboard(): - user_id = session['user_id'] - username = uuid2username[user_id] - if (user_id not in user_id2UserClass): - user_id2UserClass[user_id] = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - user_course_data = [] - for course_id in user_id2UserClass[user_id].select_course: - course_brief_info = course_list.get_course_brief_info(course_id, load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR)) - user_course_data.append(course_brief_info) - return render_template('dashboard.html',user_data = user_id2UserClass[user_id].to_json_without_dialog(), user_course_data = json.dumps(user_course_data)) - -''' -Course -''' - -@app.route('/course/') -@require_role -def course(course_id): - c = load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR) - return render_template('course.html', course_id=course_id, course_data=c) - -@app.route('/select_course', methods=['POST']) -@require_role -def select_course(): - user = user_id2UserClass[session['user_id']] - data = request.get_json() - course_id = data.get('course_id') - if course_id: - user.select_new_course(course_id, load_course_from_json(course_id, COURSE_DATA_DIR)) - return jsonify({'success': True, 'message': '课程选择成功'}) - - -@app.route('/') -@require_role -def home_index(): - selected_courses=[] - if ('user_id' in session): - if (session['user_id'] not in user_id2UserClass): return redirect(url_for('login')) - user = user_id2UserClass[session['user_id']] - for course_id in user.select_course: - selected_courses.append(course_id) - - return render_template('index.html', courses_data = course_list, selected_courses =selected_courses) - -# 一些app辅助函数,主要提供给Agent与数据库的交互能力 - -class MyFunction: - def save_chapter_memory(self, id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal): - print("-=-=-=-=-=-=-=-") - print(id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - username = uuid2username[id] - u = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - u.save_chapter_memory(course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - -app.my_function = MyFunction() -if __name__ == '__main__': - socketio.on_namespace(VSCodeNamespace('/vscode')) - socketio.on_namespace(AgentNamespace('/agent')) - socketio.run(app, host='0.0.0.0', port=5551, debug=False,allow_unsafe_werkzeug=True) - diff --git a/Html/runs/run_20250911-074554_cwc4d6/code/backboardManager.py b/Html/runs/run_20250911-074554_cwc4d6/code/backboardManager.py deleted file mode 100644 index 7de5f19..0000000 --- a/Html/runs/run_20250911-074554_cwc4d6/code/backboardManager.py +++ /dev/null @@ -1,80 +0,0 @@ - - - -import time -import os - -class Backboard: - def __init__(self, user_uuid, username, course_id, lesson_id, root_path): - self.user_uuid = user_uuid - self.username = username - self.course_id = course_id - self.lesson_id = lesson_id - self.root_path = root_path - self.create_time = time.time() - self.enter_chapter_time = time.time() - self.history = [] - self.file_tree = "[]" - self.active_file_path = "" - self.active_file_content = "" - self.pasted_file_path = "" - self.pasted_content = "" - - - def next_chapter(self): - self.enter_chapter_time = time.time() - - def get_info_prompt(self): - - five_history = "" - for h in self.history[-5:]: - five_history += h['type'] + "\n" + h.get('filePath', '') + "\n\n" - - endl = "\n" - return (f"###Global Info:###{endl}" - f"Here are some info about now user's IDE, refer to it when you need to handle some code.{endl}" - f"- User's total study time is {self.get_deltatime_mmss(self.create_time, time.time())}{endl}" - f"- User's current chapter study time is {self.get_deltatime_mmss(self.enter_chapter_time, time.time())}{endl}" - f"- Activated file path: {self.active_file_path}{endl}" - f"```{endl}" - f"{self.active_file_content[-10:]}{endl}" - f"```{endl}" - f"- Last five action:{five_history}{endl}" - f"- File tree: {self.file_tree}{endl}") - # f"- Activated file content (current editing 10 lines): {endl}" - def add_history(self, realtime_action): - if(realtime_action['type']=='config'):return - if len(self.history)!=0: - if (self.history[-1]['type']=='fileEdit'): - if(self.history[-1]['filePath'] == realtime_action['filePath']): - self.history[-1]['content'] = realtime_action['content'] - return - self.history.append(realtime_action) - - - def get_deltatime_mmss(self, start_time, end_time): - elapsed_time = end_time - start_time - hours = int(elapsed_time // 3600) - minutes = int((elapsed_time % 3600) // 60) - seconds = int(elapsed_time % 60) - return f"{hours:02d}:{minutes:02d}:{seconds:02d}" - - - def get_active_file_reletive_path(self): - relative_path = os.path.relpath(self.active_file_path, self.root_path) - return relative_path - - - -class BackBoardManager: - def __init__(self): - self.backboards = {} # user_uuid: Backboard - - def add_backboard(self, user_uuid, username, course_id, lesson_id, root_path): - self.backboards[user_uuid] = Backboard(user_uuid,username, course_id, lesson_id, root_path) - - def get_backboard(self, user_uuid) -> Backboard: - return self.backboards[user_uuid] - - - diff --git a/Html/runs/run_20250911-074554_cwc4d6/code/bootstrap.py b/Html/runs/run_20250911-074554_cwc4d6/code/bootstrap.py deleted file mode 100644 index bcb15ce..0000000 --- a/Html/runs/run_20250911-074554_cwc4d6/code/bootstrap.py +++ /dev/null @@ -1,31 +0,0 @@ -from pathlib import Path -import sys, os - -def bootstrap_paths(): - """ - 让 'AlgoriAgent'(位于 repo_root/AlgoriAgent)可被 import; - 并提供 STUDENT_WORKSPACE_ROOT 的默认值(repo_root/study)。 - 适配当前工厂位置:repo_root/Html/apps/__init__.py - """ - here = Path(__file__).resolve() - # repo_root = .../Html/apps/../../ => parents[2] - repo_root = here.parents[2] - - # 兜底:如果目录结构变化,尝试向上搜索包含 AlgoriAgent 的目录作为 repo_root - if not (repo_root / "AlgoriAgent").exists(): - for p in here.parents: - if (p / "AlgoriAgent").is_dir(): - repo_root = p - break - - # 确保仓库根在 sys.path(这样 'AlgoriAgent' 顶层包可被发现) - repo_root_str = str(repo_root) - if repo_root_str not in sys.path: - sys.path.insert(0, repo_root_str) - - # 可选:如果你还有其它顶层包,也可在此处继续插入 - - # 默认学习工作区目录(也可放到 config.ini / 环境变量覆盖) - os.environ.setdefault("STUDENT_WORKSPACE_ROOT", str(repo_root / "study")) - - return repo_root # 方便调试/日志 \ No newline at end of file diff --git a/Html/runs/run_20250911-074554_cwc4d6/code/wsgi.py b/Html/runs/run_20250911-074554_cwc4d6/code/wsgi.py deleted file mode 100644 index bbcbe5f..0000000 --- a/Html/runs/run_20250911-074554_cwc4d6/code/wsgi.py +++ /dev/null @@ -1,6 +0,0 @@ -# wsgi.py -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -# 提供一个可被 WSGI/进程管理器导入的 app 对象 -app = create_app() diff --git a/Html/runs/run_20250911-074554_cwc4d6/logging.chat b/Html/runs/run_20250911-074554_cwc4d6/logging.chat deleted file mode 100644 index e69de29..0000000 diff --git a/Html/runs/run_20250911-074554_cwc4d6/logging.log b/Html/runs/run_20250911-074554_cwc4d6/logging.log deleted file mode 100644 index 40ac3ce..0000000 --- a/Html/runs/run_20250911-074554_cwc4d6/logging.log +++ /dev/null @@ -1 +0,0 @@ -2025-09-11 07:45:59.071 | INFO | agentscope.models:read_model_configs:186 - Load configs for model wrapper: openai_cfg diff --git a/Html/runs/run_20250911-074558_y0uxsk/.config b/Html/runs/run_20250911-074558_y0uxsk/.config deleted file mode 100644 index 7725606..0000000 --- a/Html/runs/run_20250911-074558_y0uxsk/.config +++ /dev/null @@ -1,7 +0,0 @@ -{ - "project": "VDfXVu", - "name": "y0uxsk", - "run_id": "run_20250911-074558_y0uxsk", - "timestamp": "2025-09-11 07:45:58", - "pid": 2000 -} \ No newline at end of file diff --git a/Html/runs/run_20250911-074558_y0uxsk/agentscope.db b/Html/runs/run_20250911-074558_y0uxsk/agentscope.db deleted file mode 100644 index 666055b77679cda29c14fcf23b4ef1d039c5b52a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI%L2KJE6bEoS4Q(k)+glI2yjv3-0%NB!Hs&O1YUav`W0U1F<0V=#BsNLx(sSu$ z>=W&q?4#^B$!*yt2YT5l`~^0a^z(#~{ zkyg6w!t)u0!@f%5aeaJcfD9*Q_b$ozCY8>~CFA6|{Z2V!N;Z^cIq}eS$>x3HY|^=j z7lokrf1)Z$x@_R^N~@apn7OPMkZ(I<*1WJCw@v3GWy2n6&RcIQ0~zlR_x8^$%be!% zmxb7@7V;}H+K5#l(wSbZKXKY!mys6ROyi|!%aN@+%REpi?;B-K4PC3&{>iCzQnNB+ zwbW!z4iA{x(V_2L+5VJ1vMJeN;5l68yJ9?OZyl-TNCEp4P{^H8$cTGExdq$9ANE6@ zA@`ZUhb>is+Y=S?%$C1fnN{muZU1a!nMRV%#qFbMT;y3hf|KlJ)00Izz00bZa0SG_<0uX=z1a@EGHy1PL*Z=?k diff --git a/Html/runs/run_20250911-074558_y0uxsk/code/app.py b/Html/runs/run_20250911-074558_y0uxsk/code/app.py deleted file mode 100644 index c7f31f7..0000000 --- a/Html/runs/run_20250911-074558_y0uxsk/code/app.py +++ /dev/null @@ -1,21 +0,0 @@ -# app.py 0.1.1 rise to factory mode -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -from apps.extensions import socketio - -# 工厂创建 app,工厂里已经做了:加载配置/注册蓝图/注册 namespaces -app = create_app() - -if __name__ == "__main__": - # 仅本地开发用;生产不要用 werkzeug 自带的开发服务器 - socketio.run( - app, - host="0.0.0.0", - port=5551, - debug=True, # 开发期打开 - allow_unsafe_werkzeug=True, # 避免 dev server 的安全限制提示 - # ssl_context=('server.crt', 'server.key') - ) - - diff --git a/Html/runs/run_20250911-074558_y0uxsk/code/app_back.py b/Html/runs/run_20250911-074558_y0uxsk/code/app_back.py deleted file mode 100644 index 246853c..0000000 --- a/Html/runs/run_20250911-074558_y0uxsk/code/app_back.py +++ /dev/null @@ -1,480 +0,0 @@ -from bootstrap import bootstrap_paths -bootstrap_paths() -from functools import wraps -from flask import Flask, redirect, session, request, jsonify, render_template, send_from_directory, url_for -from flask_cors import CORS -from flask_socketio import SocketIO, join_room, emit, Namespace -import markdown -import os -import uuid -import shutil -import sys -import json -from apps.auth.decorators import require_role -parent_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) -sys.path.insert(0, parent_dir) -student_workspace_root_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../study')) -current_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '.')) -sys.path.insert(0, current_dir) -from AlgoriAgent.projects.algoriAgent.agent_manager import AgentManager - - -import configparser - -from db.user_list import UserList -from db.user import User, load_user_from_json, create_user_json -from db.course_list import CourseList -from db.course import Course, load_course_from_json -GLOBAL_CONFIG = configparser.ConfigParser() -GLOBAL_CONFIG.read('config.ini') -VSCODE_WEB_URL = GLOBAL_CONFIG['VSCODE_WEB']['url'] -USER_DATA_DIR = GLOBAL_CONFIG['USER_DATA']['dir'] -COURSE_DATA_DIR = GLOBAL_CONFIG['COURSE_DATA']['dir'] - -app = Flask(__name__) -socketio = SocketIO(app, cors_allowed_origins="*",ping_timeout=60, ping_interval=5) -# socketio = SocketIO(app, cors_allowed_origins="http://localhost:9888") # 设置跨域支持 -import logging -app.secret_key = 'cakebaker' -app.logger.setLevel(logging.DEBUG) -# 配置 CORS -CORS(app, resources={r"/*": {"origins": VSCODE_WEB_URL},}, supports_credentials=True) - - -userid_recorder = {} # user_id&path -> session['user_id'] - -''' -Backboard -''' -from backboardManager import BackBoardManager, Backboard - -backboard_manager = BackBoardManager() -uuid2username = {} -username2uuid = {} - - - -# 定义命名空间:用于和 VSCode 插件交流 -class VSCodeNamespace(Namespace): - def on_login(self,data): - print("VSCode client connected") - print(data) - dataconfig = data['config'] - user_id = dataconfig.get('user_id') - path = dataconfig.get('path') - course_id = dataconfig.get('course_id') - lesson_id = dataconfig.get('chapter_id') - print(f"User {user_id} connected with path: {path}") - useruuid = username2uuid[user_id] - join_room(useruuid, namespace='/vscode') - if backboard_manager.get_backboard(useruuid) == None: - backboard_manager.add_backboard(useruuid,user_id, course_id, lesson_id, path) - - - def on_message(self, data): - print(f"Received from VSCode client: {data}") - dataconfig = data['config'] - realtime_response(dataconfig, data) - # emit('response', {'message': 'Config data received and connection established'}) - def on_disconnect(self, data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - -def realtime_response(config, realtime_action): - user_id = config['user_id'] - folder_path = config['path'] - useruuid = username2uuid[user_id] - bb = backboard_manager.get_backboard(useruuid) - assert type(bb) == Backboard - - bb.add_history(realtime_action) - - if realtime_action['type'] == 'workspaceFolders': - bb.file_tree = realtime_action['fileTree'] - - if realtime_action['type'] == 'activeFile': - file_path = realtime_action['filePath'] - assert type(file_path) == str - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - if realtime_action['type'] == 'paste': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.pasted_file_path = file_path - bb.pasted_content = realtime_action['content'] - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - if realtime_action['type'] == 'fileEdit': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - - - print("config"+str(config)) - print("realtime_action"+str(realtime_action)) - pass - - -''' -Agent and Chat -''' -agent_manager = AgentManager(app = app, socketio = socketio) -user_threads = {} -import threading -from concurrent.futures import ThreadPoolExecutor, as_completed - -# 初始化线程池 -executor = ThreadPoolExecutor(max_workers=10) -class AgentNamespace(Namespace): - def on_login(self, data): - data = json.loads(data) - user = data['username'] - course_id = data['course_id'] - chapter_id = data['chapter_id'] - user_uuid = username2uuid[user] - session['user_id'] = user_uuid - print(f'User connected with session user_id: {user_uuid}') - # 从markdown、markdown_prompts、score_prompts中各读取数据folder.md并进行new_agent - with open(f'books/markdown/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fmd,\ - open(f'books/markdown_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8')as fmdp,\ - open(f'books/score_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fsp: - markdown = fmd.read() - markdown_prompts = fmdp.read() - score_prompts = fsp.read() - user_uuid, agent = agent_manager.new_agent(course_id, chapter_id, markdown, markdown_prompts, score_prompts, id=user_uuid, - root_path=f'../../study/{user}/{course_id}/{chapter_id}') - print(user_uuid) - join_room(user_uuid, namespace='/agent') # 将该用户加入以user_id为名的room - backboard_manager.add_backboard(user_uuid, user, course_id, chapter_id, root_path=f'../../study/{user}/{course_id}/{chapter_id}') - - def on_language(self, language): - id = session.get('user_id') - agent_manager.change_language(id, language) - - def on_message(self, data): - print(f"Message from client: {data}") - id = session.get('user_id') - if (type(data)==str): - data = json.loads(data) - print(id) - if data['type'] == 'text': - res = agent_manager.invoke(id, data['data'], backboard_manager.get_backboard(id).get_info_prompt()) - print('=*='*20) - print(res.content) - reply = f"{res.content['speak']}" - with app.app_context(): - emit('message',reply, room=id, namespace='/agent') - emit('request_function',res.content['function'], room=id, namespace='/agent') - - if data['type'] == 'function': - agent_manager.function_call(id, data['data']) - - def on_initiative(self,data): - print("User active function call") - user_id = session['user_id'] - if data['name'] == 'sample_judge': - agent_manager.sample_judge(user_id, backboard_manager.get_backboard(user_id)) - if data['name'] == 'judge': - agent_manager.judge(user_id, backboard_manager.get_backboard(user_id)) - - - - def on_disconnect(self,data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - - -''' -Markdown to HTML -''' -# 配置文件路径 -MARKDOWN_DIR = 'books/markdown' # 存放 markdown 文件的文件夹 -STATIC_DIR = 'static' # 存放生成的 HTML 和图片资源的文件夹 -IMAGE_DIR = 'image' # 图片资源相对于 markdown 的位置 - - - -@app.route('/--markdown', methods=['GET']) -def convert_md(course_id, filename): - md_file_path = os.path.join(MARKDOWN_DIR,course_id, f'{filename}.md') - - if not os.path.exists(md_file_path): - return jsonify({'error': 'Markdown file not found'}), 404 - - # 读取 markdown 文件内容 - with open(md_file_path, 'r', encoding='utf-8') as file: - md_content = file.read() - - # 将 markdown 转换为 HTML - html_content = markdown.markdown(md_content) - # 插入 CSS 样式,限制图片最大宽度为 100%,高度自动调整 - html_with_styles = f""" - - - - - - - {html_content} - - - """ - # 保存 HTML 文件到 static 文件夹 - html_output_path = os.path.join(STATIC_DIR, f'{filename}.html') - with open(html_output_path, 'w', encoding='utf-8') as html_file: - html_file.write(html_with_styles) - - # 处理图片资源,将 image/xxx 文件夹拷贝到 static/image/xxx - image_source_dir = os.path.join(MARKDOWN_DIR,course_id, IMAGE_DIR, filename) - image_target_dir = os.path.join(STATIC_DIR, IMAGE_DIR, filename) - print(f"Copying image resources from {image_source_dir} to {image_target_dir}") - if os.path.exists(image_source_dir): - # 确保 static/image/xxx 目录存在 - if not os.path.exists(image_target_dir): - os.makedirs(image_target_dir) - - # 拷贝图片资源 - for image_file in os.listdir(image_source_dir): - full_image_file_path = os.path.join(image_source_dir, image_file) - if os.path.isfile(full_image_file_path): - shutil.copy(full_image_file_path, image_target_dir) - - return jsonify({'html_url': f'/static/{filename}.html'}) - -# 静态文件(HTML 和图片资源)的访问 -@app.route('/static/') -def serve_static(filename): - return send_from_directory(STATIC_DIR, filename) - - -''' -Vscode -''' -@app.route('/desktop///') -def desktop(user_id, course_id, chapter_id): - if 'user_id' not in session: - # return redirect(url_for('login')) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ user_id + "uuid is"+ session['user_id']) - username2uuid[user_id] = session['user_id'] - uuid2username[session['user_id']] = user_id - userid_recorder[user_id+'&'+course_id] = session['user_id'] - - # 在学习目录下创建一个名为 user_id_path 的文件夹 - path_dir = os.path.join(student_workspace_root_path, user_id, course_id,chapter_id) - os.makedirs(path_dir, exist_ok=True) - # 在此文件夹内部创建一个.config文件,并写入 user_id=user_id\n path=path - config_path = os.path.join(path_dir, '.config') - if GLOBAL_CONFIG['VSCODE_WEB_PATH']['is_wsl']: # 如果是在 WSL 中运行,则将路径转换为 WSL 路径 - path_dir = path_dir.replace('\\', '/') - path_dir = path_dir.replace(GLOBAL_CONFIG['VSCODE_WEB_PATH']['windows_path'] , GLOBAL_CONFIG['VSCODE_WEB_PATH']['wsl_path']) - with open(config_path, 'w', encoding='utf-8') as f: - tmpd = {'user_id': user_id, 'course_id': course_id, 'chapter_id': chapter_id, 'path': path_dir} - json.dump(tmpd, f) - print('---------------------') - print(config_path) - return render_template('desktop.html', vscode_web_url=VSCODE_WEB_URL, user_id=user_id, course_id=course_id, chapter_id=chapter_id, workspace_path=path_dir) - -@app.route('/desktop_nouser//') -def desktop_nouser(course_id, chapter_id): - if 'user_id' not in session: - return redirect(url_for('login')) - user_id = session['user_id'] - username = uuid2username[user_id] - return redirect(url_for('desktop', user_id=username, course_id=course_id, chapter_id=chapter_id)) - -@app.route('/vscode_data', methods=['POST']) -def vscode_data(): - data = request.json - config = data['config'] - realtime_response(config,data) - print(f"Received data from VSCode: {data}") - return jsonify({"status": "success", "received": data}) - - - -''' -Login - -''' -users_list = UserList() -course_list = CourseList() - - -@app.route('/register') -def register(): - return render_template('register.html') - -@app.route('/register_teacher') -def register_teacher(): - return render_template('register_teacher.html') - -@app.route('/register_teacher_post', methods=['POST']) -def register_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password, teacher=True) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - -@app.route('/register_post', methods=['POST']) -def register_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - - -@app.route('/login') -def login(): - return render_template('login.html') - if 'user_id' not in session: - return render_template('login.html') - else: - return redirect(url_for('/')) - -@app.route('/login_post', methods=['POST']) -def login_post(): - # 获取请求的 JSON 数据 - data = request.get_json() - - username = data.get('username') - password = data.get('password') - - pswd = users_list.get_user_pswd(username) - - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/login_teacher_post', methods=['POST']) -def login_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - pswd = users_list.get_user_pswd(username) - is_teacher = users_list.get_user_is_teacher(username) - if is_teacher is None or is_teacher == False: - return jsonify({'success': False, 'message': '用户名不存在或非教师账号'}) - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/teacherboard') -@require_role(roles="teacher") -def teacherboard(): - return render_template('teacherboard.html') - - -@app.route('/logout') -def logout(): - session.pop('user_id', None) - return redirect(url_for('login')) - -@app.route('/get_session') -def get_session(): - user_session = session.get('user_id', 'default_session') - return jsonify({"session": user_session}) - - -''' -DashBoard -''' -user_id2UserClass = {} -@app.route('/dashboard') -@require_role -def dashboard(): - user_id = session['user_id'] - username = uuid2username[user_id] - if (user_id not in user_id2UserClass): - user_id2UserClass[user_id] = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - user_course_data = [] - for course_id in user_id2UserClass[user_id].select_course: - course_brief_info = course_list.get_course_brief_info(course_id, load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR)) - user_course_data.append(course_brief_info) - return render_template('dashboard.html',user_data = user_id2UserClass[user_id].to_json_without_dialog(), user_course_data = json.dumps(user_course_data)) - -''' -Course -''' - -@app.route('/course/') -@require_role -def course(course_id): - c = load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR) - return render_template('course.html', course_id=course_id, course_data=c) - -@app.route('/select_course', methods=['POST']) -@require_role -def select_course(): - user = user_id2UserClass[session['user_id']] - data = request.get_json() - course_id = data.get('course_id') - if course_id: - user.select_new_course(course_id, load_course_from_json(course_id, COURSE_DATA_DIR)) - return jsonify({'success': True, 'message': '课程选择成功'}) - - -@app.route('/') -@require_role -def home_index(): - selected_courses=[] - if ('user_id' in session): - if (session['user_id'] not in user_id2UserClass): return redirect(url_for('login')) - user = user_id2UserClass[session['user_id']] - for course_id in user.select_course: - selected_courses.append(course_id) - - return render_template('index.html', courses_data = course_list, selected_courses =selected_courses) - -# 一些app辅助函数,主要提供给Agent与数据库的交互能力 - -class MyFunction: - def save_chapter_memory(self, id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal): - print("-=-=-=-=-=-=-=-") - print(id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - username = uuid2username[id] - u = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - u.save_chapter_memory(course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - -app.my_function = MyFunction() -if __name__ == '__main__': - socketio.on_namespace(VSCodeNamespace('/vscode')) - socketio.on_namespace(AgentNamespace('/agent')) - socketio.run(app, host='0.0.0.0', port=5551, debug=False,allow_unsafe_werkzeug=True) - diff --git a/Html/runs/run_20250911-074558_y0uxsk/code/backboardManager.py b/Html/runs/run_20250911-074558_y0uxsk/code/backboardManager.py deleted file mode 100644 index 7de5f19..0000000 --- a/Html/runs/run_20250911-074558_y0uxsk/code/backboardManager.py +++ /dev/null @@ -1,80 +0,0 @@ - - - -import time -import os - -class Backboard: - def __init__(self, user_uuid, username, course_id, lesson_id, root_path): - self.user_uuid = user_uuid - self.username = username - self.course_id = course_id - self.lesson_id = lesson_id - self.root_path = root_path - self.create_time = time.time() - self.enter_chapter_time = time.time() - self.history = [] - self.file_tree = "[]" - self.active_file_path = "" - self.active_file_content = "" - self.pasted_file_path = "" - self.pasted_content = "" - - - def next_chapter(self): - self.enter_chapter_time = time.time() - - def get_info_prompt(self): - - five_history = "" - for h in self.history[-5:]: - five_history += h['type'] + "\n" + h.get('filePath', '') + "\n\n" - - endl = "\n" - return (f"###Global Info:###{endl}" - f"Here are some info about now user's IDE, refer to it when you need to handle some code.{endl}" - f"- User's total study time is {self.get_deltatime_mmss(self.create_time, time.time())}{endl}" - f"- User's current chapter study time is {self.get_deltatime_mmss(self.enter_chapter_time, time.time())}{endl}" - f"- Activated file path: {self.active_file_path}{endl}" - f"```{endl}" - f"{self.active_file_content[-10:]}{endl}" - f"```{endl}" - f"- Last five action:{five_history}{endl}" - f"- File tree: {self.file_tree}{endl}") - # f"- Activated file content (current editing 10 lines): {endl}" - def add_history(self, realtime_action): - if(realtime_action['type']=='config'):return - if len(self.history)!=0: - if (self.history[-1]['type']=='fileEdit'): - if(self.history[-1]['filePath'] == realtime_action['filePath']): - self.history[-1]['content'] = realtime_action['content'] - return - self.history.append(realtime_action) - - - def get_deltatime_mmss(self, start_time, end_time): - elapsed_time = end_time - start_time - hours = int(elapsed_time // 3600) - minutes = int((elapsed_time % 3600) // 60) - seconds = int(elapsed_time % 60) - return f"{hours:02d}:{minutes:02d}:{seconds:02d}" - - - def get_active_file_reletive_path(self): - relative_path = os.path.relpath(self.active_file_path, self.root_path) - return relative_path - - - -class BackBoardManager: - def __init__(self): - self.backboards = {} # user_uuid: Backboard - - def add_backboard(self, user_uuid, username, course_id, lesson_id, root_path): - self.backboards[user_uuid] = Backboard(user_uuid,username, course_id, lesson_id, root_path) - - def get_backboard(self, user_uuid) -> Backboard: - return self.backboards[user_uuid] - - - diff --git a/Html/runs/run_20250911-074558_y0uxsk/code/bootstrap.py b/Html/runs/run_20250911-074558_y0uxsk/code/bootstrap.py deleted file mode 100644 index bcb15ce..0000000 --- a/Html/runs/run_20250911-074558_y0uxsk/code/bootstrap.py +++ /dev/null @@ -1,31 +0,0 @@ -from pathlib import Path -import sys, os - -def bootstrap_paths(): - """ - 让 'AlgoriAgent'(位于 repo_root/AlgoriAgent)可被 import; - 并提供 STUDENT_WORKSPACE_ROOT 的默认值(repo_root/study)。 - 适配当前工厂位置:repo_root/Html/apps/__init__.py - """ - here = Path(__file__).resolve() - # repo_root = .../Html/apps/../../ => parents[2] - repo_root = here.parents[2] - - # 兜底:如果目录结构变化,尝试向上搜索包含 AlgoriAgent 的目录作为 repo_root - if not (repo_root / "AlgoriAgent").exists(): - for p in here.parents: - if (p / "AlgoriAgent").is_dir(): - repo_root = p - break - - # 确保仓库根在 sys.path(这样 'AlgoriAgent' 顶层包可被发现) - repo_root_str = str(repo_root) - if repo_root_str not in sys.path: - sys.path.insert(0, repo_root_str) - - # 可选:如果你还有其它顶层包,也可在此处继续插入 - - # 默认学习工作区目录(也可放到 config.ini / 环境变量覆盖) - os.environ.setdefault("STUDENT_WORKSPACE_ROOT", str(repo_root / "study")) - - return repo_root # 方便调试/日志 \ No newline at end of file diff --git a/Html/runs/run_20250911-074558_y0uxsk/code/wsgi.py b/Html/runs/run_20250911-074558_y0uxsk/code/wsgi.py deleted file mode 100644 index bbcbe5f..0000000 --- a/Html/runs/run_20250911-074558_y0uxsk/code/wsgi.py +++ /dev/null @@ -1,6 +0,0 @@ -# wsgi.py -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -# 提供一个可被 WSGI/进程管理器导入的 app 对象 -app = create_app() diff --git a/Html/runs/run_20250911-074558_y0uxsk/logging.chat b/Html/runs/run_20250911-074558_y0uxsk/logging.chat deleted file mode 100644 index e69de29..0000000 diff --git a/Html/runs/run_20250911-074558_y0uxsk/logging.log b/Html/runs/run_20250911-074558_y0uxsk/logging.log deleted file mode 100644 index 44dd9da..0000000 --- a/Html/runs/run_20250911-074558_y0uxsk/logging.log +++ /dev/null @@ -1 +0,0 @@ -2025-09-11 07:46:02.787 | INFO | agentscope.models:read_model_configs:186 - Load configs for model wrapper: openai_cfg diff --git a/Html/runs/run_20250911-090314_4fof7d/.config b/Html/runs/run_20250911-090314_4fof7d/.config deleted file mode 100644 index ea63d86..0000000 --- a/Html/runs/run_20250911-090314_4fof7d/.config +++ /dev/null @@ -1,7 +0,0 @@ -{ - "project": "QbSwd3", - "name": "4fof7d", - "run_id": "run_20250911-090314_4fof7d", - "timestamp": "2025-09-11 09:03:14", - "pid": 11904 -} \ No newline at end of file diff --git a/Html/runs/run_20250911-090314_4fof7d/agentscope.db b/Html/runs/run_20250911-090314_4fof7d/agentscope.db deleted file mode 100644 index 666055b77679cda29c14fcf23b4ef1d039c5b52a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI%L2KJE6bEoS4Q(k)+glI2yjv3-0%NB!Hs&O1YUav`W0U1F<0V=#BsNLx(sSu$ z>=W&q?4#^B$!*yt2YT5l`~^0a^z(#~{ zkyg6w!t)u0!@f%5aeaJcfD9*Q_b$ozCY8>~CFA6|{Z2V!N;Z^cIq}eS$>x3HY|^=j z7lokrf1)Z$x@_R^N~@apn7OPMkZ(I<*1WJCw@v3GWy2n6&RcIQ0~zlR_x8^$%be!% zmxb7@7V;}H+K5#l(wSbZKXKY!mys6ROyi|!%aN@+%REpi?;B-K4PC3&{>iCzQnNB+ zwbW!z4iA{x(V_2L+5VJ1vMJeN;5l68yJ9?OZyl-TNCEp4P{^H8$cTGExdq$9ANE6@ zA@`ZUhb>is+Y=S?%$C1fnN{muZU1a!nMRV%#qFbMT;y3hf|KlJ)00Izz00bZa0SG_<0uX=z1a@EGHy1PL*Z=?k diff --git a/Html/runs/run_20250911-090314_4fof7d/code/app.py b/Html/runs/run_20250911-090314_4fof7d/code/app.py deleted file mode 100644 index c7f31f7..0000000 --- a/Html/runs/run_20250911-090314_4fof7d/code/app.py +++ /dev/null @@ -1,21 +0,0 @@ -# app.py 0.1.1 rise to factory mode -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -from apps.extensions import socketio - -# 工厂创建 app,工厂里已经做了:加载配置/注册蓝图/注册 namespaces -app = create_app() - -if __name__ == "__main__": - # 仅本地开发用;生产不要用 werkzeug 自带的开发服务器 - socketio.run( - app, - host="0.0.0.0", - port=5551, - debug=True, # 开发期打开 - allow_unsafe_werkzeug=True, # 避免 dev server 的安全限制提示 - # ssl_context=('server.crt', 'server.key') - ) - - diff --git a/Html/runs/run_20250911-090314_4fof7d/code/app_back.py b/Html/runs/run_20250911-090314_4fof7d/code/app_back.py deleted file mode 100644 index 246853c..0000000 --- a/Html/runs/run_20250911-090314_4fof7d/code/app_back.py +++ /dev/null @@ -1,480 +0,0 @@ -from bootstrap import bootstrap_paths -bootstrap_paths() -from functools import wraps -from flask import Flask, redirect, session, request, jsonify, render_template, send_from_directory, url_for -from flask_cors import CORS -from flask_socketio import SocketIO, join_room, emit, Namespace -import markdown -import os -import uuid -import shutil -import sys -import json -from apps.auth.decorators import require_role -parent_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) -sys.path.insert(0, parent_dir) -student_workspace_root_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../study')) -current_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '.')) -sys.path.insert(0, current_dir) -from AlgoriAgent.projects.algoriAgent.agent_manager import AgentManager - - -import configparser - -from db.user_list import UserList -from db.user import User, load_user_from_json, create_user_json -from db.course_list import CourseList -from db.course import Course, load_course_from_json -GLOBAL_CONFIG = configparser.ConfigParser() -GLOBAL_CONFIG.read('config.ini') -VSCODE_WEB_URL = GLOBAL_CONFIG['VSCODE_WEB']['url'] -USER_DATA_DIR = GLOBAL_CONFIG['USER_DATA']['dir'] -COURSE_DATA_DIR = GLOBAL_CONFIG['COURSE_DATA']['dir'] - -app = Flask(__name__) -socketio = SocketIO(app, cors_allowed_origins="*",ping_timeout=60, ping_interval=5) -# socketio = SocketIO(app, cors_allowed_origins="http://localhost:9888") # 设置跨域支持 -import logging -app.secret_key = 'cakebaker' -app.logger.setLevel(logging.DEBUG) -# 配置 CORS -CORS(app, resources={r"/*": {"origins": VSCODE_WEB_URL},}, supports_credentials=True) - - -userid_recorder = {} # user_id&path -> session['user_id'] - -''' -Backboard -''' -from backboardManager import BackBoardManager, Backboard - -backboard_manager = BackBoardManager() -uuid2username = {} -username2uuid = {} - - - -# 定义命名空间:用于和 VSCode 插件交流 -class VSCodeNamespace(Namespace): - def on_login(self,data): - print("VSCode client connected") - print(data) - dataconfig = data['config'] - user_id = dataconfig.get('user_id') - path = dataconfig.get('path') - course_id = dataconfig.get('course_id') - lesson_id = dataconfig.get('chapter_id') - print(f"User {user_id} connected with path: {path}") - useruuid = username2uuid[user_id] - join_room(useruuid, namespace='/vscode') - if backboard_manager.get_backboard(useruuid) == None: - backboard_manager.add_backboard(useruuid,user_id, course_id, lesson_id, path) - - - def on_message(self, data): - print(f"Received from VSCode client: {data}") - dataconfig = data['config'] - realtime_response(dataconfig, data) - # emit('response', {'message': 'Config data received and connection established'}) - def on_disconnect(self, data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - -def realtime_response(config, realtime_action): - user_id = config['user_id'] - folder_path = config['path'] - useruuid = username2uuid[user_id] - bb = backboard_manager.get_backboard(useruuid) - assert type(bb) == Backboard - - bb.add_history(realtime_action) - - if realtime_action['type'] == 'workspaceFolders': - bb.file_tree = realtime_action['fileTree'] - - if realtime_action['type'] == 'activeFile': - file_path = realtime_action['filePath'] - assert type(file_path) == str - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - if realtime_action['type'] == 'paste': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.pasted_file_path = file_path - bb.pasted_content = realtime_action['content'] - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - if realtime_action['type'] == 'fileEdit': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - - - print("config"+str(config)) - print("realtime_action"+str(realtime_action)) - pass - - -''' -Agent and Chat -''' -agent_manager = AgentManager(app = app, socketio = socketio) -user_threads = {} -import threading -from concurrent.futures import ThreadPoolExecutor, as_completed - -# 初始化线程池 -executor = ThreadPoolExecutor(max_workers=10) -class AgentNamespace(Namespace): - def on_login(self, data): - data = json.loads(data) - user = data['username'] - course_id = data['course_id'] - chapter_id = data['chapter_id'] - user_uuid = username2uuid[user] - session['user_id'] = user_uuid - print(f'User connected with session user_id: {user_uuid}') - # 从markdown、markdown_prompts、score_prompts中各读取数据folder.md并进行new_agent - with open(f'books/markdown/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fmd,\ - open(f'books/markdown_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8')as fmdp,\ - open(f'books/score_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fsp: - markdown = fmd.read() - markdown_prompts = fmdp.read() - score_prompts = fsp.read() - user_uuid, agent = agent_manager.new_agent(course_id, chapter_id, markdown, markdown_prompts, score_prompts, id=user_uuid, - root_path=f'../../study/{user}/{course_id}/{chapter_id}') - print(user_uuid) - join_room(user_uuid, namespace='/agent') # 将该用户加入以user_id为名的room - backboard_manager.add_backboard(user_uuid, user, course_id, chapter_id, root_path=f'../../study/{user}/{course_id}/{chapter_id}') - - def on_language(self, language): - id = session.get('user_id') - agent_manager.change_language(id, language) - - def on_message(self, data): - print(f"Message from client: {data}") - id = session.get('user_id') - if (type(data)==str): - data = json.loads(data) - print(id) - if data['type'] == 'text': - res = agent_manager.invoke(id, data['data'], backboard_manager.get_backboard(id).get_info_prompt()) - print('=*='*20) - print(res.content) - reply = f"{res.content['speak']}" - with app.app_context(): - emit('message',reply, room=id, namespace='/agent') - emit('request_function',res.content['function'], room=id, namespace='/agent') - - if data['type'] == 'function': - agent_manager.function_call(id, data['data']) - - def on_initiative(self,data): - print("User active function call") - user_id = session['user_id'] - if data['name'] == 'sample_judge': - agent_manager.sample_judge(user_id, backboard_manager.get_backboard(user_id)) - if data['name'] == 'judge': - agent_manager.judge(user_id, backboard_manager.get_backboard(user_id)) - - - - def on_disconnect(self,data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - - -''' -Markdown to HTML -''' -# 配置文件路径 -MARKDOWN_DIR = 'books/markdown' # 存放 markdown 文件的文件夹 -STATIC_DIR = 'static' # 存放生成的 HTML 和图片资源的文件夹 -IMAGE_DIR = 'image' # 图片资源相对于 markdown 的位置 - - - -@app.route('/--markdown', methods=['GET']) -def convert_md(course_id, filename): - md_file_path = os.path.join(MARKDOWN_DIR,course_id, f'{filename}.md') - - if not os.path.exists(md_file_path): - return jsonify({'error': 'Markdown file not found'}), 404 - - # 读取 markdown 文件内容 - with open(md_file_path, 'r', encoding='utf-8') as file: - md_content = file.read() - - # 将 markdown 转换为 HTML - html_content = markdown.markdown(md_content) - # 插入 CSS 样式,限制图片最大宽度为 100%,高度自动调整 - html_with_styles = f""" - - - - - - - {html_content} - - - """ - # 保存 HTML 文件到 static 文件夹 - html_output_path = os.path.join(STATIC_DIR, f'{filename}.html') - with open(html_output_path, 'w', encoding='utf-8') as html_file: - html_file.write(html_with_styles) - - # 处理图片资源,将 image/xxx 文件夹拷贝到 static/image/xxx - image_source_dir = os.path.join(MARKDOWN_DIR,course_id, IMAGE_DIR, filename) - image_target_dir = os.path.join(STATIC_DIR, IMAGE_DIR, filename) - print(f"Copying image resources from {image_source_dir} to {image_target_dir}") - if os.path.exists(image_source_dir): - # 确保 static/image/xxx 目录存在 - if not os.path.exists(image_target_dir): - os.makedirs(image_target_dir) - - # 拷贝图片资源 - for image_file in os.listdir(image_source_dir): - full_image_file_path = os.path.join(image_source_dir, image_file) - if os.path.isfile(full_image_file_path): - shutil.copy(full_image_file_path, image_target_dir) - - return jsonify({'html_url': f'/static/{filename}.html'}) - -# 静态文件(HTML 和图片资源)的访问 -@app.route('/static/') -def serve_static(filename): - return send_from_directory(STATIC_DIR, filename) - - -''' -Vscode -''' -@app.route('/desktop///') -def desktop(user_id, course_id, chapter_id): - if 'user_id' not in session: - # return redirect(url_for('login')) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ user_id + "uuid is"+ session['user_id']) - username2uuid[user_id] = session['user_id'] - uuid2username[session['user_id']] = user_id - userid_recorder[user_id+'&'+course_id] = session['user_id'] - - # 在学习目录下创建一个名为 user_id_path 的文件夹 - path_dir = os.path.join(student_workspace_root_path, user_id, course_id,chapter_id) - os.makedirs(path_dir, exist_ok=True) - # 在此文件夹内部创建一个.config文件,并写入 user_id=user_id\n path=path - config_path = os.path.join(path_dir, '.config') - if GLOBAL_CONFIG['VSCODE_WEB_PATH']['is_wsl']: # 如果是在 WSL 中运行,则将路径转换为 WSL 路径 - path_dir = path_dir.replace('\\', '/') - path_dir = path_dir.replace(GLOBAL_CONFIG['VSCODE_WEB_PATH']['windows_path'] , GLOBAL_CONFIG['VSCODE_WEB_PATH']['wsl_path']) - with open(config_path, 'w', encoding='utf-8') as f: - tmpd = {'user_id': user_id, 'course_id': course_id, 'chapter_id': chapter_id, 'path': path_dir} - json.dump(tmpd, f) - print('---------------------') - print(config_path) - return render_template('desktop.html', vscode_web_url=VSCODE_WEB_URL, user_id=user_id, course_id=course_id, chapter_id=chapter_id, workspace_path=path_dir) - -@app.route('/desktop_nouser//') -def desktop_nouser(course_id, chapter_id): - if 'user_id' not in session: - return redirect(url_for('login')) - user_id = session['user_id'] - username = uuid2username[user_id] - return redirect(url_for('desktop', user_id=username, course_id=course_id, chapter_id=chapter_id)) - -@app.route('/vscode_data', methods=['POST']) -def vscode_data(): - data = request.json - config = data['config'] - realtime_response(config,data) - print(f"Received data from VSCode: {data}") - return jsonify({"status": "success", "received": data}) - - - -''' -Login - -''' -users_list = UserList() -course_list = CourseList() - - -@app.route('/register') -def register(): - return render_template('register.html') - -@app.route('/register_teacher') -def register_teacher(): - return render_template('register_teacher.html') - -@app.route('/register_teacher_post', methods=['POST']) -def register_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password, teacher=True) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - -@app.route('/register_post', methods=['POST']) -def register_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - - -@app.route('/login') -def login(): - return render_template('login.html') - if 'user_id' not in session: - return render_template('login.html') - else: - return redirect(url_for('/')) - -@app.route('/login_post', methods=['POST']) -def login_post(): - # 获取请求的 JSON 数据 - data = request.get_json() - - username = data.get('username') - password = data.get('password') - - pswd = users_list.get_user_pswd(username) - - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/login_teacher_post', methods=['POST']) -def login_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - pswd = users_list.get_user_pswd(username) - is_teacher = users_list.get_user_is_teacher(username) - if is_teacher is None or is_teacher == False: - return jsonify({'success': False, 'message': '用户名不存在或非教师账号'}) - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/teacherboard') -@require_role(roles="teacher") -def teacherboard(): - return render_template('teacherboard.html') - - -@app.route('/logout') -def logout(): - session.pop('user_id', None) - return redirect(url_for('login')) - -@app.route('/get_session') -def get_session(): - user_session = session.get('user_id', 'default_session') - return jsonify({"session": user_session}) - - -''' -DashBoard -''' -user_id2UserClass = {} -@app.route('/dashboard') -@require_role -def dashboard(): - user_id = session['user_id'] - username = uuid2username[user_id] - if (user_id not in user_id2UserClass): - user_id2UserClass[user_id] = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - user_course_data = [] - for course_id in user_id2UserClass[user_id].select_course: - course_brief_info = course_list.get_course_brief_info(course_id, load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR)) - user_course_data.append(course_brief_info) - return render_template('dashboard.html',user_data = user_id2UserClass[user_id].to_json_without_dialog(), user_course_data = json.dumps(user_course_data)) - -''' -Course -''' - -@app.route('/course/') -@require_role -def course(course_id): - c = load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR) - return render_template('course.html', course_id=course_id, course_data=c) - -@app.route('/select_course', methods=['POST']) -@require_role -def select_course(): - user = user_id2UserClass[session['user_id']] - data = request.get_json() - course_id = data.get('course_id') - if course_id: - user.select_new_course(course_id, load_course_from_json(course_id, COURSE_DATA_DIR)) - return jsonify({'success': True, 'message': '课程选择成功'}) - - -@app.route('/') -@require_role -def home_index(): - selected_courses=[] - if ('user_id' in session): - if (session['user_id'] not in user_id2UserClass): return redirect(url_for('login')) - user = user_id2UserClass[session['user_id']] - for course_id in user.select_course: - selected_courses.append(course_id) - - return render_template('index.html', courses_data = course_list, selected_courses =selected_courses) - -# 一些app辅助函数,主要提供给Agent与数据库的交互能力 - -class MyFunction: - def save_chapter_memory(self, id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal): - print("-=-=-=-=-=-=-=-") - print(id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - username = uuid2username[id] - u = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - u.save_chapter_memory(course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - -app.my_function = MyFunction() -if __name__ == '__main__': - socketio.on_namespace(VSCodeNamespace('/vscode')) - socketio.on_namespace(AgentNamespace('/agent')) - socketio.run(app, host='0.0.0.0', port=5551, debug=False,allow_unsafe_werkzeug=True) - diff --git a/Html/runs/run_20250911-090314_4fof7d/code/backboardManager.py b/Html/runs/run_20250911-090314_4fof7d/code/backboardManager.py deleted file mode 100644 index 7de5f19..0000000 --- a/Html/runs/run_20250911-090314_4fof7d/code/backboardManager.py +++ /dev/null @@ -1,80 +0,0 @@ - - - -import time -import os - -class Backboard: - def __init__(self, user_uuid, username, course_id, lesson_id, root_path): - self.user_uuid = user_uuid - self.username = username - self.course_id = course_id - self.lesson_id = lesson_id - self.root_path = root_path - self.create_time = time.time() - self.enter_chapter_time = time.time() - self.history = [] - self.file_tree = "[]" - self.active_file_path = "" - self.active_file_content = "" - self.pasted_file_path = "" - self.pasted_content = "" - - - def next_chapter(self): - self.enter_chapter_time = time.time() - - def get_info_prompt(self): - - five_history = "" - for h in self.history[-5:]: - five_history += h['type'] + "\n" + h.get('filePath', '') + "\n\n" - - endl = "\n" - return (f"###Global Info:###{endl}" - f"Here are some info about now user's IDE, refer to it when you need to handle some code.{endl}" - f"- User's total study time is {self.get_deltatime_mmss(self.create_time, time.time())}{endl}" - f"- User's current chapter study time is {self.get_deltatime_mmss(self.enter_chapter_time, time.time())}{endl}" - f"- Activated file path: {self.active_file_path}{endl}" - f"```{endl}" - f"{self.active_file_content[-10:]}{endl}" - f"```{endl}" - f"- Last five action:{five_history}{endl}" - f"- File tree: {self.file_tree}{endl}") - # f"- Activated file content (current editing 10 lines): {endl}" - def add_history(self, realtime_action): - if(realtime_action['type']=='config'):return - if len(self.history)!=0: - if (self.history[-1]['type']=='fileEdit'): - if(self.history[-1]['filePath'] == realtime_action['filePath']): - self.history[-1]['content'] = realtime_action['content'] - return - self.history.append(realtime_action) - - - def get_deltatime_mmss(self, start_time, end_time): - elapsed_time = end_time - start_time - hours = int(elapsed_time // 3600) - minutes = int((elapsed_time % 3600) // 60) - seconds = int(elapsed_time % 60) - return f"{hours:02d}:{minutes:02d}:{seconds:02d}" - - - def get_active_file_reletive_path(self): - relative_path = os.path.relpath(self.active_file_path, self.root_path) - return relative_path - - - -class BackBoardManager: - def __init__(self): - self.backboards = {} # user_uuid: Backboard - - def add_backboard(self, user_uuid, username, course_id, lesson_id, root_path): - self.backboards[user_uuid] = Backboard(user_uuid,username, course_id, lesson_id, root_path) - - def get_backboard(self, user_uuid) -> Backboard: - return self.backboards[user_uuid] - - - diff --git a/Html/runs/run_20250911-090314_4fof7d/code/bootstrap.py b/Html/runs/run_20250911-090314_4fof7d/code/bootstrap.py deleted file mode 100644 index bcb15ce..0000000 --- a/Html/runs/run_20250911-090314_4fof7d/code/bootstrap.py +++ /dev/null @@ -1,31 +0,0 @@ -from pathlib import Path -import sys, os - -def bootstrap_paths(): - """ - 让 'AlgoriAgent'(位于 repo_root/AlgoriAgent)可被 import; - 并提供 STUDENT_WORKSPACE_ROOT 的默认值(repo_root/study)。 - 适配当前工厂位置:repo_root/Html/apps/__init__.py - """ - here = Path(__file__).resolve() - # repo_root = .../Html/apps/../../ => parents[2] - repo_root = here.parents[2] - - # 兜底:如果目录结构变化,尝试向上搜索包含 AlgoriAgent 的目录作为 repo_root - if not (repo_root / "AlgoriAgent").exists(): - for p in here.parents: - if (p / "AlgoriAgent").is_dir(): - repo_root = p - break - - # 确保仓库根在 sys.path(这样 'AlgoriAgent' 顶层包可被发现) - repo_root_str = str(repo_root) - if repo_root_str not in sys.path: - sys.path.insert(0, repo_root_str) - - # 可选:如果你还有其它顶层包,也可在此处继续插入 - - # 默认学习工作区目录(也可放到 config.ini / 环境变量覆盖) - os.environ.setdefault("STUDENT_WORKSPACE_ROOT", str(repo_root / "study")) - - return repo_root # 方便调试/日志 \ No newline at end of file diff --git a/Html/runs/run_20250911-090314_4fof7d/code/wsgi.py b/Html/runs/run_20250911-090314_4fof7d/code/wsgi.py deleted file mode 100644 index bbcbe5f..0000000 --- a/Html/runs/run_20250911-090314_4fof7d/code/wsgi.py +++ /dev/null @@ -1,6 +0,0 @@ -# wsgi.py -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -# 提供一个可被 WSGI/进程管理器导入的 app 对象 -app = create_app() diff --git a/Html/runs/run_20250911-090314_4fof7d/logging.chat b/Html/runs/run_20250911-090314_4fof7d/logging.chat deleted file mode 100644 index e69de29..0000000 diff --git a/Html/runs/run_20250911-090314_4fof7d/logging.log b/Html/runs/run_20250911-090314_4fof7d/logging.log deleted file mode 100644 index 2cc159d..0000000 --- a/Html/runs/run_20250911-090314_4fof7d/logging.log +++ /dev/null @@ -1 +0,0 @@ -2025-09-11 09:03:21.559 | INFO | agentscope.models:read_model_configs:186 - Load configs for model wrapper: openai_cfg diff --git a/Html/runs/run_20250911-090321_2uj10i/.config b/Html/runs/run_20250911-090321_2uj10i/.config deleted file mode 100644 index 7037e1c..0000000 --- a/Html/runs/run_20250911-090321_2uj10i/.config +++ /dev/null @@ -1,7 +0,0 @@ -{ - "project": "fmLQ7N", - "name": "2uj10i", - "run_id": "run_20250911-090321_2uj10i", - "timestamp": "2025-09-11 09:03:21", - "pid": 11941 -} \ No newline at end of file diff --git a/Html/runs/run_20250911-090321_2uj10i/agentscope.db b/Html/runs/run_20250911-090321_2uj10i/agentscope.db deleted file mode 100644 index 666055b77679cda29c14fcf23b4ef1d039c5b52a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI%L2KJE6bEoS4Q(k)+glI2yjv3-0%NB!Hs&O1YUav`W0U1F<0V=#BsNLx(sSu$ z>=W&q?4#^B$!*yt2YT5l`~^0a^z(#~{ zkyg6w!t)u0!@f%5aeaJcfD9*Q_b$ozCY8>~CFA6|{Z2V!N;Z^cIq}eS$>x3HY|^=j z7lokrf1)Z$x@_R^N~@apn7OPMkZ(I<*1WJCw@v3GWy2n6&RcIQ0~zlR_x8^$%be!% zmxb7@7V;}H+K5#l(wSbZKXKY!mys6ROyi|!%aN@+%REpi?;B-K4PC3&{>iCzQnNB+ zwbW!z4iA{x(V_2L+5VJ1vMJeN;5l68yJ9?OZyl-TNCEp4P{^H8$cTGExdq$9ANE6@ zA@`ZUhb>is+Y=S?%$C1fnN{muZU1a!nMRV%#qFbMT;y3hf|KlJ)00Izz00bZa0SG_<0uX=z1a@EGHy1PL*Z=?k diff --git a/Html/runs/run_20250911-090321_2uj10i/code/app.py b/Html/runs/run_20250911-090321_2uj10i/code/app.py deleted file mode 100644 index c7f31f7..0000000 --- a/Html/runs/run_20250911-090321_2uj10i/code/app.py +++ /dev/null @@ -1,21 +0,0 @@ -# app.py 0.1.1 rise to factory mode -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -from apps.extensions import socketio - -# 工厂创建 app,工厂里已经做了:加载配置/注册蓝图/注册 namespaces -app = create_app() - -if __name__ == "__main__": - # 仅本地开发用;生产不要用 werkzeug 自带的开发服务器 - socketio.run( - app, - host="0.0.0.0", - port=5551, - debug=True, # 开发期打开 - allow_unsafe_werkzeug=True, # 避免 dev server 的安全限制提示 - # ssl_context=('server.crt', 'server.key') - ) - - diff --git a/Html/runs/run_20250911-090321_2uj10i/code/app_back.py b/Html/runs/run_20250911-090321_2uj10i/code/app_back.py deleted file mode 100644 index 246853c..0000000 --- a/Html/runs/run_20250911-090321_2uj10i/code/app_back.py +++ /dev/null @@ -1,480 +0,0 @@ -from bootstrap import bootstrap_paths -bootstrap_paths() -from functools import wraps -from flask import Flask, redirect, session, request, jsonify, render_template, send_from_directory, url_for -from flask_cors import CORS -from flask_socketio import SocketIO, join_room, emit, Namespace -import markdown -import os -import uuid -import shutil -import sys -import json -from apps.auth.decorators import require_role -parent_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) -sys.path.insert(0, parent_dir) -student_workspace_root_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../study')) -current_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '.')) -sys.path.insert(0, current_dir) -from AlgoriAgent.projects.algoriAgent.agent_manager import AgentManager - - -import configparser - -from db.user_list import UserList -from db.user import User, load_user_from_json, create_user_json -from db.course_list import CourseList -from db.course import Course, load_course_from_json -GLOBAL_CONFIG = configparser.ConfigParser() -GLOBAL_CONFIG.read('config.ini') -VSCODE_WEB_URL = GLOBAL_CONFIG['VSCODE_WEB']['url'] -USER_DATA_DIR = GLOBAL_CONFIG['USER_DATA']['dir'] -COURSE_DATA_DIR = GLOBAL_CONFIG['COURSE_DATA']['dir'] - -app = Flask(__name__) -socketio = SocketIO(app, cors_allowed_origins="*",ping_timeout=60, ping_interval=5) -# socketio = SocketIO(app, cors_allowed_origins="http://localhost:9888") # 设置跨域支持 -import logging -app.secret_key = 'cakebaker' -app.logger.setLevel(logging.DEBUG) -# 配置 CORS -CORS(app, resources={r"/*": {"origins": VSCODE_WEB_URL},}, supports_credentials=True) - - -userid_recorder = {} # user_id&path -> session['user_id'] - -''' -Backboard -''' -from backboardManager import BackBoardManager, Backboard - -backboard_manager = BackBoardManager() -uuid2username = {} -username2uuid = {} - - - -# 定义命名空间:用于和 VSCode 插件交流 -class VSCodeNamespace(Namespace): - def on_login(self,data): - print("VSCode client connected") - print(data) - dataconfig = data['config'] - user_id = dataconfig.get('user_id') - path = dataconfig.get('path') - course_id = dataconfig.get('course_id') - lesson_id = dataconfig.get('chapter_id') - print(f"User {user_id} connected with path: {path}") - useruuid = username2uuid[user_id] - join_room(useruuid, namespace='/vscode') - if backboard_manager.get_backboard(useruuid) == None: - backboard_manager.add_backboard(useruuid,user_id, course_id, lesson_id, path) - - - def on_message(self, data): - print(f"Received from VSCode client: {data}") - dataconfig = data['config'] - realtime_response(dataconfig, data) - # emit('response', {'message': 'Config data received and connection established'}) - def on_disconnect(self, data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - -def realtime_response(config, realtime_action): - user_id = config['user_id'] - folder_path = config['path'] - useruuid = username2uuid[user_id] - bb = backboard_manager.get_backboard(useruuid) - assert type(bb) == Backboard - - bb.add_history(realtime_action) - - if realtime_action['type'] == 'workspaceFolders': - bb.file_tree = realtime_action['fileTree'] - - if realtime_action['type'] == 'activeFile': - file_path = realtime_action['filePath'] - assert type(file_path) == str - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - if realtime_action['type'] == 'paste': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.pasted_file_path = file_path - bb.pasted_content = realtime_action['content'] - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - if realtime_action['type'] == 'fileEdit': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - - - print("config"+str(config)) - print("realtime_action"+str(realtime_action)) - pass - - -''' -Agent and Chat -''' -agent_manager = AgentManager(app = app, socketio = socketio) -user_threads = {} -import threading -from concurrent.futures import ThreadPoolExecutor, as_completed - -# 初始化线程池 -executor = ThreadPoolExecutor(max_workers=10) -class AgentNamespace(Namespace): - def on_login(self, data): - data = json.loads(data) - user = data['username'] - course_id = data['course_id'] - chapter_id = data['chapter_id'] - user_uuid = username2uuid[user] - session['user_id'] = user_uuid - print(f'User connected with session user_id: {user_uuid}') - # 从markdown、markdown_prompts、score_prompts中各读取数据folder.md并进行new_agent - with open(f'books/markdown/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fmd,\ - open(f'books/markdown_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8')as fmdp,\ - open(f'books/score_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fsp: - markdown = fmd.read() - markdown_prompts = fmdp.read() - score_prompts = fsp.read() - user_uuid, agent = agent_manager.new_agent(course_id, chapter_id, markdown, markdown_prompts, score_prompts, id=user_uuid, - root_path=f'../../study/{user}/{course_id}/{chapter_id}') - print(user_uuid) - join_room(user_uuid, namespace='/agent') # 将该用户加入以user_id为名的room - backboard_manager.add_backboard(user_uuid, user, course_id, chapter_id, root_path=f'../../study/{user}/{course_id}/{chapter_id}') - - def on_language(self, language): - id = session.get('user_id') - agent_manager.change_language(id, language) - - def on_message(self, data): - print(f"Message from client: {data}") - id = session.get('user_id') - if (type(data)==str): - data = json.loads(data) - print(id) - if data['type'] == 'text': - res = agent_manager.invoke(id, data['data'], backboard_manager.get_backboard(id).get_info_prompt()) - print('=*='*20) - print(res.content) - reply = f"{res.content['speak']}" - with app.app_context(): - emit('message',reply, room=id, namespace='/agent') - emit('request_function',res.content['function'], room=id, namespace='/agent') - - if data['type'] == 'function': - agent_manager.function_call(id, data['data']) - - def on_initiative(self,data): - print("User active function call") - user_id = session['user_id'] - if data['name'] == 'sample_judge': - agent_manager.sample_judge(user_id, backboard_manager.get_backboard(user_id)) - if data['name'] == 'judge': - agent_manager.judge(user_id, backboard_manager.get_backboard(user_id)) - - - - def on_disconnect(self,data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - - -''' -Markdown to HTML -''' -# 配置文件路径 -MARKDOWN_DIR = 'books/markdown' # 存放 markdown 文件的文件夹 -STATIC_DIR = 'static' # 存放生成的 HTML 和图片资源的文件夹 -IMAGE_DIR = 'image' # 图片资源相对于 markdown 的位置 - - - -@app.route('/--markdown', methods=['GET']) -def convert_md(course_id, filename): - md_file_path = os.path.join(MARKDOWN_DIR,course_id, f'{filename}.md') - - if not os.path.exists(md_file_path): - return jsonify({'error': 'Markdown file not found'}), 404 - - # 读取 markdown 文件内容 - with open(md_file_path, 'r', encoding='utf-8') as file: - md_content = file.read() - - # 将 markdown 转换为 HTML - html_content = markdown.markdown(md_content) - # 插入 CSS 样式,限制图片最大宽度为 100%,高度自动调整 - html_with_styles = f""" - - - - - - - {html_content} - - - """ - # 保存 HTML 文件到 static 文件夹 - html_output_path = os.path.join(STATIC_DIR, f'{filename}.html') - with open(html_output_path, 'w', encoding='utf-8') as html_file: - html_file.write(html_with_styles) - - # 处理图片资源,将 image/xxx 文件夹拷贝到 static/image/xxx - image_source_dir = os.path.join(MARKDOWN_DIR,course_id, IMAGE_DIR, filename) - image_target_dir = os.path.join(STATIC_DIR, IMAGE_DIR, filename) - print(f"Copying image resources from {image_source_dir} to {image_target_dir}") - if os.path.exists(image_source_dir): - # 确保 static/image/xxx 目录存在 - if not os.path.exists(image_target_dir): - os.makedirs(image_target_dir) - - # 拷贝图片资源 - for image_file in os.listdir(image_source_dir): - full_image_file_path = os.path.join(image_source_dir, image_file) - if os.path.isfile(full_image_file_path): - shutil.copy(full_image_file_path, image_target_dir) - - return jsonify({'html_url': f'/static/{filename}.html'}) - -# 静态文件(HTML 和图片资源)的访问 -@app.route('/static/') -def serve_static(filename): - return send_from_directory(STATIC_DIR, filename) - - -''' -Vscode -''' -@app.route('/desktop///') -def desktop(user_id, course_id, chapter_id): - if 'user_id' not in session: - # return redirect(url_for('login')) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ user_id + "uuid is"+ session['user_id']) - username2uuid[user_id] = session['user_id'] - uuid2username[session['user_id']] = user_id - userid_recorder[user_id+'&'+course_id] = session['user_id'] - - # 在学习目录下创建一个名为 user_id_path 的文件夹 - path_dir = os.path.join(student_workspace_root_path, user_id, course_id,chapter_id) - os.makedirs(path_dir, exist_ok=True) - # 在此文件夹内部创建一个.config文件,并写入 user_id=user_id\n path=path - config_path = os.path.join(path_dir, '.config') - if GLOBAL_CONFIG['VSCODE_WEB_PATH']['is_wsl']: # 如果是在 WSL 中运行,则将路径转换为 WSL 路径 - path_dir = path_dir.replace('\\', '/') - path_dir = path_dir.replace(GLOBAL_CONFIG['VSCODE_WEB_PATH']['windows_path'] , GLOBAL_CONFIG['VSCODE_WEB_PATH']['wsl_path']) - with open(config_path, 'w', encoding='utf-8') as f: - tmpd = {'user_id': user_id, 'course_id': course_id, 'chapter_id': chapter_id, 'path': path_dir} - json.dump(tmpd, f) - print('---------------------') - print(config_path) - return render_template('desktop.html', vscode_web_url=VSCODE_WEB_URL, user_id=user_id, course_id=course_id, chapter_id=chapter_id, workspace_path=path_dir) - -@app.route('/desktop_nouser//') -def desktop_nouser(course_id, chapter_id): - if 'user_id' not in session: - return redirect(url_for('login')) - user_id = session['user_id'] - username = uuid2username[user_id] - return redirect(url_for('desktop', user_id=username, course_id=course_id, chapter_id=chapter_id)) - -@app.route('/vscode_data', methods=['POST']) -def vscode_data(): - data = request.json - config = data['config'] - realtime_response(config,data) - print(f"Received data from VSCode: {data}") - return jsonify({"status": "success", "received": data}) - - - -''' -Login - -''' -users_list = UserList() -course_list = CourseList() - - -@app.route('/register') -def register(): - return render_template('register.html') - -@app.route('/register_teacher') -def register_teacher(): - return render_template('register_teacher.html') - -@app.route('/register_teacher_post', methods=['POST']) -def register_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password, teacher=True) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - -@app.route('/register_post', methods=['POST']) -def register_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - - -@app.route('/login') -def login(): - return render_template('login.html') - if 'user_id' not in session: - return render_template('login.html') - else: - return redirect(url_for('/')) - -@app.route('/login_post', methods=['POST']) -def login_post(): - # 获取请求的 JSON 数据 - data = request.get_json() - - username = data.get('username') - password = data.get('password') - - pswd = users_list.get_user_pswd(username) - - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/login_teacher_post', methods=['POST']) -def login_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - pswd = users_list.get_user_pswd(username) - is_teacher = users_list.get_user_is_teacher(username) - if is_teacher is None or is_teacher == False: - return jsonify({'success': False, 'message': '用户名不存在或非教师账号'}) - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/teacherboard') -@require_role(roles="teacher") -def teacherboard(): - return render_template('teacherboard.html') - - -@app.route('/logout') -def logout(): - session.pop('user_id', None) - return redirect(url_for('login')) - -@app.route('/get_session') -def get_session(): - user_session = session.get('user_id', 'default_session') - return jsonify({"session": user_session}) - - -''' -DashBoard -''' -user_id2UserClass = {} -@app.route('/dashboard') -@require_role -def dashboard(): - user_id = session['user_id'] - username = uuid2username[user_id] - if (user_id not in user_id2UserClass): - user_id2UserClass[user_id] = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - user_course_data = [] - for course_id in user_id2UserClass[user_id].select_course: - course_brief_info = course_list.get_course_brief_info(course_id, load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR)) - user_course_data.append(course_brief_info) - return render_template('dashboard.html',user_data = user_id2UserClass[user_id].to_json_without_dialog(), user_course_data = json.dumps(user_course_data)) - -''' -Course -''' - -@app.route('/course/') -@require_role -def course(course_id): - c = load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR) - return render_template('course.html', course_id=course_id, course_data=c) - -@app.route('/select_course', methods=['POST']) -@require_role -def select_course(): - user = user_id2UserClass[session['user_id']] - data = request.get_json() - course_id = data.get('course_id') - if course_id: - user.select_new_course(course_id, load_course_from_json(course_id, COURSE_DATA_DIR)) - return jsonify({'success': True, 'message': '课程选择成功'}) - - -@app.route('/') -@require_role -def home_index(): - selected_courses=[] - if ('user_id' in session): - if (session['user_id'] not in user_id2UserClass): return redirect(url_for('login')) - user = user_id2UserClass[session['user_id']] - for course_id in user.select_course: - selected_courses.append(course_id) - - return render_template('index.html', courses_data = course_list, selected_courses =selected_courses) - -# 一些app辅助函数,主要提供给Agent与数据库的交互能力 - -class MyFunction: - def save_chapter_memory(self, id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal): - print("-=-=-=-=-=-=-=-") - print(id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - username = uuid2username[id] - u = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - u.save_chapter_memory(course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - -app.my_function = MyFunction() -if __name__ == '__main__': - socketio.on_namespace(VSCodeNamespace('/vscode')) - socketio.on_namespace(AgentNamespace('/agent')) - socketio.run(app, host='0.0.0.0', port=5551, debug=False,allow_unsafe_werkzeug=True) - diff --git a/Html/runs/run_20250911-090321_2uj10i/code/backboardManager.py b/Html/runs/run_20250911-090321_2uj10i/code/backboardManager.py deleted file mode 100644 index 7de5f19..0000000 --- a/Html/runs/run_20250911-090321_2uj10i/code/backboardManager.py +++ /dev/null @@ -1,80 +0,0 @@ - - - -import time -import os - -class Backboard: - def __init__(self, user_uuid, username, course_id, lesson_id, root_path): - self.user_uuid = user_uuid - self.username = username - self.course_id = course_id - self.lesson_id = lesson_id - self.root_path = root_path - self.create_time = time.time() - self.enter_chapter_time = time.time() - self.history = [] - self.file_tree = "[]" - self.active_file_path = "" - self.active_file_content = "" - self.pasted_file_path = "" - self.pasted_content = "" - - - def next_chapter(self): - self.enter_chapter_time = time.time() - - def get_info_prompt(self): - - five_history = "" - for h in self.history[-5:]: - five_history += h['type'] + "\n" + h.get('filePath', '') + "\n\n" - - endl = "\n" - return (f"###Global Info:###{endl}" - f"Here are some info about now user's IDE, refer to it when you need to handle some code.{endl}" - f"- User's total study time is {self.get_deltatime_mmss(self.create_time, time.time())}{endl}" - f"- User's current chapter study time is {self.get_deltatime_mmss(self.enter_chapter_time, time.time())}{endl}" - f"- Activated file path: {self.active_file_path}{endl}" - f"```{endl}" - f"{self.active_file_content[-10:]}{endl}" - f"```{endl}" - f"- Last five action:{five_history}{endl}" - f"- File tree: {self.file_tree}{endl}") - # f"- Activated file content (current editing 10 lines): {endl}" - def add_history(self, realtime_action): - if(realtime_action['type']=='config'):return - if len(self.history)!=0: - if (self.history[-1]['type']=='fileEdit'): - if(self.history[-1]['filePath'] == realtime_action['filePath']): - self.history[-1]['content'] = realtime_action['content'] - return - self.history.append(realtime_action) - - - def get_deltatime_mmss(self, start_time, end_time): - elapsed_time = end_time - start_time - hours = int(elapsed_time // 3600) - minutes = int((elapsed_time % 3600) // 60) - seconds = int(elapsed_time % 60) - return f"{hours:02d}:{minutes:02d}:{seconds:02d}" - - - def get_active_file_reletive_path(self): - relative_path = os.path.relpath(self.active_file_path, self.root_path) - return relative_path - - - -class BackBoardManager: - def __init__(self): - self.backboards = {} # user_uuid: Backboard - - def add_backboard(self, user_uuid, username, course_id, lesson_id, root_path): - self.backboards[user_uuid] = Backboard(user_uuid,username, course_id, lesson_id, root_path) - - def get_backboard(self, user_uuid) -> Backboard: - return self.backboards[user_uuid] - - - diff --git a/Html/runs/run_20250911-090321_2uj10i/code/bootstrap.py b/Html/runs/run_20250911-090321_2uj10i/code/bootstrap.py deleted file mode 100644 index bcb15ce..0000000 --- a/Html/runs/run_20250911-090321_2uj10i/code/bootstrap.py +++ /dev/null @@ -1,31 +0,0 @@ -from pathlib import Path -import sys, os - -def bootstrap_paths(): - """ - 让 'AlgoriAgent'(位于 repo_root/AlgoriAgent)可被 import; - 并提供 STUDENT_WORKSPACE_ROOT 的默认值(repo_root/study)。 - 适配当前工厂位置:repo_root/Html/apps/__init__.py - """ - here = Path(__file__).resolve() - # repo_root = .../Html/apps/../../ => parents[2] - repo_root = here.parents[2] - - # 兜底:如果目录结构变化,尝试向上搜索包含 AlgoriAgent 的目录作为 repo_root - if not (repo_root / "AlgoriAgent").exists(): - for p in here.parents: - if (p / "AlgoriAgent").is_dir(): - repo_root = p - break - - # 确保仓库根在 sys.path(这样 'AlgoriAgent' 顶层包可被发现) - repo_root_str = str(repo_root) - if repo_root_str not in sys.path: - sys.path.insert(0, repo_root_str) - - # 可选:如果你还有其它顶层包,也可在此处继续插入 - - # 默认学习工作区目录(也可放到 config.ini / 环境变量覆盖) - os.environ.setdefault("STUDENT_WORKSPACE_ROOT", str(repo_root / "study")) - - return repo_root # 方便调试/日志 \ No newline at end of file diff --git a/Html/runs/run_20250911-090321_2uj10i/code/wsgi.py b/Html/runs/run_20250911-090321_2uj10i/code/wsgi.py deleted file mode 100644 index bbcbe5f..0000000 --- a/Html/runs/run_20250911-090321_2uj10i/code/wsgi.py +++ /dev/null @@ -1,6 +0,0 @@ -# wsgi.py -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -# 提供一个可被 WSGI/进程管理器导入的 app 对象 -app = create_app() diff --git a/Html/runs/run_20250911-090321_2uj10i/logging.chat b/Html/runs/run_20250911-090321_2uj10i/logging.chat deleted file mode 100644 index e69de29..0000000 diff --git a/Html/runs/run_20250911-090321_2uj10i/logging.log b/Html/runs/run_20250911-090321_2uj10i/logging.log deleted file mode 100644 index 8866c41..0000000 --- a/Html/runs/run_20250911-090321_2uj10i/logging.log +++ /dev/null @@ -1 +0,0 @@ -2025-09-11 09:03:25.219 | INFO | agentscope.models:read_model_configs:186 - Load configs for model wrapper: openai_cfg diff --git a/Html/runs/run_20250911-090909_8r99r2/.config b/Html/runs/run_20250911-090909_8r99r2/.config deleted file mode 100644 index 4fa0b28..0000000 --- a/Html/runs/run_20250911-090909_8r99r2/.config +++ /dev/null @@ -1,7 +0,0 @@ -{ - "project": "e99PK3", - "name": "8r99r2", - "run_id": "run_20250911-090909_8r99r2", - "timestamp": "2025-09-11 09:09:09", - "pid": 12477 -} \ No newline at end of file diff --git a/Html/runs/run_20250911-090909_8r99r2/agentscope.db b/Html/runs/run_20250911-090909_8r99r2/agentscope.db deleted file mode 100644 index 666055b77679cda29c14fcf23b4ef1d039c5b52a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI%L2KJE6bEoS4Q(k)+glI2yjv3-0%NB!Hs&O1YUav`W0U1F<0V=#BsNLx(sSu$ z>=W&q?4#^B$!*yt2YT5l`~^0a^z(#~{ zkyg6w!t)u0!@f%5aeaJcfD9*Q_b$ozCY8>~CFA6|{Z2V!N;Z^cIq}eS$>x3HY|^=j z7lokrf1)Z$x@_R^N~@apn7OPMkZ(I<*1WJCw@v3GWy2n6&RcIQ0~zlR_x8^$%be!% zmxb7@7V;}H+K5#l(wSbZKXKY!mys6ROyi|!%aN@+%REpi?;B-K4PC3&{>iCzQnNB+ zwbW!z4iA{x(V_2L+5VJ1vMJeN;5l68yJ9?OZyl-TNCEp4P{^H8$cTGExdq$9ANE6@ zA@`ZUhb>is+Y=S?%$C1fnN{muZU1a!nMRV%#qFbMT;y3hf|KlJ)00Izz00bZa0SG_<0uX=z1a@EGHy1PL*Z=?k diff --git a/Html/runs/run_20250911-090909_8r99r2/code/app.py b/Html/runs/run_20250911-090909_8r99r2/code/app.py deleted file mode 100644 index c7f31f7..0000000 --- a/Html/runs/run_20250911-090909_8r99r2/code/app.py +++ /dev/null @@ -1,21 +0,0 @@ -# app.py 0.1.1 rise to factory mode -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -from apps.extensions import socketio - -# 工厂创建 app,工厂里已经做了:加载配置/注册蓝图/注册 namespaces -app = create_app() - -if __name__ == "__main__": - # 仅本地开发用;生产不要用 werkzeug 自带的开发服务器 - socketio.run( - app, - host="0.0.0.0", - port=5551, - debug=True, # 开发期打开 - allow_unsafe_werkzeug=True, # 避免 dev server 的安全限制提示 - # ssl_context=('server.crt', 'server.key') - ) - - diff --git a/Html/runs/run_20250911-090909_8r99r2/code/app_back.py b/Html/runs/run_20250911-090909_8r99r2/code/app_back.py deleted file mode 100644 index 246853c..0000000 --- a/Html/runs/run_20250911-090909_8r99r2/code/app_back.py +++ /dev/null @@ -1,480 +0,0 @@ -from bootstrap import bootstrap_paths -bootstrap_paths() -from functools import wraps -from flask import Flask, redirect, session, request, jsonify, render_template, send_from_directory, url_for -from flask_cors import CORS -from flask_socketio import SocketIO, join_room, emit, Namespace -import markdown -import os -import uuid -import shutil -import sys -import json -from apps.auth.decorators import require_role -parent_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) -sys.path.insert(0, parent_dir) -student_workspace_root_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../study')) -current_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '.')) -sys.path.insert(0, current_dir) -from AlgoriAgent.projects.algoriAgent.agent_manager import AgentManager - - -import configparser - -from db.user_list import UserList -from db.user import User, load_user_from_json, create_user_json -from db.course_list import CourseList -from db.course import Course, load_course_from_json -GLOBAL_CONFIG = configparser.ConfigParser() -GLOBAL_CONFIG.read('config.ini') -VSCODE_WEB_URL = GLOBAL_CONFIG['VSCODE_WEB']['url'] -USER_DATA_DIR = GLOBAL_CONFIG['USER_DATA']['dir'] -COURSE_DATA_DIR = GLOBAL_CONFIG['COURSE_DATA']['dir'] - -app = Flask(__name__) -socketio = SocketIO(app, cors_allowed_origins="*",ping_timeout=60, ping_interval=5) -# socketio = SocketIO(app, cors_allowed_origins="http://localhost:9888") # 设置跨域支持 -import logging -app.secret_key = 'cakebaker' -app.logger.setLevel(logging.DEBUG) -# 配置 CORS -CORS(app, resources={r"/*": {"origins": VSCODE_WEB_URL},}, supports_credentials=True) - - -userid_recorder = {} # user_id&path -> session['user_id'] - -''' -Backboard -''' -from backboardManager import BackBoardManager, Backboard - -backboard_manager = BackBoardManager() -uuid2username = {} -username2uuid = {} - - - -# 定义命名空间:用于和 VSCode 插件交流 -class VSCodeNamespace(Namespace): - def on_login(self,data): - print("VSCode client connected") - print(data) - dataconfig = data['config'] - user_id = dataconfig.get('user_id') - path = dataconfig.get('path') - course_id = dataconfig.get('course_id') - lesson_id = dataconfig.get('chapter_id') - print(f"User {user_id} connected with path: {path}") - useruuid = username2uuid[user_id] - join_room(useruuid, namespace='/vscode') - if backboard_manager.get_backboard(useruuid) == None: - backboard_manager.add_backboard(useruuid,user_id, course_id, lesson_id, path) - - - def on_message(self, data): - print(f"Received from VSCode client: {data}") - dataconfig = data['config'] - realtime_response(dataconfig, data) - # emit('response', {'message': 'Config data received and connection established'}) - def on_disconnect(self, data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - -def realtime_response(config, realtime_action): - user_id = config['user_id'] - folder_path = config['path'] - useruuid = username2uuid[user_id] - bb = backboard_manager.get_backboard(useruuid) - assert type(bb) == Backboard - - bb.add_history(realtime_action) - - if realtime_action['type'] == 'workspaceFolders': - bb.file_tree = realtime_action['fileTree'] - - if realtime_action['type'] == 'activeFile': - file_path = realtime_action['filePath'] - assert type(file_path) == str - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - if realtime_action['type'] == 'paste': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.pasted_file_path = file_path - bb.pasted_content = realtime_action['content'] - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - if realtime_action['type'] == 'fileEdit': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - - - print("config"+str(config)) - print("realtime_action"+str(realtime_action)) - pass - - -''' -Agent and Chat -''' -agent_manager = AgentManager(app = app, socketio = socketio) -user_threads = {} -import threading -from concurrent.futures import ThreadPoolExecutor, as_completed - -# 初始化线程池 -executor = ThreadPoolExecutor(max_workers=10) -class AgentNamespace(Namespace): - def on_login(self, data): - data = json.loads(data) - user = data['username'] - course_id = data['course_id'] - chapter_id = data['chapter_id'] - user_uuid = username2uuid[user] - session['user_id'] = user_uuid - print(f'User connected with session user_id: {user_uuid}') - # 从markdown、markdown_prompts、score_prompts中各读取数据folder.md并进行new_agent - with open(f'books/markdown/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fmd,\ - open(f'books/markdown_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8')as fmdp,\ - open(f'books/score_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fsp: - markdown = fmd.read() - markdown_prompts = fmdp.read() - score_prompts = fsp.read() - user_uuid, agent = agent_manager.new_agent(course_id, chapter_id, markdown, markdown_prompts, score_prompts, id=user_uuid, - root_path=f'../../study/{user}/{course_id}/{chapter_id}') - print(user_uuid) - join_room(user_uuid, namespace='/agent') # 将该用户加入以user_id为名的room - backboard_manager.add_backboard(user_uuid, user, course_id, chapter_id, root_path=f'../../study/{user}/{course_id}/{chapter_id}') - - def on_language(self, language): - id = session.get('user_id') - agent_manager.change_language(id, language) - - def on_message(self, data): - print(f"Message from client: {data}") - id = session.get('user_id') - if (type(data)==str): - data = json.loads(data) - print(id) - if data['type'] == 'text': - res = agent_manager.invoke(id, data['data'], backboard_manager.get_backboard(id).get_info_prompt()) - print('=*='*20) - print(res.content) - reply = f"{res.content['speak']}" - with app.app_context(): - emit('message',reply, room=id, namespace='/agent') - emit('request_function',res.content['function'], room=id, namespace='/agent') - - if data['type'] == 'function': - agent_manager.function_call(id, data['data']) - - def on_initiative(self,data): - print("User active function call") - user_id = session['user_id'] - if data['name'] == 'sample_judge': - agent_manager.sample_judge(user_id, backboard_manager.get_backboard(user_id)) - if data['name'] == 'judge': - agent_manager.judge(user_id, backboard_manager.get_backboard(user_id)) - - - - def on_disconnect(self,data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - - -''' -Markdown to HTML -''' -# 配置文件路径 -MARKDOWN_DIR = 'books/markdown' # 存放 markdown 文件的文件夹 -STATIC_DIR = 'static' # 存放生成的 HTML 和图片资源的文件夹 -IMAGE_DIR = 'image' # 图片资源相对于 markdown 的位置 - - - -@app.route('/--markdown', methods=['GET']) -def convert_md(course_id, filename): - md_file_path = os.path.join(MARKDOWN_DIR,course_id, f'{filename}.md') - - if not os.path.exists(md_file_path): - return jsonify({'error': 'Markdown file not found'}), 404 - - # 读取 markdown 文件内容 - with open(md_file_path, 'r', encoding='utf-8') as file: - md_content = file.read() - - # 将 markdown 转换为 HTML - html_content = markdown.markdown(md_content) - # 插入 CSS 样式,限制图片最大宽度为 100%,高度自动调整 - html_with_styles = f""" - - - - - - - {html_content} - - - """ - # 保存 HTML 文件到 static 文件夹 - html_output_path = os.path.join(STATIC_DIR, f'{filename}.html') - with open(html_output_path, 'w', encoding='utf-8') as html_file: - html_file.write(html_with_styles) - - # 处理图片资源,将 image/xxx 文件夹拷贝到 static/image/xxx - image_source_dir = os.path.join(MARKDOWN_DIR,course_id, IMAGE_DIR, filename) - image_target_dir = os.path.join(STATIC_DIR, IMAGE_DIR, filename) - print(f"Copying image resources from {image_source_dir} to {image_target_dir}") - if os.path.exists(image_source_dir): - # 确保 static/image/xxx 目录存在 - if not os.path.exists(image_target_dir): - os.makedirs(image_target_dir) - - # 拷贝图片资源 - for image_file in os.listdir(image_source_dir): - full_image_file_path = os.path.join(image_source_dir, image_file) - if os.path.isfile(full_image_file_path): - shutil.copy(full_image_file_path, image_target_dir) - - return jsonify({'html_url': f'/static/{filename}.html'}) - -# 静态文件(HTML 和图片资源)的访问 -@app.route('/static/') -def serve_static(filename): - return send_from_directory(STATIC_DIR, filename) - - -''' -Vscode -''' -@app.route('/desktop///') -def desktop(user_id, course_id, chapter_id): - if 'user_id' not in session: - # return redirect(url_for('login')) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ user_id + "uuid is"+ session['user_id']) - username2uuid[user_id] = session['user_id'] - uuid2username[session['user_id']] = user_id - userid_recorder[user_id+'&'+course_id] = session['user_id'] - - # 在学习目录下创建一个名为 user_id_path 的文件夹 - path_dir = os.path.join(student_workspace_root_path, user_id, course_id,chapter_id) - os.makedirs(path_dir, exist_ok=True) - # 在此文件夹内部创建一个.config文件,并写入 user_id=user_id\n path=path - config_path = os.path.join(path_dir, '.config') - if GLOBAL_CONFIG['VSCODE_WEB_PATH']['is_wsl']: # 如果是在 WSL 中运行,则将路径转换为 WSL 路径 - path_dir = path_dir.replace('\\', '/') - path_dir = path_dir.replace(GLOBAL_CONFIG['VSCODE_WEB_PATH']['windows_path'] , GLOBAL_CONFIG['VSCODE_WEB_PATH']['wsl_path']) - with open(config_path, 'w', encoding='utf-8') as f: - tmpd = {'user_id': user_id, 'course_id': course_id, 'chapter_id': chapter_id, 'path': path_dir} - json.dump(tmpd, f) - print('---------------------') - print(config_path) - return render_template('desktop.html', vscode_web_url=VSCODE_WEB_URL, user_id=user_id, course_id=course_id, chapter_id=chapter_id, workspace_path=path_dir) - -@app.route('/desktop_nouser//') -def desktop_nouser(course_id, chapter_id): - if 'user_id' not in session: - return redirect(url_for('login')) - user_id = session['user_id'] - username = uuid2username[user_id] - return redirect(url_for('desktop', user_id=username, course_id=course_id, chapter_id=chapter_id)) - -@app.route('/vscode_data', methods=['POST']) -def vscode_data(): - data = request.json - config = data['config'] - realtime_response(config,data) - print(f"Received data from VSCode: {data}") - return jsonify({"status": "success", "received": data}) - - - -''' -Login - -''' -users_list = UserList() -course_list = CourseList() - - -@app.route('/register') -def register(): - return render_template('register.html') - -@app.route('/register_teacher') -def register_teacher(): - return render_template('register_teacher.html') - -@app.route('/register_teacher_post', methods=['POST']) -def register_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password, teacher=True) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - -@app.route('/register_post', methods=['POST']) -def register_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - - -@app.route('/login') -def login(): - return render_template('login.html') - if 'user_id' not in session: - return render_template('login.html') - else: - return redirect(url_for('/')) - -@app.route('/login_post', methods=['POST']) -def login_post(): - # 获取请求的 JSON 数据 - data = request.get_json() - - username = data.get('username') - password = data.get('password') - - pswd = users_list.get_user_pswd(username) - - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/login_teacher_post', methods=['POST']) -def login_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - pswd = users_list.get_user_pswd(username) - is_teacher = users_list.get_user_is_teacher(username) - if is_teacher is None or is_teacher == False: - return jsonify({'success': False, 'message': '用户名不存在或非教师账号'}) - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/teacherboard') -@require_role(roles="teacher") -def teacherboard(): - return render_template('teacherboard.html') - - -@app.route('/logout') -def logout(): - session.pop('user_id', None) - return redirect(url_for('login')) - -@app.route('/get_session') -def get_session(): - user_session = session.get('user_id', 'default_session') - return jsonify({"session": user_session}) - - -''' -DashBoard -''' -user_id2UserClass = {} -@app.route('/dashboard') -@require_role -def dashboard(): - user_id = session['user_id'] - username = uuid2username[user_id] - if (user_id not in user_id2UserClass): - user_id2UserClass[user_id] = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - user_course_data = [] - for course_id in user_id2UserClass[user_id].select_course: - course_brief_info = course_list.get_course_brief_info(course_id, load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR)) - user_course_data.append(course_brief_info) - return render_template('dashboard.html',user_data = user_id2UserClass[user_id].to_json_without_dialog(), user_course_data = json.dumps(user_course_data)) - -''' -Course -''' - -@app.route('/course/') -@require_role -def course(course_id): - c = load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR) - return render_template('course.html', course_id=course_id, course_data=c) - -@app.route('/select_course', methods=['POST']) -@require_role -def select_course(): - user = user_id2UserClass[session['user_id']] - data = request.get_json() - course_id = data.get('course_id') - if course_id: - user.select_new_course(course_id, load_course_from_json(course_id, COURSE_DATA_DIR)) - return jsonify({'success': True, 'message': '课程选择成功'}) - - -@app.route('/') -@require_role -def home_index(): - selected_courses=[] - if ('user_id' in session): - if (session['user_id'] not in user_id2UserClass): return redirect(url_for('login')) - user = user_id2UserClass[session['user_id']] - for course_id in user.select_course: - selected_courses.append(course_id) - - return render_template('index.html', courses_data = course_list, selected_courses =selected_courses) - -# 一些app辅助函数,主要提供给Agent与数据库的交互能力 - -class MyFunction: - def save_chapter_memory(self, id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal): - print("-=-=-=-=-=-=-=-") - print(id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - username = uuid2username[id] - u = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - u.save_chapter_memory(course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - -app.my_function = MyFunction() -if __name__ == '__main__': - socketio.on_namespace(VSCodeNamespace('/vscode')) - socketio.on_namespace(AgentNamespace('/agent')) - socketio.run(app, host='0.0.0.0', port=5551, debug=False,allow_unsafe_werkzeug=True) - diff --git a/Html/runs/run_20250911-090909_8r99r2/code/backboardManager.py b/Html/runs/run_20250911-090909_8r99r2/code/backboardManager.py deleted file mode 100644 index 7de5f19..0000000 --- a/Html/runs/run_20250911-090909_8r99r2/code/backboardManager.py +++ /dev/null @@ -1,80 +0,0 @@ - - - -import time -import os - -class Backboard: - def __init__(self, user_uuid, username, course_id, lesson_id, root_path): - self.user_uuid = user_uuid - self.username = username - self.course_id = course_id - self.lesson_id = lesson_id - self.root_path = root_path - self.create_time = time.time() - self.enter_chapter_time = time.time() - self.history = [] - self.file_tree = "[]" - self.active_file_path = "" - self.active_file_content = "" - self.pasted_file_path = "" - self.pasted_content = "" - - - def next_chapter(self): - self.enter_chapter_time = time.time() - - def get_info_prompt(self): - - five_history = "" - for h in self.history[-5:]: - five_history += h['type'] + "\n" + h.get('filePath', '') + "\n\n" - - endl = "\n" - return (f"###Global Info:###{endl}" - f"Here are some info about now user's IDE, refer to it when you need to handle some code.{endl}" - f"- User's total study time is {self.get_deltatime_mmss(self.create_time, time.time())}{endl}" - f"- User's current chapter study time is {self.get_deltatime_mmss(self.enter_chapter_time, time.time())}{endl}" - f"- Activated file path: {self.active_file_path}{endl}" - f"```{endl}" - f"{self.active_file_content[-10:]}{endl}" - f"```{endl}" - f"- Last five action:{five_history}{endl}" - f"- File tree: {self.file_tree}{endl}") - # f"- Activated file content (current editing 10 lines): {endl}" - def add_history(self, realtime_action): - if(realtime_action['type']=='config'):return - if len(self.history)!=0: - if (self.history[-1]['type']=='fileEdit'): - if(self.history[-1]['filePath'] == realtime_action['filePath']): - self.history[-1]['content'] = realtime_action['content'] - return - self.history.append(realtime_action) - - - def get_deltatime_mmss(self, start_time, end_time): - elapsed_time = end_time - start_time - hours = int(elapsed_time // 3600) - minutes = int((elapsed_time % 3600) // 60) - seconds = int(elapsed_time % 60) - return f"{hours:02d}:{minutes:02d}:{seconds:02d}" - - - def get_active_file_reletive_path(self): - relative_path = os.path.relpath(self.active_file_path, self.root_path) - return relative_path - - - -class BackBoardManager: - def __init__(self): - self.backboards = {} # user_uuid: Backboard - - def add_backboard(self, user_uuid, username, course_id, lesson_id, root_path): - self.backboards[user_uuid] = Backboard(user_uuid,username, course_id, lesson_id, root_path) - - def get_backboard(self, user_uuid) -> Backboard: - return self.backboards[user_uuid] - - - diff --git a/Html/runs/run_20250911-090909_8r99r2/code/bootstrap.py b/Html/runs/run_20250911-090909_8r99r2/code/bootstrap.py deleted file mode 100644 index bcb15ce..0000000 --- a/Html/runs/run_20250911-090909_8r99r2/code/bootstrap.py +++ /dev/null @@ -1,31 +0,0 @@ -from pathlib import Path -import sys, os - -def bootstrap_paths(): - """ - 让 'AlgoriAgent'(位于 repo_root/AlgoriAgent)可被 import; - 并提供 STUDENT_WORKSPACE_ROOT 的默认值(repo_root/study)。 - 适配当前工厂位置:repo_root/Html/apps/__init__.py - """ - here = Path(__file__).resolve() - # repo_root = .../Html/apps/../../ => parents[2] - repo_root = here.parents[2] - - # 兜底:如果目录结构变化,尝试向上搜索包含 AlgoriAgent 的目录作为 repo_root - if not (repo_root / "AlgoriAgent").exists(): - for p in here.parents: - if (p / "AlgoriAgent").is_dir(): - repo_root = p - break - - # 确保仓库根在 sys.path(这样 'AlgoriAgent' 顶层包可被发现) - repo_root_str = str(repo_root) - if repo_root_str not in sys.path: - sys.path.insert(0, repo_root_str) - - # 可选:如果你还有其它顶层包,也可在此处继续插入 - - # 默认学习工作区目录(也可放到 config.ini / 环境变量覆盖) - os.environ.setdefault("STUDENT_WORKSPACE_ROOT", str(repo_root / "study")) - - return repo_root # 方便调试/日志 \ No newline at end of file diff --git a/Html/runs/run_20250911-090909_8r99r2/code/wsgi.py b/Html/runs/run_20250911-090909_8r99r2/code/wsgi.py deleted file mode 100644 index bbcbe5f..0000000 --- a/Html/runs/run_20250911-090909_8r99r2/code/wsgi.py +++ /dev/null @@ -1,6 +0,0 @@ -# wsgi.py -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -# 提供一个可被 WSGI/进程管理器导入的 app 对象 -app = create_app() diff --git a/Html/runs/run_20250911-090909_8r99r2/logging.chat b/Html/runs/run_20250911-090909_8r99r2/logging.chat deleted file mode 100644 index e69de29..0000000 diff --git a/Html/runs/run_20250911-090909_8r99r2/logging.log b/Html/runs/run_20250911-090909_8r99r2/logging.log deleted file mode 100644 index 8c975ab..0000000 --- a/Html/runs/run_20250911-090909_8r99r2/logging.log +++ /dev/null @@ -1 +0,0 @@ -2025-09-11 09:09:13.797 | INFO | agentscope.models:read_model_configs:186 - Load configs for model wrapper: openai_cfg diff --git a/Html/runs/run_20250911-090913_pb8uat/.config b/Html/runs/run_20250911-090913_pb8uat/.config deleted file mode 100644 index 7c16bbb..0000000 --- a/Html/runs/run_20250911-090913_pb8uat/.config +++ /dev/null @@ -1,7 +0,0 @@ -{ - "project": "P0kqCv", - "name": "pb8uat", - "run_id": "run_20250911-090913_pb8uat", - "timestamp": "2025-09-11 09:09:13", - "pid": 12499 -} \ No newline at end of file diff --git a/Html/runs/run_20250911-090913_pb8uat/agentscope.db b/Html/runs/run_20250911-090913_pb8uat/agentscope.db deleted file mode 100644 index 666055b77679cda29c14fcf23b4ef1d039c5b52a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI%L2KJE6bEoS4Q(k)+glI2yjv3-0%NB!Hs&O1YUav`W0U1F<0V=#BsNLx(sSu$ z>=W&q?4#^B$!*yt2YT5l`~^0a^z(#~{ zkyg6w!t)u0!@f%5aeaJcfD9*Q_b$ozCY8>~CFA6|{Z2V!N;Z^cIq}eS$>x3HY|^=j z7lokrf1)Z$x@_R^N~@apn7OPMkZ(I<*1WJCw@v3GWy2n6&RcIQ0~zlR_x8^$%be!% zmxb7@7V;}H+K5#l(wSbZKXKY!mys6ROyi|!%aN@+%REpi?;B-K4PC3&{>iCzQnNB+ zwbW!z4iA{x(V_2L+5VJ1vMJeN;5l68yJ9?OZyl-TNCEp4P{^H8$cTGExdq$9ANE6@ zA@`ZUhb>is+Y=S?%$C1fnN{muZU1a!nMRV%#qFbMT;y3hf|KlJ)00Izz00bZa0SG_<0uX=z1a@EGHy1PL*Z=?k diff --git a/Html/runs/run_20250911-090913_pb8uat/code/app.py b/Html/runs/run_20250911-090913_pb8uat/code/app.py deleted file mode 100644 index c7f31f7..0000000 --- a/Html/runs/run_20250911-090913_pb8uat/code/app.py +++ /dev/null @@ -1,21 +0,0 @@ -# app.py 0.1.1 rise to factory mode -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -from apps.extensions import socketio - -# 工厂创建 app,工厂里已经做了:加载配置/注册蓝图/注册 namespaces -app = create_app() - -if __name__ == "__main__": - # 仅本地开发用;生产不要用 werkzeug 自带的开发服务器 - socketio.run( - app, - host="0.0.0.0", - port=5551, - debug=True, # 开发期打开 - allow_unsafe_werkzeug=True, # 避免 dev server 的安全限制提示 - # ssl_context=('server.crt', 'server.key') - ) - - diff --git a/Html/runs/run_20250911-090913_pb8uat/code/app_back.py b/Html/runs/run_20250911-090913_pb8uat/code/app_back.py deleted file mode 100644 index 246853c..0000000 --- a/Html/runs/run_20250911-090913_pb8uat/code/app_back.py +++ /dev/null @@ -1,480 +0,0 @@ -from bootstrap import bootstrap_paths -bootstrap_paths() -from functools import wraps -from flask import Flask, redirect, session, request, jsonify, render_template, send_from_directory, url_for -from flask_cors import CORS -from flask_socketio import SocketIO, join_room, emit, Namespace -import markdown -import os -import uuid -import shutil -import sys -import json -from apps.auth.decorators import require_role -parent_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) -sys.path.insert(0, parent_dir) -student_workspace_root_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../study')) -current_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '.')) -sys.path.insert(0, current_dir) -from AlgoriAgent.projects.algoriAgent.agent_manager import AgentManager - - -import configparser - -from db.user_list import UserList -from db.user import User, load_user_from_json, create_user_json -from db.course_list import CourseList -from db.course import Course, load_course_from_json -GLOBAL_CONFIG = configparser.ConfigParser() -GLOBAL_CONFIG.read('config.ini') -VSCODE_WEB_URL = GLOBAL_CONFIG['VSCODE_WEB']['url'] -USER_DATA_DIR = GLOBAL_CONFIG['USER_DATA']['dir'] -COURSE_DATA_DIR = GLOBAL_CONFIG['COURSE_DATA']['dir'] - -app = Flask(__name__) -socketio = SocketIO(app, cors_allowed_origins="*",ping_timeout=60, ping_interval=5) -# socketio = SocketIO(app, cors_allowed_origins="http://localhost:9888") # 设置跨域支持 -import logging -app.secret_key = 'cakebaker' -app.logger.setLevel(logging.DEBUG) -# 配置 CORS -CORS(app, resources={r"/*": {"origins": VSCODE_WEB_URL},}, supports_credentials=True) - - -userid_recorder = {} # user_id&path -> session['user_id'] - -''' -Backboard -''' -from backboardManager import BackBoardManager, Backboard - -backboard_manager = BackBoardManager() -uuid2username = {} -username2uuid = {} - - - -# 定义命名空间:用于和 VSCode 插件交流 -class VSCodeNamespace(Namespace): - def on_login(self,data): - print("VSCode client connected") - print(data) - dataconfig = data['config'] - user_id = dataconfig.get('user_id') - path = dataconfig.get('path') - course_id = dataconfig.get('course_id') - lesson_id = dataconfig.get('chapter_id') - print(f"User {user_id} connected with path: {path}") - useruuid = username2uuid[user_id] - join_room(useruuid, namespace='/vscode') - if backboard_manager.get_backboard(useruuid) == None: - backboard_manager.add_backboard(useruuid,user_id, course_id, lesson_id, path) - - - def on_message(self, data): - print(f"Received from VSCode client: {data}") - dataconfig = data['config'] - realtime_response(dataconfig, data) - # emit('response', {'message': 'Config data received and connection established'}) - def on_disconnect(self, data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - -def realtime_response(config, realtime_action): - user_id = config['user_id'] - folder_path = config['path'] - useruuid = username2uuid[user_id] - bb = backboard_manager.get_backboard(useruuid) - assert type(bb) == Backboard - - bb.add_history(realtime_action) - - if realtime_action['type'] == 'workspaceFolders': - bb.file_tree = realtime_action['fileTree'] - - if realtime_action['type'] == 'activeFile': - file_path = realtime_action['filePath'] - assert type(file_path) == str - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - if realtime_action['type'] == 'paste': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.pasted_file_path = file_path - bb.pasted_content = realtime_action['content'] - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - if realtime_action['type'] == 'fileEdit': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - - - print("config"+str(config)) - print("realtime_action"+str(realtime_action)) - pass - - -''' -Agent and Chat -''' -agent_manager = AgentManager(app = app, socketio = socketio) -user_threads = {} -import threading -from concurrent.futures import ThreadPoolExecutor, as_completed - -# 初始化线程池 -executor = ThreadPoolExecutor(max_workers=10) -class AgentNamespace(Namespace): - def on_login(self, data): - data = json.loads(data) - user = data['username'] - course_id = data['course_id'] - chapter_id = data['chapter_id'] - user_uuid = username2uuid[user] - session['user_id'] = user_uuid - print(f'User connected with session user_id: {user_uuid}') - # 从markdown、markdown_prompts、score_prompts中各读取数据folder.md并进行new_agent - with open(f'books/markdown/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fmd,\ - open(f'books/markdown_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8')as fmdp,\ - open(f'books/score_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fsp: - markdown = fmd.read() - markdown_prompts = fmdp.read() - score_prompts = fsp.read() - user_uuid, agent = agent_manager.new_agent(course_id, chapter_id, markdown, markdown_prompts, score_prompts, id=user_uuid, - root_path=f'../../study/{user}/{course_id}/{chapter_id}') - print(user_uuid) - join_room(user_uuid, namespace='/agent') # 将该用户加入以user_id为名的room - backboard_manager.add_backboard(user_uuid, user, course_id, chapter_id, root_path=f'../../study/{user}/{course_id}/{chapter_id}') - - def on_language(self, language): - id = session.get('user_id') - agent_manager.change_language(id, language) - - def on_message(self, data): - print(f"Message from client: {data}") - id = session.get('user_id') - if (type(data)==str): - data = json.loads(data) - print(id) - if data['type'] == 'text': - res = agent_manager.invoke(id, data['data'], backboard_manager.get_backboard(id).get_info_prompt()) - print('=*='*20) - print(res.content) - reply = f"{res.content['speak']}" - with app.app_context(): - emit('message',reply, room=id, namespace='/agent') - emit('request_function',res.content['function'], room=id, namespace='/agent') - - if data['type'] == 'function': - agent_manager.function_call(id, data['data']) - - def on_initiative(self,data): - print("User active function call") - user_id = session['user_id'] - if data['name'] == 'sample_judge': - agent_manager.sample_judge(user_id, backboard_manager.get_backboard(user_id)) - if data['name'] == 'judge': - agent_manager.judge(user_id, backboard_manager.get_backboard(user_id)) - - - - def on_disconnect(self,data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - - -''' -Markdown to HTML -''' -# 配置文件路径 -MARKDOWN_DIR = 'books/markdown' # 存放 markdown 文件的文件夹 -STATIC_DIR = 'static' # 存放生成的 HTML 和图片资源的文件夹 -IMAGE_DIR = 'image' # 图片资源相对于 markdown 的位置 - - - -@app.route('/--markdown', methods=['GET']) -def convert_md(course_id, filename): - md_file_path = os.path.join(MARKDOWN_DIR,course_id, f'{filename}.md') - - if not os.path.exists(md_file_path): - return jsonify({'error': 'Markdown file not found'}), 404 - - # 读取 markdown 文件内容 - with open(md_file_path, 'r', encoding='utf-8') as file: - md_content = file.read() - - # 将 markdown 转换为 HTML - html_content = markdown.markdown(md_content) - # 插入 CSS 样式,限制图片最大宽度为 100%,高度自动调整 - html_with_styles = f""" - - - - - - - {html_content} - - - """ - # 保存 HTML 文件到 static 文件夹 - html_output_path = os.path.join(STATIC_DIR, f'{filename}.html') - with open(html_output_path, 'w', encoding='utf-8') as html_file: - html_file.write(html_with_styles) - - # 处理图片资源,将 image/xxx 文件夹拷贝到 static/image/xxx - image_source_dir = os.path.join(MARKDOWN_DIR,course_id, IMAGE_DIR, filename) - image_target_dir = os.path.join(STATIC_DIR, IMAGE_DIR, filename) - print(f"Copying image resources from {image_source_dir} to {image_target_dir}") - if os.path.exists(image_source_dir): - # 确保 static/image/xxx 目录存在 - if not os.path.exists(image_target_dir): - os.makedirs(image_target_dir) - - # 拷贝图片资源 - for image_file in os.listdir(image_source_dir): - full_image_file_path = os.path.join(image_source_dir, image_file) - if os.path.isfile(full_image_file_path): - shutil.copy(full_image_file_path, image_target_dir) - - return jsonify({'html_url': f'/static/{filename}.html'}) - -# 静态文件(HTML 和图片资源)的访问 -@app.route('/static/') -def serve_static(filename): - return send_from_directory(STATIC_DIR, filename) - - -''' -Vscode -''' -@app.route('/desktop///') -def desktop(user_id, course_id, chapter_id): - if 'user_id' not in session: - # return redirect(url_for('login')) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ user_id + "uuid is"+ session['user_id']) - username2uuid[user_id] = session['user_id'] - uuid2username[session['user_id']] = user_id - userid_recorder[user_id+'&'+course_id] = session['user_id'] - - # 在学习目录下创建一个名为 user_id_path 的文件夹 - path_dir = os.path.join(student_workspace_root_path, user_id, course_id,chapter_id) - os.makedirs(path_dir, exist_ok=True) - # 在此文件夹内部创建一个.config文件,并写入 user_id=user_id\n path=path - config_path = os.path.join(path_dir, '.config') - if GLOBAL_CONFIG['VSCODE_WEB_PATH']['is_wsl']: # 如果是在 WSL 中运行,则将路径转换为 WSL 路径 - path_dir = path_dir.replace('\\', '/') - path_dir = path_dir.replace(GLOBAL_CONFIG['VSCODE_WEB_PATH']['windows_path'] , GLOBAL_CONFIG['VSCODE_WEB_PATH']['wsl_path']) - with open(config_path, 'w', encoding='utf-8') as f: - tmpd = {'user_id': user_id, 'course_id': course_id, 'chapter_id': chapter_id, 'path': path_dir} - json.dump(tmpd, f) - print('---------------------') - print(config_path) - return render_template('desktop.html', vscode_web_url=VSCODE_WEB_URL, user_id=user_id, course_id=course_id, chapter_id=chapter_id, workspace_path=path_dir) - -@app.route('/desktop_nouser//') -def desktop_nouser(course_id, chapter_id): - if 'user_id' not in session: - return redirect(url_for('login')) - user_id = session['user_id'] - username = uuid2username[user_id] - return redirect(url_for('desktop', user_id=username, course_id=course_id, chapter_id=chapter_id)) - -@app.route('/vscode_data', methods=['POST']) -def vscode_data(): - data = request.json - config = data['config'] - realtime_response(config,data) - print(f"Received data from VSCode: {data}") - return jsonify({"status": "success", "received": data}) - - - -''' -Login - -''' -users_list = UserList() -course_list = CourseList() - - -@app.route('/register') -def register(): - return render_template('register.html') - -@app.route('/register_teacher') -def register_teacher(): - return render_template('register_teacher.html') - -@app.route('/register_teacher_post', methods=['POST']) -def register_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password, teacher=True) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - -@app.route('/register_post', methods=['POST']) -def register_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - - -@app.route('/login') -def login(): - return render_template('login.html') - if 'user_id' not in session: - return render_template('login.html') - else: - return redirect(url_for('/')) - -@app.route('/login_post', methods=['POST']) -def login_post(): - # 获取请求的 JSON 数据 - data = request.get_json() - - username = data.get('username') - password = data.get('password') - - pswd = users_list.get_user_pswd(username) - - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/login_teacher_post', methods=['POST']) -def login_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - pswd = users_list.get_user_pswd(username) - is_teacher = users_list.get_user_is_teacher(username) - if is_teacher is None or is_teacher == False: - return jsonify({'success': False, 'message': '用户名不存在或非教师账号'}) - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/teacherboard') -@require_role(roles="teacher") -def teacherboard(): - return render_template('teacherboard.html') - - -@app.route('/logout') -def logout(): - session.pop('user_id', None) - return redirect(url_for('login')) - -@app.route('/get_session') -def get_session(): - user_session = session.get('user_id', 'default_session') - return jsonify({"session": user_session}) - - -''' -DashBoard -''' -user_id2UserClass = {} -@app.route('/dashboard') -@require_role -def dashboard(): - user_id = session['user_id'] - username = uuid2username[user_id] - if (user_id not in user_id2UserClass): - user_id2UserClass[user_id] = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - user_course_data = [] - for course_id in user_id2UserClass[user_id].select_course: - course_brief_info = course_list.get_course_brief_info(course_id, load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR)) - user_course_data.append(course_brief_info) - return render_template('dashboard.html',user_data = user_id2UserClass[user_id].to_json_without_dialog(), user_course_data = json.dumps(user_course_data)) - -''' -Course -''' - -@app.route('/course/') -@require_role -def course(course_id): - c = load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR) - return render_template('course.html', course_id=course_id, course_data=c) - -@app.route('/select_course', methods=['POST']) -@require_role -def select_course(): - user = user_id2UserClass[session['user_id']] - data = request.get_json() - course_id = data.get('course_id') - if course_id: - user.select_new_course(course_id, load_course_from_json(course_id, COURSE_DATA_DIR)) - return jsonify({'success': True, 'message': '课程选择成功'}) - - -@app.route('/') -@require_role -def home_index(): - selected_courses=[] - if ('user_id' in session): - if (session['user_id'] not in user_id2UserClass): return redirect(url_for('login')) - user = user_id2UserClass[session['user_id']] - for course_id in user.select_course: - selected_courses.append(course_id) - - return render_template('index.html', courses_data = course_list, selected_courses =selected_courses) - -# 一些app辅助函数,主要提供给Agent与数据库的交互能力 - -class MyFunction: - def save_chapter_memory(self, id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal): - print("-=-=-=-=-=-=-=-") - print(id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - username = uuid2username[id] - u = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - u.save_chapter_memory(course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - -app.my_function = MyFunction() -if __name__ == '__main__': - socketio.on_namespace(VSCodeNamespace('/vscode')) - socketio.on_namespace(AgentNamespace('/agent')) - socketio.run(app, host='0.0.0.0', port=5551, debug=False,allow_unsafe_werkzeug=True) - diff --git a/Html/runs/run_20250911-090913_pb8uat/code/backboardManager.py b/Html/runs/run_20250911-090913_pb8uat/code/backboardManager.py deleted file mode 100644 index 7de5f19..0000000 --- a/Html/runs/run_20250911-090913_pb8uat/code/backboardManager.py +++ /dev/null @@ -1,80 +0,0 @@ - - - -import time -import os - -class Backboard: - def __init__(self, user_uuid, username, course_id, lesson_id, root_path): - self.user_uuid = user_uuid - self.username = username - self.course_id = course_id - self.lesson_id = lesson_id - self.root_path = root_path - self.create_time = time.time() - self.enter_chapter_time = time.time() - self.history = [] - self.file_tree = "[]" - self.active_file_path = "" - self.active_file_content = "" - self.pasted_file_path = "" - self.pasted_content = "" - - - def next_chapter(self): - self.enter_chapter_time = time.time() - - def get_info_prompt(self): - - five_history = "" - for h in self.history[-5:]: - five_history += h['type'] + "\n" + h.get('filePath', '') + "\n\n" - - endl = "\n" - return (f"###Global Info:###{endl}" - f"Here are some info about now user's IDE, refer to it when you need to handle some code.{endl}" - f"- User's total study time is {self.get_deltatime_mmss(self.create_time, time.time())}{endl}" - f"- User's current chapter study time is {self.get_deltatime_mmss(self.enter_chapter_time, time.time())}{endl}" - f"- Activated file path: {self.active_file_path}{endl}" - f"```{endl}" - f"{self.active_file_content[-10:]}{endl}" - f"```{endl}" - f"- Last five action:{five_history}{endl}" - f"- File tree: {self.file_tree}{endl}") - # f"- Activated file content (current editing 10 lines): {endl}" - def add_history(self, realtime_action): - if(realtime_action['type']=='config'):return - if len(self.history)!=0: - if (self.history[-1]['type']=='fileEdit'): - if(self.history[-1]['filePath'] == realtime_action['filePath']): - self.history[-1]['content'] = realtime_action['content'] - return - self.history.append(realtime_action) - - - def get_deltatime_mmss(self, start_time, end_time): - elapsed_time = end_time - start_time - hours = int(elapsed_time // 3600) - minutes = int((elapsed_time % 3600) // 60) - seconds = int(elapsed_time % 60) - return f"{hours:02d}:{minutes:02d}:{seconds:02d}" - - - def get_active_file_reletive_path(self): - relative_path = os.path.relpath(self.active_file_path, self.root_path) - return relative_path - - - -class BackBoardManager: - def __init__(self): - self.backboards = {} # user_uuid: Backboard - - def add_backboard(self, user_uuid, username, course_id, lesson_id, root_path): - self.backboards[user_uuid] = Backboard(user_uuid,username, course_id, lesson_id, root_path) - - def get_backboard(self, user_uuid) -> Backboard: - return self.backboards[user_uuid] - - - diff --git a/Html/runs/run_20250911-090913_pb8uat/code/bootstrap.py b/Html/runs/run_20250911-090913_pb8uat/code/bootstrap.py deleted file mode 100644 index bcb15ce..0000000 --- a/Html/runs/run_20250911-090913_pb8uat/code/bootstrap.py +++ /dev/null @@ -1,31 +0,0 @@ -from pathlib import Path -import sys, os - -def bootstrap_paths(): - """ - 让 'AlgoriAgent'(位于 repo_root/AlgoriAgent)可被 import; - 并提供 STUDENT_WORKSPACE_ROOT 的默认值(repo_root/study)。 - 适配当前工厂位置:repo_root/Html/apps/__init__.py - """ - here = Path(__file__).resolve() - # repo_root = .../Html/apps/../../ => parents[2] - repo_root = here.parents[2] - - # 兜底:如果目录结构变化,尝试向上搜索包含 AlgoriAgent 的目录作为 repo_root - if not (repo_root / "AlgoriAgent").exists(): - for p in here.parents: - if (p / "AlgoriAgent").is_dir(): - repo_root = p - break - - # 确保仓库根在 sys.path(这样 'AlgoriAgent' 顶层包可被发现) - repo_root_str = str(repo_root) - if repo_root_str not in sys.path: - sys.path.insert(0, repo_root_str) - - # 可选:如果你还有其它顶层包,也可在此处继续插入 - - # 默认学习工作区目录(也可放到 config.ini / 环境变量覆盖) - os.environ.setdefault("STUDENT_WORKSPACE_ROOT", str(repo_root / "study")) - - return repo_root # 方便调试/日志 \ No newline at end of file diff --git a/Html/runs/run_20250911-090913_pb8uat/code/wsgi.py b/Html/runs/run_20250911-090913_pb8uat/code/wsgi.py deleted file mode 100644 index bbcbe5f..0000000 --- a/Html/runs/run_20250911-090913_pb8uat/code/wsgi.py +++ /dev/null @@ -1,6 +0,0 @@ -# wsgi.py -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -# 提供一个可被 WSGI/进程管理器导入的 app 对象 -app = create_app() diff --git a/Html/runs/run_20250911-090913_pb8uat/logging.chat b/Html/runs/run_20250911-090913_pb8uat/logging.chat deleted file mode 100644 index e69de29..0000000 diff --git a/Html/runs/run_20250911-090913_pb8uat/logging.log b/Html/runs/run_20250911-090913_pb8uat/logging.log deleted file mode 100644 index affb613..0000000 --- a/Html/runs/run_20250911-090913_pb8uat/logging.log +++ /dev/null @@ -1 +0,0 @@ -2025-09-11 09:09:17.446 | INFO | agentscope.models:read_model_configs:186 - Load configs for model wrapper: openai_cfg diff --git a/Html/runs/run_20250911-092225_wfvsed/.config b/Html/runs/run_20250911-092225_wfvsed/.config deleted file mode 100644 index 933ce6f..0000000 --- a/Html/runs/run_20250911-092225_wfvsed/.config +++ /dev/null @@ -1,7 +0,0 @@ -{ - "project": "wsxDPC", - "name": "wfvsed", - "run_id": "run_20250911-092225_wfvsed", - "timestamp": "2025-09-11 09:22:25", - "pid": 13836 -} \ No newline at end of file diff --git a/Html/runs/run_20250911-092225_wfvsed/agentscope.db b/Html/runs/run_20250911-092225_wfvsed/agentscope.db deleted file mode 100644 index 666055b77679cda29c14fcf23b4ef1d039c5b52a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI%L2KJE6bEoS4Q(k)+glI2yjv3-0%NB!Hs&O1YUav`W0U1F<0V=#BsNLx(sSu$ z>=W&q?4#^B$!*yt2YT5l`~^0a^z(#~{ zkyg6w!t)u0!@f%5aeaJcfD9*Q_b$ozCY8>~CFA6|{Z2V!N;Z^cIq}eS$>x3HY|^=j z7lokrf1)Z$x@_R^N~@apn7OPMkZ(I<*1WJCw@v3GWy2n6&RcIQ0~zlR_x8^$%be!% zmxb7@7V;}H+K5#l(wSbZKXKY!mys6ROyi|!%aN@+%REpi?;B-K4PC3&{>iCzQnNB+ zwbW!z4iA{x(V_2L+5VJ1vMJeN;5l68yJ9?OZyl-TNCEp4P{^H8$cTGExdq$9ANE6@ zA@`ZUhb>is+Y=S?%$C1fnN{muZU1a!nMRV%#qFbMT;y3hf|KlJ)00Izz00bZa0SG_<0uX=z1a@EGHy1PL*Z=?k diff --git a/Html/runs/run_20250911-092225_wfvsed/code/app.py b/Html/runs/run_20250911-092225_wfvsed/code/app.py deleted file mode 100644 index c7f31f7..0000000 --- a/Html/runs/run_20250911-092225_wfvsed/code/app.py +++ /dev/null @@ -1,21 +0,0 @@ -# app.py 0.1.1 rise to factory mode -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -from apps.extensions import socketio - -# 工厂创建 app,工厂里已经做了:加载配置/注册蓝图/注册 namespaces -app = create_app() - -if __name__ == "__main__": - # 仅本地开发用;生产不要用 werkzeug 自带的开发服务器 - socketio.run( - app, - host="0.0.0.0", - port=5551, - debug=True, # 开发期打开 - allow_unsafe_werkzeug=True, # 避免 dev server 的安全限制提示 - # ssl_context=('server.crt', 'server.key') - ) - - diff --git a/Html/runs/run_20250911-092225_wfvsed/code/app_back.py b/Html/runs/run_20250911-092225_wfvsed/code/app_back.py deleted file mode 100644 index 246853c..0000000 --- a/Html/runs/run_20250911-092225_wfvsed/code/app_back.py +++ /dev/null @@ -1,480 +0,0 @@ -from bootstrap import bootstrap_paths -bootstrap_paths() -from functools import wraps -from flask import Flask, redirect, session, request, jsonify, render_template, send_from_directory, url_for -from flask_cors import CORS -from flask_socketio import SocketIO, join_room, emit, Namespace -import markdown -import os -import uuid -import shutil -import sys -import json -from apps.auth.decorators import require_role -parent_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) -sys.path.insert(0, parent_dir) -student_workspace_root_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../study')) -current_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '.')) -sys.path.insert(0, current_dir) -from AlgoriAgent.projects.algoriAgent.agent_manager import AgentManager - - -import configparser - -from db.user_list import UserList -from db.user import User, load_user_from_json, create_user_json -from db.course_list import CourseList -from db.course import Course, load_course_from_json -GLOBAL_CONFIG = configparser.ConfigParser() -GLOBAL_CONFIG.read('config.ini') -VSCODE_WEB_URL = GLOBAL_CONFIG['VSCODE_WEB']['url'] -USER_DATA_DIR = GLOBAL_CONFIG['USER_DATA']['dir'] -COURSE_DATA_DIR = GLOBAL_CONFIG['COURSE_DATA']['dir'] - -app = Flask(__name__) -socketio = SocketIO(app, cors_allowed_origins="*",ping_timeout=60, ping_interval=5) -# socketio = SocketIO(app, cors_allowed_origins="http://localhost:9888") # 设置跨域支持 -import logging -app.secret_key = 'cakebaker' -app.logger.setLevel(logging.DEBUG) -# 配置 CORS -CORS(app, resources={r"/*": {"origins": VSCODE_WEB_URL},}, supports_credentials=True) - - -userid_recorder = {} # user_id&path -> session['user_id'] - -''' -Backboard -''' -from backboardManager import BackBoardManager, Backboard - -backboard_manager = BackBoardManager() -uuid2username = {} -username2uuid = {} - - - -# 定义命名空间:用于和 VSCode 插件交流 -class VSCodeNamespace(Namespace): - def on_login(self,data): - print("VSCode client connected") - print(data) - dataconfig = data['config'] - user_id = dataconfig.get('user_id') - path = dataconfig.get('path') - course_id = dataconfig.get('course_id') - lesson_id = dataconfig.get('chapter_id') - print(f"User {user_id} connected with path: {path}") - useruuid = username2uuid[user_id] - join_room(useruuid, namespace='/vscode') - if backboard_manager.get_backboard(useruuid) == None: - backboard_manager.add_backboard(useruuid,user_id, course_id, lesson_id, path) - - - def on_message(self, data): - print(f"Received from VSCode client: {data}") - dataconfig = data['config'] - realtime_response(dataconfig, data) - # emit('response', {'message': 'Config data received and connection established'}) - def on_disconnect(self, data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - -def realtime_response(config, realtime_action): - user_id = config['user_id'] - folder_path = config['path'] - useruuid = username2uuid[user_id] - bb = backboard_manager.get_backboard(useruuid) - assert type(bb) == Backboard - - bb.add_history(realtime_action) - - if realtime_action['type'] == 'workspaceFolders': - bb.file_tree = realtime_action['fileTree'] - - if realtime_action['type'] == 'activeFile': - file_path = realtime_action['filePath'] - assert type(file_path) == str - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - if realtime_action['type'] == 'paste': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.pasted_file_path = file_path - bb.pasted_content = realtime_action['content'] - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - if realtime_action['type'] == 'fileEdit': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - - - print("config"+str(config)) - print("realtime_action"+str(realtime_action)) - pass - - -''' -Agent and Chat -''' -agent_manager = AgentManager(app = app, socketio = socketio) -user_threads = {} -import threading -from concurrent.futures import ThreadPoolExecutor, as_completed - -# 初始化线程池 -executor = ThreadPoolExecutor(max_workers=10) -class AgentNamespace(Namespace): - def on_login(self, data): - data = json.loads(data) - user = data['username'] - course_id = data['course_id'] - chapter_id = data['chapter_id'] - user_uuid = username2uuid[user] - session['user_id'] = user_uuid - print(f'User connected with session user_id: {user_uuid}') - # 从markdown、markdown_prompts、score_prompts中各读取数据folder.md并进行new_agent - with open(f'books/markdown/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fmd,\ - open(f'books/markdown_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8')as fmdp,\ - open(f'books/score_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fsp: - markdown = fmd.read() - markdown_prompts = fmdp.read() - score_prompts = fsp.read() - user_uuid, agent = agent_manager.new_agent(course_id, chapter_id, markdown, markdown_prompts, score_prompts, id=user_uuid, - root_path=f'../../study/{user}/{course_id}/{chapter_id}') - print(user_uuid) - join_room(user_uuid, namespace='/agent') # 将该用户加入以user_id为名的room - backboard_manager.add_backboard(user_uuid, user, course_id, chapter_id, root_path=f'../../study/{user}/{course_id}/{chapter_id}') - - def on_language(self, language): - id = session.get('user_id') - agent_manager.change_language(id, language) - - def on_message(self, data): - print(f"Message from client: {data}") - id = session.get('user_id') - if (type(data)==str): - data = json.loads(data) - print(id) - if data['type'] == 'text': - res = agent_manager.invoke(id, data['data'], backboard_manager.get_backboard(id).get_info_prompt()) - print('=*='*20) - print(res.content) - reply = f"{res.content['speak']}" - with app.app_context(): - emit('message',reply, room=id, namespace='/agent') - emit('request_function',res.content['function'], room=id, namespace='/agent') - - if data['type'] == 'function': - agent_manager.function_call(id, data['data']) - - def on_initiative(self,data): - print("User active function call") - user_id = session['user_id'] - if data['name'] == 'sample_judge': - agent_manager.sample_judge(user_id, backboard_manager.get_backboard(user_id)) - if data['name'] == 'judge': - agent_manager.judge(user_id, backboard_manager.get_backboard(user_id)) - - - - def on_disconnect(self,data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - - -''' -Markdown to HTML -''' -# 配置文件路径 -MARKDOWN_DIR = 'books/markdown' # 存放 markdown 文件的文件夹 -STATIC_DIR = 'static' # 存放生成的 HTML 和图片资源的文件夹 -IMAGE_DIR = 'image' # 图片资源相对于 markdown 的位置 - - - -@app.route('/--markdown', methods=['GET']) -def convert_md(course_id, filename): - md_file_path = os.path.join(MARKDOWN_DIR,course_id, f'{filename}.md') - - if not os.path.exists(md_file_path): - return jsonify({'error': 'Markdown file not found'}), 404 - - # 读取 markdown 文件内容 - with open(md_file_path, 'r', encoding='utf-8') as file: - md_content = file.read() - - # 将 markdown 转换为 HTML - html_content = markdown.markdown(md_content) - # 插入 CSS 样式,限制图片最大宽度为 100%,高度自动调整 - html_with_styles = f""" - - - - - - - {html_content} - - - """ - # 保存 HTML 文件到 static 文件夹 - html_output_path = os.path.join(STATIC_DIR, f'{filename}.html') - with open(html_output_path, 'w', encoding='utf-8') as html_file: - html_file.write(html_with_styles) - - # 处理图片资源,将 image/xxx 文件夹拷贝到 static/image/xxx - image_source_dir = os.path.join(MARKDOWN_DIR,course_id, IMAGE_DIR, filename) - image_target_dir = os.path.join(STATIC_DIR, IMAGE_DIR, filename) - print(f"Copying image resources from {image_source_dir} to {image_target_dir}") - if os.path.exists(image_source_dir): - # 确保 static/image/xxx 目录存在 - if not os.path.exists(image_target_dir): - os.makedirs(image_target_dir) - - # 拷贝图片资源 - for image_file in os.listdir(image_source_dir): - full_image_file_path = os.path.join(image_source_dir, image_file) - if os.path.isfile(full_image_file_path): - shutil.copy(full_image_file_path, image_target_dir) - - return jsonify({'html_url': f'/static/{filename}.html'}) - -# 静态文件(HTML 和图片资源)的访问 -@app.route('/static/') -def serve_static(filename): - return send_from_directory(STATIC_DIR, filename) - - -''' -Vscode -''' -@app.route('/desktop///') -def desktop(user_id, course_id, chapter_id): - if 'user_id' not in session: - # return redirect(url_for('login')) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ user_id + "uuid is"+ session['user_id']) - username2uuid[user_id] = session['user_id'] - uuid2username[session['user_id']] = user_id - userid_recorder[user_id+'&'+course_id] = session['user_id'] - - # 在学习目录下创建一个名为 user_id_path 的文件夹 - path_dir = os.path.join(student_workspace_root_path, user_id, course_id,chapter_id) - os.makedirs(path_dir, exist_ok=True) - # 在此文件夹内部创建一个.config文件,并写入 user_id=user_id\n path=path - config_path = os.path.join(path_dir, '.config') - if GLOBAL_CONFIG['VSCODE_WEB_PATH']['is_wsl']: # 如果是在 WSL 中运行,则将路径转换为 WSL 路径 - path_dir = path_dir.replace('\\', '/') - path_dir = path_dir.replace(GLOBAL_CONFIG['VSCODE_WEB_PATH']['windows_path'] , GLOBAL_CONFIG['VSCODE_WEB_PATH']['wsl_path']) - with open(config_path, 'w', encoding='utf-8') as f: - tmpd = {'user_id': user_id, 'course_id': course_id, 'chapter_id': chapter_id, 'path': path_dir} - json.dump(tmpd, f) - print('---------------------') - print(config_path) - return render_template('desktop.html', vscode_web_url=VSCODE_WEB_URL, user_id=user_id, course_id=course_id, chapter_id=chapter_id, workspace_path=path_dir) - -@app.route('/desktop_nouser//') -def desktop_nouser(course_id, chapter_id): - if 'user_id' not in session: - return redirect(url_for('login')) - user_id = session['user_id'] - username = uuid2username[user_id] - return redirect(url_for('desktop', user_id=username, course_id=course_id, chapter_id=chapter_id)) - -@app.route('/vscode_data', methods=['POST']) -def vscode_data(): - data = request.json - config = data['config'] - realtime_response(config,data) - print(f"Received data from VSCode: {data}") - return jsonify({"status": "success", "received": data}) - - - -''' -Login - -''' -users_list = UserList() -course_list = CourseList() - - -@app.route('/register') -def register(): - return render_template('register.html') - -@app.route('/register_teacher') -def register_teacher(): - return render_template('register_teacher.html') - -@app.route('/register_teacher_post', methods=['POST']) -def register_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password, teacher=True) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - -@app.route('/register_post', methods=['POST']) -def register_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - - -@app.route('/login') -def login(): - return render_template('login.html') - if 'user_id' not in session: - return render_template('login.html') - else: - return redirect(url_for('/')) - -@app.route('/login_post', methods=['POST']) -def login_post(): - # 获取请求的 JSON 数据 - data = request.get_json() - - username = data.get('username') - password = data.get('password') - - pswd = users_list.get_user_pswd(username) - - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/login_teacher_post', methods=['POST']) -def login_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - pswd = users_list.get_user_pswd(username) - is_teacher = users_list.get_user_is_teacher(username) - if is_teacher is None or is_teacher == False: - return jsonify({'success': False, 'message': '用户名不存在或非教师账号'}) - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/teacherboard') -@require_role(roles="teacher") -def teacherboard(): - return render_template('teacherboard.html') - - -@app.route('/logout') -def logout(): - session.pop('user_id', None) - return redirect(url_for('login')) - -@app.route('/get_session') -def get_session(): - user_session = session.get('user_id', 'default_session') - return jsonify({"session": user_session}) - - -''' -DashBoard -''' -user_id2UserClass = {} -@app.route('/dashboard') -@require_role -def dashboard(): - user_id = session['user_id'] - username = uuid2username[user_id] - if (user_id not in user_id2UserClass): - user_id2UserClass[user_id] = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - user_course_data = [] - for course_id in user_id2UserClass[user_id].select_course: - course_brief_info = course_list.get_course_brief_info(course_id, load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR)) - user_course_data.append(course_brief_info) - return render_template('dashboard.html',user_data = user_id2UserClass[user_id].to_json_without_dialog(), user_course_data = json.dumps(user_course_data)) - -''' -Course -''' - -@app.route('/course/') -@require_role -def course(course_id): - c = load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR) - return render_template('course.html', course_id=course_id, course_data=c) - -@app.route('/select_course', methods=['POST']) -@require_role -def select_course(): - user = user_id2UserClass[session['user_id']] - data = request.get_json() - course_id = data.get('course_id') - if course_id: - user.select_new_course(course_id, load_course_from_json(course_id, COURSE_DATA_DIR)) - return jsonify({'success': True, 'message': '课程选择成功'}) - - -@app.route('/') -@require_role -def home_index(): - selected_courses=[] - if ('user_id' in session): - if (session['user_id'] not in user_id2UserClass): return redirect(url_for('login')) - user = user_id2UserClass[session['user_id']] - for course_id in user.select_course: - selected_courses.append(course_id) - - return render_template('index.html', courses_data = course_list, selected_courses =selected_courses) - -# 一些app辅助函数,主要提供给Agent与数据库的交互能力 - -class MyFunction: - def save_chapter_memory(self, id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal): - print("-=-=-=-=-=-=-=-") - print(id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - username = uuid2username[id] - u = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - u.save_chapter_memory(course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - -app.my_function = MyFunction() -if __name__ == '__main__': - socketio.on_namespace(VSCodeNamespace('/vscode')) - socketio.on_namespace(AgentNamespace('/agent')) - socketio.run(app, host='0.0.0.0', port=5551, debug=False,allow_unsafe_werkzeug=True) - diff --git a/Html/runs/run_20250911-092225_wfvsed/code/backboardManager.py b/Html/runs/run_20250911-092225_wfvsed/code/backboardManager.py deleted file mode 100644 index 7de5f19..0000000 --- a/Html/runs/run_20250911-092225_wfvsed/code/backboardManager.py +++ /dev/null @@ -1,80 +0,0 @@ - - - -import time -import os - -class Backboard: - def __init__(self, user_uuid, username, course_id, lesson_id, root_path): - self.user_uuid = user_uuid - self.username = username - self.course_id = course_id - self.lesson_id = lesson_id - self.root_path = root_path - self.create_time = time.time() - self.enter_chapter_time = time.time() - self.history = [] - self.file_tree = "[]" - self.active_file_path = "" - self.active_file_content = "" - self.pasted_file_path = "" - self.pasted_content = "" - - - def next_chapter(self): - self.enter_chapter_time = time.time() - - def get_info_prompt(self): - - five_history = "" - for h in self.history[-5:]: - five_history += h['type'] + "\n" + h.get('filePath', '') + "\n\n" - - endl = "\n" - return (f"###Global Info:###{endl}" - f"Here are some info about now user's IDE, refer to it when you need to handle some code.{endl}" - f"- User's total study time is {self.get_deltatime_mmss(self.create_time, time.time())}{endl}" - f"- User's current chapter study time is {self.get_deltatime_mmss(self.enter_chapter_time, time.time())}{endl}" - f"- Activated file path: {self.active_file_path}{endl}" - f"```{endl}" - f"{self.active_file_content[-10:]}{endl}" - f"```{endl}" - f"- Last five action:{five_history}{endl}" - f"- File tree: {self.file_tree}{endl}") - # f"- Activated file content (current editing 10 lines): {endl}" - def add_history(self, realtime_action): - if(realtime_action['type']=='config'):return - if len(self.history)!=0: - if (self.history[-1]['type']=='fileEdit'): - if(self.history[-1]['filePath'] == realtime_action['filePath']): - self.history[-1]['content'] = realtime_action['content'] - return - self.history.append(realtime_action) - - - def get_deltatime_mmss(self, start_time, end_time): - elapsed_time = end_time - start_time - hours = int(elapsed_time // 3600) - minutes = int((elapsed_time % 3600) // 60) - seconds = int(elapsed_time % 60) - return f"{hours:02d}:{minutes:02d}:{seconds:02d}" - - - def get_active_file_reletive_path(self): - relative_path = os.path.relpath(self.active_file_path, self.root_path) - return relative_path - - - -class BackBoardManager: - def __init__(self): - self.backboards = {} # user_uuid: Backboard - - def add_backboard(self, user_uuid, username, course_id, lesson_id, root_path): - self.backboards[user_uuid] = Backboard(user_uuid,username, course_id, lesson_id, root_path) - - def get_backboard(self, user_uuid) -> Backboard: - return self.backboards[user_uuid] - - - diff --git a/Html/runs/run_20250911-092225_wfvsed/code/bootstrap.py b/Html/runs/run_20250911-092225_wfvsed/code/bootstrap.py deleted file mode 100644 index bcb15ce..0000000 --- a/Html/runs/run_20250911-092225_wfvsed/code/bootstrap.py +++ /dev/null @@ -1,31 +0,0 @@ -from pathlib import Path -import sys, os - -def bootstrap_paths(): - """ - 让 'AlgoriAgent'(位于 repo_root/AlgoriAgent)可被 import; - 并提供 STUDENT_WORKSPACE_ROOT 的默认值(repo_root/study)。 - 适配当前工厂位置:repo_root/Html/apps/__init__.py - """ - here = Path(__file__).resolve() - # repo_root = .../Html/apps/../../ => parents[2] - repo_root = here.parents[2] - - # 兜底:如果目录结构变化,尝试向上搜索包含 AlgoriAgent 的目录作为 repo_root - if not (repo_root / "AlgoriAgent").exists(): - for p in here.parents: - if (p / "AlgoriAgent").is_dir(): - repo_root = p - break - - # 确保仓库根在 sys.path(这样 'AlgoriAgent' 顶层包可被发现) - repo_root_str = str(repo_root) - if repo_root_str not in sys.path: - sys.path.insert(0, repo_root_str) - - # 可选:如果你还有其它顶层包,也可在此处继续插入 - - # 默认学习工作区目录(也可放到 config.ini / 环境变量覆盖) - os.environ.setdefault("STUDENT_WORKSPACE_ROOT", str(repo_root / "study")) - - return repo_root # 方便调试/日志 \ No newline at end of file diff --git a/Html/runs/run_20250911-092225_wfvsed/code/wsgi.py b/Html/runs/run_20250911-092225_wfvsed/code/wsgi.py deleted file mode 100644 index bbcbe5f..0000000 --- a/Html/runs/run_20250911-092225_wfvsed/code/wsgi.py +++ /dev/null @@ -1,6 +0,0 @@ -# wsgi.py -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -# 提供一个可被 WSGI/进程管理器导入的 app 对象 -app = create_app() diff --git a/Html/runs/run_20250911-092225_wfvsed/logging.chat b/Html/runs/run_20250911-092225_wfvsed/logging.chat deleted file mode 100644 index e69de29..0000000 diff --git a/Html/runs/run_20250911-092225_wfvsed/logging.log b/Html/runs/run_20250911-092225_wfvsed/logging.log deleted file mode 100644 index ea9d371..0000000 --- a/Html/runs/run_20250911-092225_wfvsed/logging.log +++ /dev/null @@ -1 +0,0 @@ -2025-09-11 09:22:31.682 | INFO | agentscope.models:read_model_configs:186 - Load configs for model wrapper: openai_cfg diff --git a/Html/runs/run_20250911-092231_bhi1fr/.config b/Html/runs/run_20250911-092231_bhi1fr/.config deleted file mode 100644 index 3cb3c98..0000000 --- a/Html/runs/run_20250911-092231_bhi1fr/.config +++ /dev/null @@ -1,7 +0,0 @@ -{ - "project": "shO9Jd", - "name": "bhi1fr", - "run_id": "run_20250911-092231_bhi1fr", - "timestamp": "2025-09-11 09:22:31", - "pid": 13857 -} \ No newline at end of file diff --git a/Html/runs/run_20250911-092231_bhi1fr/agentscope.db b/Html/runs/run_20250911-092231_bhi1fr/agentscope.db deleted file mode 100644 index 666055b77679cda29c14fcf23b4ef1d039c5b52a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI%L2KJE6bEoS4Q(k)+glI2yjv3-0%NB!Hs&O1YUav`W0U1F<0V=#BsNLx(sSu$ z>=W&q?4#^B$!*yt2YT5l`~^0a^z(#~{ zkyg6w!t)u0!@f%5aeaJcfD9*Q_b$ozCY8>~CFA6|{Z2V!N;Z^cIq}eS$>x3HY|^=j z7lokrf1)Z$x@_R^N~@apn7OPMkZ(I<*1WJCw@v3GWy2n6&RcIQ0~zlR_x8^$%be!% zmxb7@7V;}H+K5#l(wSbZKXKY!mys6ROyi|!%aN@+%REpi?;B-K4PC3&{>iCzQnNB+ zwbW!z4iA{x(V_2L+5VJ1vMJeN;5l68yJ9?OZyl-TNCEp4P{^H8$cTGExdq$9ANE6@ zA@`ZUhb>is+Y=S?%$C1fnN{muZU1a!nMRV%#qFbMT;y3hf|KlJ)00Izz00bZa0SG_<0uX=z1a@EGHy1PL*Z=?k diff --git a/Html/runs/run_20250911-092231_bhi1fr/code/app.py b/Html/runs/run_20250911-092231_bhi1fr/code/app.py deleted file mode 100644 index c7f31f7..0000000 --- a/Html/runs/run_20250911-092231_bhi1fr/code/app.py +++ /dev/null @@ -1,21 +0,0 @@ -# app.py 0.1.1 rise to factory mode -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -from apps.extensions import socketio - -# 工厂创建 app,工厂里已经做了:加载配置/注册蓝图/注册 namespaces -app = create_app() - -if __name__ == "__main__": - # 仅本地开发用;生产不要用 werkzeug 自带的开发服务器 - socketio.run( - app, - host="0.0.0.0", - port=5551, - debug=True, # 开发期打开 - allow_unsafe_werkzeug=True, # 避免 dev server 的安全限制提示 - # ssl_context=('server.crt', 'server.key') - ) - - diff --git a/Html/runs/run_20250911-092231_bhi1fr/code/app_back.py b/Html/runs/run_20250911-092231_bhi1fr/code/app_back.py deleted file mode 100644 index 246853c..0000000 --- a/Html/runs/run_20250911-092231_bhi1fr/code/app_back.py +++ /dev/null @@ -1,480 +0,0 @@ -from bootstrap import bootstrap_paths -bootstrap_paths() -from functools import wraps -from flask import Flask, redirect, session, request, jsonify, render_template, send_from_directory, url_for -from flask_cors import CORS -from flask_socketio import SocketIO, join_room, emit, Namespace -import markdown -import os -import uuid -import shutil -import sys -import json -from apps.auth.decorators import require_role -parent_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) -sys.path.insert(0, parent_dir) -student_workspace_root_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../study')) -current_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '.')) -sys.path.insert(0, current_dir) -from AlgoriAgent.projects.algoriAgent.agent_manager import AgentManager - - -import configparser - -from db.user_list import UserList -from db.user import User, load_user_from_json, create_user_json -from db.course_list import CourseList -from db.course import Course, load_course_from_json -GLOBAL_CONFIG = configparser.ConfigParser() -GLOBAL_CONFIG.read('config.ini') -VSCODE_WEB_URL = GLOBAL_CONFIG['VSCODE_WEB']['url'] -USER_DATA_DIR = GLOBAL_CONFIG['USER_DATA']['dir'] -COURSE_DATA_DIR = GLOBAL_CONFIG['COURSE_DATA']['dir'] - -app = Flask(__name__) -socketio = SocketIO(app, cors_allowed_origins="*",ping_timeout=60, ping_interval=5) -# socketio = SocketIO(app, cors_allowed_origins="http://localhost:9888") # 设置跨域支持 -import logging -app.secret_key = 'cakebaker' -app.logger.setLevel(logging.DEBUG) -# 配置 CORS -CORS(app, resources={r"/*": {"origins": VSCODE_WEB_URL},}, supports_credentials=True) - - -userid_recorder = {} # user_id&path -> session['user_id'] - -''' -Backboard -''' -from backboardManager import BackBoardManager, Backboard - -backboard_manager = BackBoardManager() -uuid2username = {} -username2uuid = {} - - - -# 定义命名空间:用于和 VSCode 插件交流 -class VSCodeNamespace(Namespace): - def on_login(self,data): - print("VSCode client connected") - print(data) - dataconfig = data['config'] - user_id = dataconfig.get('user_id') - path = dataconfig.get('path') - course_id = dataconfig.get('course_id') - lesson_id = dataconfig.get('chapter_id') - print(f"User {user_id} connected with path: {path}") - useruuid = username2uuid[user_id] - join_room(useruuid, namespace='/vscode') - if backboard_manager.get_backboard(useruuid) == None: - backboard_manager.add_backboard(useruuid,user_id, course_id, lesson_id, path) - - - def on_message(self, data): - print(f"Received from VSCode client: {data}") - dataconfig = data['config'] - realtime_response(dataconfig, data) - # emit('response', {'message': 'Config data received and connection established'}) - def on_disconnect(self, data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - -def realtime_response(config, realtime_action): - user_id = config['user_id'] - folder_path = config['path'] - useruuid = username2uuid[user_id] - bb = backboard_manager.get_backboard(useruuid) - assert type(bb) == Backboard - - bb.add_history(realtime_action) - - if realtime_action['type'] == 'workspaceFolders': - bb.file_tree = realtime_action['fileTree'] - - if realtime_action['type'] == 'activeFile': - file_path = realtime_action['filePath'] - assert type(file_path) == str - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - if realtime_action['type'] == 'paste': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.pasted_file_path = file_path - bb.pasted_content = realtime_action['content'] - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - if realtime_action['type'] == 'fileEdit': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - - - print("config"+str(config)) - print("realtime_action"+str(realtime_action)) - pass - - -''' -Agent and Chat -''' -agent_manager = AgentManager(app = app, socketio = socketio) -user_threads = {} -import threading -from concurrent.futures import ThreadPoolExecutor, as_completed - -# 初始化线程池 -executor = ThreadPoolExecutor(max_workers=10) -class AgentNamespace(Namespace): - def on_login(self, data): - data = json.loads(data) - user = data['username'] - course_id = data['course_id'] - chapter_id = data['chapter_id'] - user_uuid = username2uuid[user] - session['user_id'] = user_uuid - print(f'User connected with session user_id: {user_uuid}') - # 从markdown、markdown_prompts、score_prompts中各读取数据folder.md并进行new_agent - with open(f'books/markdown/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fmd,\ - open(f'books/markdown_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8')as fmdp,\ - open(f'books/score_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fsp: - markdown = fmd.read() - markdown_prompts = fmdp.read() - score_prompts = fsp.read() - user_uuid, agent = agent_manager.new_agent(course_id, chapter_id, markdown, markdown_prompts, score_prompts, id=user_uuid, - root_path=f'../../study/{user}/{course_id}/{chapter_id}') - print(user_uuid) - join_room(user_uuid, namespace='/agent') # 将该用户加入以user_id为名的room - backboard_manager.add_backboard(user_uuid, user, course_id, chapter_id, root_path=f'../../study/{user}/{course_id}/{chapter_id}') - - def on_language(self, language): - id = session.get('user_id') - agent_manager.change_language(id, language) - - def on_message(self, data): - print(f"Message from client: {data}") - id = session.get('user_id') - if (type(data)==str): - data = json.loads(data) - print(id) - if data['type'] == 'text': - res = agent_manager.invoke(id, data['data'], backboard_manager.get_backboard(id).get_info_prompt()) - print('=*='*20) - print(res.content) - reply = f"{res.content['speak']}" - with app.app_context(): - emit('message',reply, room=id, namespace='/agent') - emit('request_function',res.content['function'], room=id, namespace='/agent') - - if data['type'] == 'function': - agent_manager.function_call(id, data['data']) - - def on_initiative(self,data): - print("User active function call") - user_id = session['user_id'] - if data['name'] == 'sample_judge': - agent_manager.sample_judge(user_id, backboard_manager.get_backboard(user_id)) - if data['name'] == 'judge': - agent_manager.judge(user_id, backboard_manager.get_backboard(user_id)) - - - - def on_disconnect(self,data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - - -''' -Markdown to HTML -''' -# 配置文件路径 -MARKDOWN_DIR = 'books/markdown' # 存放 markdown 文件的文件夹 -STATIC_DIR = 'static' # 存放生成的 HTML 和图片资源的文件夹 -IMAGE_DIR = 'image' # 图片资源相对于 markdown 的位置 - - - -@app.route('/--markdown', methods=['GET']) -def convert_md(course_id, filename): - md_file_path = os.path.join(MARKDOWN_DIR,course_id, f'{filename}.md') - - if not os.path.exists(md_file_path): - return jsonify({'error': 'Markdown file not found'}), 404 - - # 读取 markdown 文件内容 - with open(md_file_path, 'r', encoding='utf-8') as file: - md_content = file.read() - - # 将 markdown 转换为 HTML - html_content = markdown.markdown(md_content) - # 插入 CSS 样式,限制图片最大宽度为 100%,高度自动调整 - html_with_styles = f""" - - - - - - - {html_content} - - - """ - # 保存 HTML 文件到 static 文件夹 - html_output_path = os.path.join(STATIC_DIR, f'{filename}.html') - with open(html_output_path, 'w', encoding='utf-8') as html_file: - html_file.write(html_with_styles) - - # 处理图片资源,将 image/xxx 文件夹拷贝到 static/image/xxx - image_source_dir = os.path.join(MARKDOWN_DIR,course_id, IMAGE_DIR, filename) - image_target_dir = os.path.join(STATIC_DIR, IMAGE_DIR, filename) - print(f"Copying image resources from {image_source_dir} to {image_target_dir}") - if os.path.exists(image_source_dir): - # 确保 static/image/xxx 目录存在 - if not os.path.exists(image_target_dir): - os.makedirs(image_target_dir) - - # 拷贝图片资源 - for image_file in os.listdir(image_source_dir): - full_image_file_path = os.path.join(image_source_dir, image_file) - if os.path.isfile(full_image_file_path): - shutil.copy(full_image_file_path, image_target_dir) - - return jsonify({'html_url': f'/static/{filename}.html'}) - -# 静态文件(HTML 和图片资源)的访问 -@app.route('/static/') -def serve_static(filename): - return send_from_directory(STATIC_DIR, filename) - - -''' -Vscode -''' -@app.route('/desktop///') -def desktop(user_id, course_id, chapter_id): - if 'user_id' not in session: - # return redirect(url_for('login')) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ user_id + "uuid is"+ session['user_id']) - username2uuid[user_id] = session['user_id'] - uuid2username[session['user_id']] = user_id - userid_recorder[user_id+'&'+course_id] = session['user_id'] - - # 在学习目录下创建一个名为 user_id_path 的文件夹 - path_dir = os.path.join(student_workspace_root_path, user_id, course_id,chapter_id) - os.makedirs(path_dir, exist_ok=True) - # 在此文件夹内部创建一个.config文件,并写入 user_id=user_id\n path=path - config_path = os.path.join(path_dir, '.config') - if GLOBAL_CONFIG['VSCODE_WEB_PATH']['is_wsl']: # 如果是在 WSL 中运行,则将路径转换为 WSL 路径 - path_dir = path_dir.replace('\\', '/') - path_dir = path_dir.replace(GLOBAL_CONFIG['VSCODE_WEB_PATH']['windows_path'] , GLOBAL_CONFIG['VSCODE_WEB_PATH']['wsl_path']) - with open(config_path, 'w', encoding='utf-8') as f: - tmpd = {'user_id': user_id, 'course_id': course_id, 'chapter_id': chapter_id, 'path': path_dir} - json.dump(tmpd, f) - print('---------------------') - print(config_path) - return render_template('desktop.html', vscode_web_url=VSCODE_WEB_URL, user_id=user_id, course_id=course_id, chapter_id=chapter_id, workspace_path=path_dir) - -@app.route('/desktop_nouser//') -def desktop_nouser(course_id, chapter_id): - if 'user_id' not in session: - return redirect(url_for('login')) - user_id = session['user_id'] - username = uuid2username[user_id] - return redirect(url_for('desktop', user_id=username, course_id=course_id, chapter_id=chapter_id)) - -@app.route('/vscode_data', methods=['POST']) -def vscode_data(): - data = request.json - config = data['config'] - realtime_response(config,data) - print(f"Received data from VSCode: {data}") - return jsonify({"status": "success", "received": data}) - - - -''' -Login - -''' -users_list = UserList() -course_list = CourseList() - - -@app.route('/register') -def register(): - return render_template('register.html') - -@app.route('/register_teacher') -def register_teacher(): - return render_template('register_teacher.html') - -@app.route('/register_teacher_post', methods=['POST']) -def register_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password, teacher=True) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - -@app.route('/register_post', methods=['POST']) -def register_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - - -@app.route('/login') -def login(): - return render_template('login.html') - if 'user_id' not in session: - return render_template('login.html') - else: - return redirect(url_for('/')) - -@app.route('/login_post', methods=['POST']) -def login_post(): - # 获取请求的 JSON 数据 - data = request.get_json() - - username = data.get('username') - password = data.get('password') - - pswd = users_list.get_user_pswd(username) - - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/login_teacher_post', methods=['POST']) -def login_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - pswd = users_list.get_user_pswd(username) - is_teacher = users_list.get_user_is_teacher(username) - if is_teacher is None or is_teacher == False: - return jsonify({'success': False, 'message': '用户名不存在或非教师账号'}) - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/teacherboard') -@require_role(roles="teacher") -def teacherboard(): - return render_template('teacherboard.html') - - -@app.route('/logout') -def logout(): - session.pop('user_id', None) - return redirect(url_for('login')) - -@app.route('/get_session') -def get_session(): - user_session = session.get('user_id', 'default_session') - return jsonify({"session": user_session}) - - -''' -DashBoard -''' -user_id2UserClass = {} -@app.route('/dashboard') -@require_role -def dashboard(): - user_id = session['user_id'] - username = uuid2username[user_id] - if (user_id not in user_id2UserClass): - user_id2UserClass[user_id] = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - user_course_data = [] - for course_id in user_id2UserClass[user_id].select_course: - course_brief_info = course_list.get_course_brief_info(course_id, load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR)) - user_course_data.append(course_brief_info) - return render_template('dashboard.html',user_data = user_id2UserClass[user_id].to_json_without_dialog(), user_course_data = json.dumps(user_course_data)) - -''' -Course -''' - -@app.route('/course/') -@require_role -def course(course_id): - c = load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR) - return render_template('course.html', course_id=course_id, course_data=c) - -@app.route('/select_course', methods=['POST']) -@require_role -def select_course(): - user = user_id2UserClass[session['user_id']] - data = request.get_json() - course_id = data.get('course_id') - if course_id: - user.select_new_course(course_id, load_course_from_json(course_id, COURSE_DATA_DIR)) - return jsonify({'success': True, 'message': '课程选择成功'}) - - -@app.route('/') -@require_role -def home_index(): - selected_courses=[] - if ('user_id' in session): - if (session['user_id'] not in user_id2UserClass): return redirect(url_for('login')) - user = user_id2UserClass[session['user_id']] - for course_id in user.select_course: - selected_courses.append(course_id) - - return render_template('index.html', courses_data = course_list, selected_courses =selected_courses) - -# 一些app辅助函数,主要提供给Agent与数据库的交互能力 - -class MyFunction: - def save_chapter_memory(self, id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal): - print("-=-=-=-=-=-=-=-") - print(id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - username = uuid2username[id] - u = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - u.save_chapter_memory(course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - -app.my_function = MyFunction() -if __name__ == '__main__': - socketio.on_namespace(VSCodeNamespace('/vscode')) - socketio.on_namespace(AgentNamespace('/agent')) - socketio.run(app, host='0.0.0.0', port=5551, debug=False,allow_unsafe_werkzeug=True) - diff --git a/Html/runs/run_20250911-092231_bhi1fr/code/backboardManager.py b/Html/runs/run_20250911-092231_bhi1fr/code/backboardManager.py deleted file mode 100644 index 7de5f19..0000000 --- a/Html/runs/run_20250911-092231_bhi1fr/code/backboardManager.py +++ /dev/null @@ -1,80 +0,0 @@ - - - -import time -import os - -class Backboard: - def __init__(self, user_uuid, username, course_id, lesson_id, root_path): - self.user_uuid = user_uuid - self.username = username - self.course_id = course_id - self.lesson_id = lesson_id - self.root_path = root_path - self.create_time = time.time() - self.enter_chapter_time = time.time() - self.history = [] - self.file_tree = "[]" - self.active_file_path = "" - self.active_file_content = "" - self.pasted_file_path = "" - self.pasted_content = "" - - - def next_chapter(self): - self.enter_chapter_time = time.time() - - def get_info_prompt(self): - - five_history = "" - for h in self.history[-5:]: - five_history += h['type'] + "\n" + h.get('filePath', '') + "\n\n" - - endl = "\n" - return (f"###Global Info:###{endl}" - f"Here are some info about now user's IDE, refer to it when you need to handle some code.{endl}" - f"- User's total study time is {self.get_deltatime_mmss(self.create_time, time.time())}{endl}" - f"- User's current chapter study time is {self.get_deltatime_mmss(self.enter_chapter_time, time.time())}{endl}" - f"- Activated file path: {self.active_file_path}{endl}" - f"```{endl}" - f"{self.active_file_content[-10:]}{endl}" - f"```{endl}" - f"- Last five action:{five_history}{endl}" - f"- File tree: {self.file_tree}{endl}") - # f"- Activated file content (current editing 10 lines): {endl}" - def add_history(self, realtime_action): - if(realtime_action['type']=='config'):return - if len(self.history)!=0: - if (self.history[-1]['type']=='fileEdit'): - if(self.history[-1]['filePath'] == realtime_action['filePath']): - self.history[-1]['content'] = realtime_action['content'] - return - self.history.append(realtime_action) - - - def get_deltatime_mmss(self, start_time, end_time): - elapsed_time = end_time - start_time - hours = int(elapsed_time // 3600) - minutes = int((elapsed_time % 3600) // 60) - seconds = int(elapsed_time % 60) - return f"{hours:02d}:{minutes:02d}:{seconds:02d}" - - - def get_active_file_reletive_path(self): - relative_path = os.path.relpath(self.active_file_path, self.root_path) - return relative_path - - - -class BackBoardManager: - def __init__(self): - self.backboards = {} # user_uuid: Backboard - - def add_backboard(self, user_uuid, username, course_id, lesson_id, root_path): - self.backboards[user_uuid] = Backboard(user_uuid,username, course_id, lesson_id, root_path) - - def get_backboard(self, user_uuid) -> Backboard: - return self.backboards[user_uuid] - - - diff --git a/Html/runs/run_20250911-092231_bhi1fr/code/bootstrap.py b/Html/runs/run_20250911-092231_bhi1fr/code/bootstrap.py deleted file mode 100644 index bcb15ce..0000000 --- a/Html/runs/run_20250911-092231_bhi1fr/code/bootstrap.py +++ /dev/null @@ -1,31 +0,0 @@ -from pathlib import Path -import sys, os - -def bootstrap_paths(): - """ - 让 'AlgoriAgent'(位于 repo_root/AlgoriAgent)可被 import; - 并提供 STUDENT_WORKSPACE_ROOT 的默认值(repo_root/study)。 - 适配当前工厂位置:repo_root/Html/apps/__init__.py - """ - here = Path(__file__).resolve() - # repo_root = .../Html/apps/../../ => parents[2] - repo_root = here.parents[2] - - # 兜底:如果目录结构变化,尝试向上搜索包含 AlgoriAgent 的目录作为 repo_root - if not (repo_root / "AlgoriAgent").exists(): - for p in here.parents: - if (p / "AlgoriAgent").is_dir(): - repo_root = p - break - - # 确保仓库根在 sys.path(这样 'AlgoriAgent' 顶层包可被发现) - repo_root_str = str(repo_root) - if repo_root_str not in sys.path: - sys.path.insert(0, repo_root_str) - - # 可选:如果你还有其它顶层包,也可在此处继续插入 - - # 默认学习工作区目录(也可放到 config.ini / 环境变量覆盖) - os.environ.setdefault("STUDENT_WORKSPACE_ROOT", str(repo_root / "study")) - - return repo_root # 方便调试/日志 \ No newline at end of file diff --git a/Html/runs/run_20250911-092231_bhi1fr/code/wsgi.py b/Html/runs/run_20250911-092231_bhi1fr/code/wsgi.py deleted file mode 100644 index bbcbe5f..0000000 --- a/Html/runs/run_20250911-092231_bhi1fr/code/wsgi.py +++ /dev/null @@ -1,6 +0,0 @@ -# wsgi.py -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -# 提供一个可被 WSGI/进程管理器导入的 app 对象 -app = create_app() diff --git a/Html/runs/run_20250911-092231_bhi1fr/logging.chat b/Html/runs/run_20250911-092231_bhi1fr/logging.chat deleted file mode 100644 index e69de29..0000000 diff --git a/Html/runs/run_20250911-092231_bhi1fr/logging.log b/Html/runs/run_20250911-092231_bhi1fr/logging.log deleted file mode 100644 index 652f1bf..0000000 --- a/Html/runs/run_20250911-092231_bhi1fr/logging.log +++ /dev/null @@ -1 +0,0 @@ -2025-09-11 09:22:35.414 | INFO | agentscope.models:read_model_configs:186 - Load configs for model wrapper: openai_cfg diff --git a/Html/runs/run_20250911-092325_o2aue5/.config b/Html/runs/run_20250911-092325_o2aue5/.config deleted file mode 100644 index b536e2e..0000000 --- a/Html/runs/run_20250911-092325_o2aue5/.config +++ /dev/null @@ -1,7 +0,0 @@ -{ - "project": "X5PWGj", - "name": "o2aue5", - "run_id": "run_20250911-092325_o2aue5", - "timestamp": "2025-09-11 09:23:25", - "pid": 14344 -} \ No newline at end of file diff --git a/Html/runs/run_20250911-092325_o2aue5/agentscope.db b/Html/runs/run_20250911-092325_o2aue5/agentscope.db deleted file mode 100644 index 666055b77679cda29c14fcf23b4ef1d039c5b52a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI%L2KJE6bEoS4Q(k)+glI2yjv3-0%NB!Hs&O1YUav`W0U1F<0V=#BsNLx(sSu$ z>=W&q?4#^B$!*yt2YT5l`~^0a^z(#~{ zkyg6w!t)u0!@f%5aeaJcfD9*Q_b$ozCY8>~CFA6|{Z2V!N;Z^cIq}eS$>x3HY|^=j z7lokrf1)Z$x@_R^N~@apn7OPMkZ(I<*1WJCw@v3GWy2n6&RcIQ0~zlR_x8^$%be!% zmxb7@7V;}H+K5#l(wSbZKXKY!mys6ROyi|!%aN@+%REpi?;B-K4PC3&{>iCzQnNB+ zwbW!z4iA{x(V_2L+5VJ1vMJeN;5l68yJ9?OZyl-TNCEp4P{^H8$cTGExdq$9ANE6@ zA@`ZUhb>is+Y=S?%$C1fnN{muZU1a!nMRV%#qFbMT;y3hf|KlJ)00Izz00bZa0SG_<0uX=z1a@EGHy1PL*Z=?k diff --git a/Html/runs/run_20250911-092325_o2aue5/code/app.py b/Html/runs/run_20250911-092325_o2aue5/code/app.py deleted file mode 100644 index c7f31f7..0000000 --- a/Html/runs/run_20250911-092325_o2aue5/code/app.py +++ /dev/null @@ -1,21 +0,0 @@ -# app.py 0.1.1 rise to factory mode -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -from apps.extensions import socketio - -# 工厂创建 app,工厂里已经做了:加载配置/注册蓝图/注册 namespaces -app = create_app() - -if __name__ == "__main__": - # 仅本地开发用;生产不要用 werkzeug 自带的开发服务器 - socketio.run( - app, - host="0.0.0.0", - port=5551, - debug=True, # 开发期打开 - allow_unsafe_werkzeug=True, # 避免 dev server 的安全限制提示 - # ssl_context=('server.crt', 'server.key') - ) - - diff --git a/Html/runs/run_20250911-092325_o2aue5/code/app_back.py b/Html/runs/run_20250911-092325_o2aue5/code/app_back.py deleted file mode 100644 index 246853c..0000000 --- a/Html/runs/run_20250911-092325_o2aue5/code/app_back.py +++ /dev/null @@ -1,480 +0,0 @@ -from bootstrap import bootstrap_paths -bootstrap_paths() -from functools import wraps -from flask import Flask, redirect, session, request, jsonify, render_template, send_from_directory, url_for -from flask_cors import CORS -from flask_socketio import SocketIO, join_room, emit, Namespace -import markdown -import os -import uuid -import shutil -import sys -import json -from apps.auth.decorators import require_role -parent_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) -sys.path.insert(0, parent_dir) -student_workspace_root_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../study')) -current_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '.')) -sys.path.insert(0, current_dir) -from AlgoriAgent.projects.algoriAgent.agent_manager import AgentManager - - -import configparser - -from db.user_list import UserList -from db.user import User, load_user_from_json, create_user_json -from db.course_list import CourseList -from db.course import Course, load_course_from_json -GLOBAL_CONFIG = configparser.ConfigParser() -GLOBAL_CONFIG.read('config.ini') -VSCODE_WEB_URL = GLOBAL_CONFIG['VSCODE_WEB']['url'] -USER_DATA_DIR = GLOBAL_CONFIG['USER_DATA']['dir'] -COURSE_DATA_DIR = GLOBAL_CONFIG['COURSE_DATA']['dir'] - -app = Flask(__name__) -socketio = SocketIO(app, cors_allowed_origins="*",ping_timeout=60, ping_interval=5) -# socketio = SocketIO(app, cors_allowed_origins="http://localhost:9888") # 设置跨域支持 -import logging -app.secret_key = 'cakebaker' -app.logger.setLevel(logging.DEBUG) -# 配置 CORS -CORS(app, resources={r"/*": {"origins": VSCODE_WEB_URL},}, supports_credentials=True) - - -userid_recorder = {} # user_id&path -> session['user_id'] - -''' -Backboard -''' -from backboardManager import BackBoardManager, Backboard - -backboard_manager = BackBoardManager() -uuid2username = {} -username2uuid = {} - - - -# 定义命名空间:用于和 VSCode 插件交流 -class VSCodeNamespace(Namespace): - def on_login(self,data): - print("VSCode client connected") - print(data) - dataconfig = data['config'] - user_id = dataconfig.get('user_id') - path = dataconfig.get('path') - course_id = dataconfig.get('course_id') - lesson_id = dataconfig.get('chapter_id') - print(f"User {user_id} connected with path: {path}") - useruuid = username2uuid[user_id] - join_room(useruuid, namespace='/vscode') - if backboard_manager.get_backboard(useruuid) == None: - backboard_manager.add_backboard(useruuid,user_id, course_id, lesson_id, path) - - - def on_message(self, data): - print(f"Received from VSCode client: {data}") - dataconfig = data['config'] - realtime_response(dataconfig, data) - # emit('response', {'message': 'Config data received and connection established'}) - def on_disconnect(self, data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - -def realtime_response(config, realtime_action): - user_id = config['user_id'] - folder_path = config['path'] - useruuid = username2uuid[user_id] - bb = backboard_manager.get_backboard(useruuid) - assert type(bb) == Backboard - - bb.add_history(realtime_action) - - if realtime_action['type'] == 'workspaceFolders': - bb.file_tree = realtime_action['fileTree'] - - if realtime_action['type'] == 'activeFile': - file_path = realtime_action['filePath'] - assert type(file_path) == str - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - if realtime_action['type'] == 'paste': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.pasted_file_path = file_path - bb.pasted_content = realtime_action['content'] - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - if realtime_action['type'] == 'fileEdit': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - - - print("config"+str(config)) - print("realtime_action"+str(realtime_action)) - pass - - -''' -Agent and Chat -''' -agent_manager = AgentManager(app = app, socketio = socketio) -user_threads = {} -import threading -from concurrent.futures import ThreadPoolExecutor, as_completed - -# 初始化线程池 -executor = ThreadPoolExecutor(max_workers=10) -class AgentNamespace(Namespace): - def on_login(self, data): - data = json.loads(data) - user = data['username'] - course_id = data['course_id'] - chapter_id = data['chapter_id'] - user_uuid = username2uuid[user] - session['user_id'] = user_uuid - print(f'User connected with session user_id: {user_uuid}') - # 从markdown、markdown_prompts、score_prompts中各读取数据folder.md并进行new_agent - with open(f'books/markdown/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fmd,\ - open(f'books/markdown_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8')as fmdp,\ - open(f'books/score_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fsp: - markdown = fmd.read() - markdown_prompts = fmdp.read() - score_prompts = fsp.read() - user_uuid, agent = agent_manager.new_agent(course_id, chapter_id, markdown, markdown_prompts, score_prompts, id=user_uuid, - root_path=f'../../study/{user}/{course_id}/{chapter_id}') - print(user_uuid) - join_room(user_uuid, namespace='/agent') # 将该用户加入以user_id为名的room - backboard_manager.add_backboard(user_uuid, user, course_id, chapter_id, root_path=f'../../study/{user}/{course_id}/{chapter_id}') - - def on_language(self, language): - id = session.get('user_id') - agent_manager.change_language(id, language) - - def on_message(self, data): - print(f"Message from client: {data}") - id = session.get('user_id') - if (type(data)==str): - data = json.loads(data) - print(id) - if data['type'] == 'text': - res = agent_manager.invoke(id, data['data'], backboard_manager.get_backboard(id).get_info_prompt()) - print('=*='*20) - print(res.content) - reply = f"{res.content['speak']}" - with app.app_context(): - emit('message',reply, room=id, namespace='/agent') - emit('request_function',res.content['function'], room=id, namespace='/agent') - - if data['type'] == 'function': - agent_manager.function_call(id, data['data']) - - def on_initiative(self,data): - print("User active function call") - user_id = session['user_id'] - if data['name'] == 'sample_judge': - agent_manager.sample_judge(user_id, backboard_manager.get_backboard(user_id)) - if data['name'] == 'judge': - agent_manager.judge(user_id, backboard_manager.get_backboard(user_id)) - - - - def on_disconnect(self,data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - - -''' -Markdown to HTML -''' -# 配置文件路径 -MARKDOWN_DIR = 'books/markdown' # 存放 markdown 文件的文件夹 -STATIC_DIR = 'static' # 存放生成的 HTML 和图片资源的文件夹 -IMAGE_DIR = 'image' # 图片资源相对于 markdown 的位置 - - - -@app.route('/--markdown', methods=['GET']) -def convert_md(course_id, filename): - md_file_path = os.path.join(MARKDOWN_DIR,course_id, f'{filename}.md') - - if not os.path.exists(md_file_path): - return jsonify({'error': 'Markdown file not found'}), 404 - - # 读取 markdown 文件内容 - with open(md_file_path, 'r', encoding='utf-8') as file: - md_content = file.read() - - # 将 markdown 转换为 HTML - html_content = markdown.markdown(md_content) - # 插入 CSS 样式,限制图片最大宽度为 100%,高度自动调整 - html_with_styles = f""" - - - - - - - {html_content} - - - """ - # 保存 HTML 文件到 static 文件夹 - html_output_path = os.path.join(STATIC_DIR, f'{filename}.html') - with open(html_output_path, 'w', encoding='utf-8') as html_file: - html_file.write(html_with_styles) - - # 处理图片资源,将 image/xxx 文件夹拷贝到 static/image/xxx - image_source_dir = os.path.join(MARKDOWN_DIR,course_id, IMAGE_DIR, filename) - image_target_dir = os.path.join(STATIC_DIR, IMAGE_DIR, filename) - print(f"Copying image resources from {image_source_dir} to {image_target_dir}") - if os.path.exists(image_source_dir): - # 确保 static/image/xxx 目录存在 - if not os.path.exists(image_target_dir): - os.makedirs(image_target_dir) - - # 拷贝图片资源 - for image_file in os.listdir(image_source_dir): - full_image_file_path = os.path.join(image_source_dir, image_file) - if os.path.isfile(full_image_file_path): - shutil.copy(full_image_file_path, image_target_dir) - - return jsonify({'html_url': f'/static/{filename}.html'}) - -# 静态文件(HTML 和图片资源)的访问 -@app.route('/static/') -def serve_static(filename): - return send_from_directory(STATIC_DIR, filename) - - -''' -Vscode -''' -@app.route('/desktop///') -def desktop(user_id, course_id, chapter_id): - if 'user_id' not in session: - # return redirect(url_for('login')) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ user_id + "uuid is"+ session['user_id']) - username2uuid[user_id] = session['user_id'] - uuid2username[session['user_id']] = user_id - userid_recorder[user_id+'&'+course_id] = session['user_id'] - - # 在学习目录下创建一个名为 user_id_path 的文件夹 - path_dir = os.path.join(student_workspace_root_path, user_id, course_id,chapter_id) - os.makedirs(path_dir, exist_ok=True) - # 在此文件夹内部创建一个.config文件,并写入 user_id=user_id\n path=path - config_path = os.path.join(path_dir, '.config') - if GLOBAL_CONFIG['VSCODE_WEB_PATH']['is_wsl']: # 如果是在 WSL 中运行,则将路径转换为 WSL 路径 - path_dir = path_dir.replace('\\', '/') - path_dir = path_dir.replace(GLOBAL_CONFIG['VSCODE_WEB_PATH']['windows_path'] , GLOBAL_CONFIG['VSCODE_WEB_PATH']['wsl_path']) - with open(config_path, 'w', encoding='utf-8') as f: - tmpd = {'user_id': user_id, 'course_id': course_id, 'chapter_id': chapter_id, 'path': path_dir} - json.dump(tmpd, f) - print('---------------------') - print(config_path) - return render_template('desktop.html', vscode_web_url=VSCODE_WEB_URL, user_id=user_id, course_id=course_id, chapter_id=chapter_id, workspace_path=path_dir) - -@app.route('/desktop_nouser//') -def desktop_nouser(course_id, chapter_id): - if 'user_id' not in session: - return redirect(url_for('login')) - user_id = session['user_id'] - username = uuid2username[user_id] - return redirect(url_for('desktop', user_id=username, course_id=course_id, chapter_id=chapter_id)) - -@app.route('/vscode_data', methods=['POST']) -def vscode_data(): - data = request.json - config = data['config'] - realtime_response(config,data) - print(f"Received data from VSCode: {data}") - return jsonify({"status": "success", "received": data}) - - - -''' -Login - -''' -users_list = UserList() -course_list = CourseList() - - -@app.route('/register') -def register(): - return render_template('register.html') - -@app.route('/register_teacher') -def register_teacher(): - return render_template('register_teacher.html') - -@app.route('/register_teacher_post', methods=['POST']) -def register_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password, teacher=True) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - -@app.route('/register_post', methods=['POST']) -def register_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - - -@app.route('/login') -def login(): - return render_template('login.html') - if 'user_id' not in session: - return render_template('login.html') - else: - return redirect(url_for('/')) - -@app.route('/login_post', methods=['POST']) -def login_post(): - # 获取请求的 JSON 数据 - data = request.get_json() - - username = data.get('username') - password = data.get('password') - - pswd = users_list.get_user_pswd(username) - - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/login_teacher_post', methods=['POST']) -def login_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - pswd = users_list.get_user_pswd(username) - is_teacher = users_list.get_user_is_teacher(username) - if is_teacher is None or is_teacher == False: - return jsonify({'success': False, 'message': '用户名不存在或非教师账号'}) - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/teacherboard') -@require_role(roles="teacher") -def teacherboard(): - return render_template('teacherboard.html') - - -@app.route('/logout') -def logout(): - session.pop('user_id', None) - return redirect(url_for('login')) - -@app.route('/get_session') -def get_session(): - user_session = session.get('user_id', 'default_session') - return jsonify({"session": user_session}) - - -''' -DashBoard -''' -user_id2UserClass = {} -@app.route('/dashboard') -@require_role -def dashboard(): - user_id = session['user_id'] - username = uuid2username[user_id] - if (user_id not in user_id2UserClass): - user_id2UserClass[user_id] = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - user_course_data = [] - for course_id in user_id2UserClass[user_id].select_course: - course_brief_info = course_list.get_course_brief_info(course_id, load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR)) - user_course_data.append(course_brief_info) - return render_template('dashboard.html',user_data = user_id2UserClass[user_id].to_json_without_dialog(), user_course_data = json.dumps(user_course_data)) - -''' -Course -''' - -@app.route('/course/') -@require_role -def course(course_id): - c = load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR) - return render_template('course.html', course_id=course_id, course_data=c) - -@app.route('/select_course', methods=['POST']) -@require_role -def select_course(): - user = user_id2UserClass[session['user_id']] - data = request.get_json() - course_id = data.get('course_id') - if course_id: - user.select_new_course(course_id, load_course_from_json(course_id, COURSE_DATA_DIR)) - return jsonify({'success': True, 'message': '课程选择成功'}) - - -@app.route('/') -@require_role -def home_index(): - selected_courses=[] - if ('user_id' in session): - if (session['user_id'] not in user_id2UserClass): return redirect(url_for('login')) - user = user_id2UserClass[session['user_id']] - for course_id in user.select_course: - selected_courses.append(course_id) - - return render_template('index.html', courses_data = course_list, selected_courses =selected_courses) - -# 一些app辅助函数,主要提供给Agent与数据库的交互能力 - -class MyFunction: - def save_chapter_memory(self, id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal): - print("-=-=-=-=-=-=-=-") - print(id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - username = uuid2username[id] - u = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - u.save_chapter_memory(course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - -app.my_function = MyFunction() -if __name__ == '__main__': - socketio.on_namespace(VSCodeNamespace('/vscode')) - socketio.on_namespace(AgentNamespace('/agent')) - socketio.run(app, host='0.0.0.0', port=5551, debug=False,allow_unsafe_werkzeug=True) - diff --git a/Html/runs/run_20250911-092325_o2aue5/code/backboardManager.py b/Html/runs/run_20250911-092325_o2aue5/code/backboardManager.py deleted file mode 100644 index 7de5f19..0000000 --- a/Html/runs/run_20250911-092325_o2aue5/code/backboardManager.py +++ /dev/null @@ -1,80 +0,0 @@ - - - -import time -import os - -class Backboard: - def __init__(self, user_uuid, username, course_id, lesson_id, root_path): - self.user_uuid = user_uuid - self.username = username - self.course_id = course_id - self.lesson_id = lesson_id - self.root_path = root_path - self.create_time = time.time() - self.enter_chapter_time = time.time() - self.history = [] - self.file_tree = "[]" - self.active_file_path = "" - self.active_file_content = "" - self.pasted_file_path = "" - self.pasted_content = "" - - - def next_chapter(self): - self.enter_chapter_time = time.time() - - def get_info_prompt(self): - - five_history = "" - for h in self.history[-5:]: - five_history += h['type'] + "\n" + h.get('filePath', '') + "\n\n" - - endl = "\n" - return (f"###Global Info:###{endl}" - f"Here are some info about now user's IDE, refer to it when you need to handle some code.{endl}" - f"- User's total study time is {self.get_deltatime_mmss(self.create_time, time.time())}{endl}" - f"- User's current chapter study time is {self.get_deltatime_mmss(self.enter_chapter_time, time.time())}{endl}" - f"- Activated file path: {self.active_file_path}{endl}" - f"```{endl}" - f"{self.active_file_content[-10:]}{endl}" - f"```{endl}" - f"- Last five action:{five_history}{endl}" - f"- File tree: {self.file_tree}{endl}") - # f"- Activated file content (current editing 10 lines): {endl}" - def add_history(self, realtime_action): - if(realtime_action['type']=='config'):return - if len(self.history)!=0: - if (self.history[-1]['type']=='fileEdit'): - if(self.history[-1]['filePath'] == realtime_action['filePath']): - self.history[-1]['content'] = realtime_action['content'] - return - self.history.append(realtime_action) - - - def get_deltatime_mmss(self, start_time, end_time): - elapsed_time = end_time - start_time - hours = int(elapsed_time // 3600) - minutes = int((elapsed_time % 3600) // 60) - seconds = int(elapsed_time % 60) - return f"{hours:02d}:{minutes:02d}:{seconds:02d}" - - - def get_active_file_reletive_path(self): - relative_path = os.path.relpath(self.active_file_path, self.root_path) - return relative_path - - - -class BackBoardManager: - def __init__(self): - self.backboards = {} # user_uuid: Backboard - - def add_backboard(self, user_uuid, username, course_id, lesson_id, root_path): - self.backboards[user_uuid] = Backboard(user_uuid,username, course_id, lesson_id, root_path) - - def get_backboard(self, user_uuid) -> Backboard: - return self.backboards[user_uuid] - - - diff --git a/Html/runs/run_20250911-092325_o2aue5/code/bootstrap.py b/Html/runs/run_20250911-092325_o2aue5/code/bootstrap.py deleted file mode 100644 index bcb15ce..0000000 --- a/Html/runs/run_20250911-092325_o2aue5/code/bootstrap.py +++ /dev/null @@ -1,31 +0,0 @@ -from pathlib import Path -import sys, os - -def bootstrap_paths(): - """ - 让 'AlgoriAgent'(位于 repo_root/AlgoriAgent)可被 import; - 并提供 STUDENT_WORKSPACE_ROOT 的默认值(repo_root/study)。 - 适配当前工厂位置:repo_root/Html/apps/__init__.py - """ - here = Path(__file__).resolve() - # repo_root = .../Html/apps/../../ => parents[2] - repo_root = here.parents[2] - - # 兜底:如果目录结构变化,尝试向上搜索包含 AlgoriAgent 的目录作为 repo_root - if not (repo_root / "AlgoriAgent").exists(): - for p in here.parents: - if (p / "AlgoriAgent").is_dir(): - repo_root = p - break - - # 确保仓库根在 sys.path(这样 'AlgoriAgent' 顶层包可被发现) - repo_root_str = str(repo_root) - if repo_root_str not in sys.path: - sys.path.insert(0, repo_root_str) - - # 可选:如果你还有其它顶层包,也可在此处继续插入 - - # 默认学习工作区目录(也可放到 config.ini / 环境变量覆盖) - os.environ.setdefault("STUDENT_WORKSPACE_ROOT", str(repo_root / "study")) - - return repo_root # 方便调试/日志 \ No newline at end of file diff --git a/Html/runs/run_20250911-092325_o2aue5/code/wsgi.py b/Html/runs/run_20250911-092325_o2aue5/code/wsgi.py deleted file mode 100644 index bbcbe5f..0000000 --- a/Html/runs/run_20250911-092325_o2aue5/code/wsgi.py +++ /dev/null @@ -1,6 +0,0 @@ -# wsgi.py -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -# 提供一个可被 WSGI/进程管理器导入的 app 对象 -app = create_app() diff --git a/Html/runs/run_20250911-092325_o2aue5/logging.chat b/Html/runs/run_20250911-092325_o2aue5/logging.chat deleted file mode 100644 index e69de29..0000000 diff --git a/Html/runs/run_20250911-092325_o2aue5/logging.log b/Html/runs/run_20250911-092325_o2aue5/logging.log deleted file mode 100644 index 41b9ca8..0000000 --- a/Html/runs/run_20250911-092325_o2aue5/logging.log +++ /dev/null @@ -1 +0,0 @@ -2025-09-11 09:23:32.065 | INFO | agentscope.models:read_model_configs:186 - Load configs for model wrapper: openai_cfg diff --git a/Html/runs/run_20250911-092331_bvossb/.config b/Html/runs/run_20250911-092331_bvossb/.config deleted file mode 100644 index c93b1ac..0000000 --- a/Html/runs/run_20250911-092331_bvossb/.config +++ /dev/null @@ -1,7 +0,0 @@ -{ - "project": "Z8XB5F", - "name": "bvossb", - "run_id": "run_20250911-092331_bvossb", - "timestamp": "2025-09-11 09:23:31", - "pid": 14384 -} \ No newline at end of file diff --git a/Html/runs/run_20250911-092331_bvossb/agentscope.db b/Html/runs/run_20250911-092331_bvossb/agentscope.db deleted file mode 100644 index 666055b77679cda29c14fcf23b4ef1d039c5b52a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI%L2KJE6bEoS4Q(k)+glI2yjv3-0%NB!Hs&O1YUav`W0U1F<0V=#BsNLx(sSu$ z>=W&q?4#^B$!*yt2YT5l`~^0a^z(#~{ zkyg6w!t)u0!@f%5aeaJcfD9*Q_b$ozCY8>~CFA6|{Z2V!N;Z^cIq}eS$>x3HY|^=j z7lokrf1)Z$x@_R^N~@apn7OPMkZ(I<*1WJCw@v3GWy2n6&RcIQ0~zlR_x8^$%be!% zmxb7@7V;}H+K5#l(wSbZKXKY!mys6ROyi|!%aN@+%REpi?;B-K4PC3&{>iCzQnNB+ zwbW!z4iA{x(V_2L+5VJ1vMJeN;5l68yJ9?OZyl-TNCEp4P{^H8$cTGExdq$9ANE6@ zA@`ZUhb>is+Y=S?%$C1fnN{muZU1a!nMRV%#qFbMT;y3hf|KlJ)00Izz00bZa0SG_<0uX=z1a@EGHy1PL*Z=?k diff --git a/Html/runs/run_20250911-092331_bvossb/code/app.py b/Html/runs/run_20250911-092331_bvossb/code/app.py deleted file mode 100644 index c7f31f7..0000000 --- a/Html/runs/run_20250911-092331_bvossb/code/app.py +++ /dev/null @@ -1,21 +0,0 @@ -# app.py 0.1.1 rise to factory mode -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -from apps.extensions import socketio - -# 工厂创建 app,工厂里已经做了:加载配置/注册蓝图/注册 namespaces -app = create_app() - -if __name__ == "__main__": - # 仅本地开发用;生产不要用 werkzeug 自带的开发服务器 - socketio.run( - app, - host="0.0.0.0", - port=5551, - debug=True, # 开发期打开 - allow_unsafe_werkzeug=True, # 避免 dev server 的安全限制提示 - # ssl_context=('server.crt', 'server.key') - ) - - diff --git a/Html/runs/run_20250911-092331_bvossb/code/app_back.py b/Html/runs/run_20250911-092331_bvossb/code/app_back.py deleted file mode 100644 index 246853c..0000000 --- a/Html/runs/run_20250911-092331_bvossb/code/app_back.py +++ /dev/null @@ -1,480 +0,0 @@ -from bootstrap import bootstrap_paths -bootstrap_paths() -from functools import wraps -from flask import Flask, redirect, session, request, jsonify, render_template, send_from_directory, url_for -from flask_cors import CORS -from flask_socketio import SocketIO, join_room, emit, Namespace -import markdown -import os -import uuid -import shutil -import sys -import json -from apps.auth.decorators import require_role -parent_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) -sys.path.insert(0, parent_dir) -student_workspace_root_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../study')) -current_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '.')) -sys.path.insert(0, current_dir) -from AlgoriAgent.projects.algoriAgent.agent_manager import AgentManager - - -import configparser - -from db.user_list import UserList -from db.user import User, load_user_from_json, create_user_json -from db.course_list import CourseList -from db.course import Course, load_course_from_json -GLOBAL_CONFIG = configparser.ConfigParser() -GLOBAL_CONFIG.read('config.ini') -VSCODE_WEB_URL = GLOBAL_CONFIG['VSCODE_WEB']['url'] -USER_DATA_DIR = GLOBAL_CONFIG['USER_DATA']['dir'] -COURSE_DATA_DIR = GLOBAL_CONFIG['COURSE_DATA']['dir'] - -app = Flask(__name__) -socketio = SocketIO(app, cors_allowed_origins="*",ping_timeout=60, ping_interval=5) -# socketio = SocketIO(app, cors_allowed_origins="http://localhost:9888") # 设置跨域支持 -import logging -app.secret_key = 'cakebaker' -app.logger.setLevel(logging.DEBUG) -# 配置 CORS -CORS(app, resources={r"/*": {"origins": VSCODE_WEB_URL},}, supports_credentials=True) - - -userid_recorder = {} # user_id&path -> session['user_id'] - -''' -Backboard -''' -from backboardManager import BackBoardManager, Backboard - -backboard_manager = BackBoardManager() -uuid2username = {} -username2uuid = {} - - - -# 定义命名空间:用于和 VSCode 插件交流 -class VSCodeNamespace(Namespace): - def on_login(self,data): - print("VSCode client connected") - print(data) - dataconfig = data['config'] - user_id = dataconfig.get('user_id') - path = dataconfig.get('path') - course_id = dataconfig.get('course_id') - lesson_id = dataconfig.get('chapter_id') - print(f"User {user_id} connected with path: {path}") - useruuid = username2uuid[user_id] - join_room(useruuid, namespace='/vscode') - if backboard_manager.get_backboard(useruuid) == None: - backboard_manager.add_backboard(useruuid,user_id, course_id, lesson_id, path) - - - def on_message(self, data): - print(f"Received from VSCode client: {data}") - dataconfig = data['config'] - realtime_response(dataconfig, data) - # emit('response', {'message': 'Config data received and connection established'}) - def on_disconnect(self, data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - -def realtime_response(config, realtime_action): - user_id = config['user_id'] - folder_path = config['path'] - useruuid = username2uuid[user_id] - bb = backboard_manager.get_backboard(useruuid) - assert type(bb) == Backboard - - bb.add_history(realtime_action) - - if realtime_action['type'] == 'workspaceFolders': - bb.file_tree = realtime_action['fileTree'] - - if realtime_action['type'] == 'activeFile': - file_path = realtime_action['filePath'] - assert type(file_path) == str - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - if realtime_action['type'] == 'paste': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.pasted_file_path = file_path - bb.pasted_content = realtime_action['content'] - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - if realtime_action['type'] == 'fileEdit': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - - - print("config"+str(config)) - print("realtime_action"+str(realtime_action)) - pass - - -''' -Agent and Chat -''' -agent_manager = AgentManager(app = app, socketio = socketio) -user_threads = {} -import threading -from concurrent.futures import ThreadPoolExecutor, as_completed - -# 初始化线程池 -executor = ThreadPoolExecutor(max_workers=10) -class AgentNamespace(Namespace): - def on_login(self, data): - data = json.loads(data) - user = data['username'] - course_id = data['course_id'] - chapter_id = data['chapter_id'] - user_uuid = username2uuid[user] - session['user_id'] = user_uuid - print(f'User connected with session user_id: {user_uuid}') - # 从markdown、markdown_prompts、score_prompts中各读取数据folder.md并进行new_agent - with open(f'books/markdown/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fmd,\ - open(f'books/markdown_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8')as fmdp,\ - open(f'books/score_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fsp: - markdown = fmd.read() - markdown_prompts = fmdp.read() - score_prompts = fsp.read() - user_uuid, agent = agent_manager.new_agent(course_id, chapter_id, markdown, markdown_prompts, score_prompts, id=user_uuid, - root_path=f'../../study/{user}/{course_id}/{chapter_id}') - print(user_uuid) - join_room(user_uuid, namespace='/agent') # 将该用户加入以user_id为名的room - backboard_manager.add_backboard(user_uuid, user, course_id, chapter_id, root_path=f'../../study/{user}/{course_id}/{chapter_id}') - - def on_language(self, language): - id = session.get('user_id') - agent_manager.change_language(id, language) - - def on_message(self, data): - print(f"Message from client: {data}") - id = session.get('user_id') - if (type(data)==str): - data = json.loads(data) - print(id) - if data['type'] == 'text': - res = agent_manager.invoke(id, data['data'], backboard_manager.get_backboard(id).get_info_prompt()) - print('=*='*20) - print(res.content) - reply = f"{res.content['speak']}" - with app.app_context(): - emit('message',reply, room=id, namespace='/agent') - emit('request_function',res.content['function'], room=id, namespace='/agent') - - if data['type'] == 'function': - agent_manager.function_call(id, data['data']) - - def on_initiative(self,data): - print("User active function call") - user_id = session['user_id'] - if data['name'] == 'sample_judge': - agent_manager.sample_judge(user_id, backboard_manager.get_backboard(user_id)) - if data['name'] == 'judge': - agent_manager.judge(user_id, backboard_manager.get_backboard(user_id)) - - - - def on_disconnect(self,data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - - -''' -Markdown to HTML -''' -# 配置文件路径 -MARKDOWN_DIR = 'books/markdown' # 存放 markdown 文件的文件夹 -STATIC_DIR = 'static' # 存放生成的 HTML 和图片资源的文件夹 -IMAGE_DIR = 'image' # 图片资源相对于 markdown 的位置 - - - -@app.route('/--markdown', methods=['GET']) -def convert_md(course_id, filename): - md_file_path = os.path.join(MARKDOWN_DIR,course_id, f'{filename}.md') - - if not os.path.exists(md_file_path): - return jsonify({'error': 'Markdown file not found'}), 404 - - # 读取 markdown 文件内容 - with open(md_file_path, 'r', encoding='utf-8') as file: - md_content = file.read() - - # 将 markdown 转换为 HTML - html_content = markdown.markdown(md_content) - # 插入 CSS 样式,限制图片最大宽度为 100%,高度自动调整 - html_with_styles = f""" - - - - - - - {html_content} - - - """ - # 保存 HTML 文件到 static 文件夹 - html_output_path = os.path.join(STATIC_DIR, f'{filename}.html') - with open(html_output_path, 'w', encoding='utf-8') as html_file: - html_file.write(html_with_styles) - - # 处理图片资源,将 image/xxx 文件夹拷贝到 static/image/xxx - image_source_dir = os.path.join(MARKDOWN_DIR,course_id, IMAGE_DIR, filename) - image_target_dir = os.path.join(STATIC_DIR, IMAGE_DIR, filename) - print(f"Copying image resources from {image_source_dir} to {image_target_dir}") - if os.path.exists(image_source_dir): - # 确保 static/image/xxx 目录存在 - if not os.path.exists(image_target_dir): - os.makedirs(image_target_dir) - - # 拷贝图片资源 - for image_file in os.listdir(image_source_dir): - full_image_file_path = os.path.join(image_source_dir, image_file) - if os.path.isfile(full_image_file_path): - shutil.copy(full_image_file_path, image_target_dir) - - return jsonify({'html_url': f'/static/{filename}.html'}) - -# 静态文件(HTML 和图片资源)的访问 -@app.route('/static/') -def serve_static(filename): - return send_from_directory(STATIC_DIR, filename) - - -''' -Vscode -''' -@app.route('/desktop///') -def desktop(user_id, course_id, chapter_id): - if 'user_id' not in session: - # return redirect(url_for('login')) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ user_id + "uuid is"+ session['user_id']) - username2uuid[user_id] = session['user_id'] - uuid2username[session['user_id']] = user_id - userid_recorder[user_id+'&'+course_id] = session['user_id'] - - # 在学习目录下创建一个名为 user_id_path 的文件夹 - path_dir = os.path.join(student_workspace_root_path, user_id, course_id,chapter_id) - os.makedirs(path_dir, exist_ok=True) - # 在此文件夹内部创建一个.config文件,并写入 user_id=user_id\n path=path - config_path = os.path.join(path_dir, '.config') - if GLOBAL_CONFIG['VSCODE_WEB_PATH']['is_wsl']: # 如果是在 WSL 中运行,则将路径转换为 WSL 路径 - path_dir = path_dir.replace('\\', '/') - path_dir = path_dir.replace(GLOBAL_CONFIG['VSCODE_WEB_PATH']['windows_path'] , GLOBAL_CONFIG['VSCODE_WEB_PATH']['wsl_path']) - with open(config_path, 'w', encoding='utf-8') as f: - tmpd = {'user_id': user_id, 'course_id': course_id, 'chapter_id': chapter_id, 'path': path_dir} - json.dump(tmpd, f) - print('---------------------') - print(config_path) - return render_template('desktop.html', vscode_web_url=VSCODE_WEB_URL, user_id=user_id, course_id=course_id, chapter_id=chapter_id, workspace_path=path_dir) - -@app.route('/desktop_nouser//') -def desktop_nouser(course_id, chapter_id): - if 'user_id' not in session: - return redirect(url_for('login')) - user_id = session['user_id'] - username = uuid2username[user_id] - return redirect(url_for('desktop', user_id=username, course_id=course_id, chapter_id=chapter_id)) - -@app.route('/vscode_data', methods=['POST']) -def vscode_data(): - data = request.json - config = data['config'] - realtime_response(config,data) - print(f"Received data from VSCode: {data}") - return jsonify({"status": "success", "received": data}) - - - -''' -Login - -''' -users_list = UserList() -course_list = CourseList() - - -@app.route('/register') -def register(): - return render_template('register.html') - -@app.route('/register_teacher') -def register_teacher(): - return render_template('register_teacher.html') - -@app.route('/register_teacher_post', methods=['POST']) -def register_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password, teacher=True) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - -@app.route('/register_post', methods=['POST']) -def register_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - - -@app.route('/login') -def login(): - return render_template('login.html') - if 'user_id' not in session: - return render_template('login.html') - else: - return redirect(url_for('/')) - -@app.route('/login_post', methods=['POST']) -def login_post(): - # 获取请求的 JSON 数据 - data = request.get_json() - - username = data.get('username') - password = data.get('password') - - pswd = users_list.get_user_pswd(username) - - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/login_teacher_post', methods=['POST']) -def login_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - pswd = users_list.get_user_pswd(username) - is_teacher = users_list.get_user_is_teacher(username) - if is_teacher is None or is_teacher == False: - return jsonify({'success': False, 'message': '用户名不存在或非教师账号'}) - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/teacherboard') -@require_role(roles="teacher") -def teacherboard(): - return render_template('teacherboard.html') - - -@app.route('/logout') -def logout(): - session.pop('user_id', None) - return redirect(url_for('login')) - -@app.route('/get_session') -def get_session(): - user_session = session.get('user_id', 'default_session') - return jsonify({"session": user_session}) - - -''' -DashBoard -''' -user_id2UserClass = {} -@app.route('/dashboard') -@require_role -def dashboard(): - user_id = session['user_id'] - username = uuid2username[user_id] - if (user_id not in user_id2UserClass): - user_id2UserClass[user_id] = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - user_course_data = [] - for course_id in user_id2UserClass[user_id].select_course: - course_brief_info = course_list.get_course_brief_info(course_id, load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR)) - user_course_data.append(course_brief_info) - return render_template('dashboard.html',user_data = user_id2UserClass[user_id].to_json_without_dialog(), user_course_data = json.dumps(user_course_data)) - -''' -Course -''' - -@app.route('/course/') -@require_role -def course(course_id): - c = load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR) - return render_template('course.html', course_id=course_id, course_data=c) - -@app.route('/select_course', methods=['POST']) -@require_role -def select_course(): - user = user_id2UserClass[session['user_id']] - data = request.get_json() - course_id = data.get('course_id') - if course_id: - user.select_new_course(course_id, load_course_from_json(course_id, COURSE_DATA_DIR)) - return jsonify({'success': True, 'message': '课程选择成功'}) - - -@app.route('/') -@require_role -def home_index(): - selected_courses=[] - if ('user_id' in session): - if (session['user_id'] not in user_id2UserClass): return redirect(url_for('login')) - user = user_id2UserClass[session['user_id']] - for course_id in user.select_course: - selected_courses.append(course_id) - - return render_template('index.html', courses_data = course_list, selected_courses =selected_courses) - -# 一些app辅助函数,主要提供给Agent与数据库的交互能力 - -class MyFunction: - def save_chapter_memory(self, id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal): - print("-=-=-=-=-=-=-=-") - print(id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - username = uuid2username[id] - u = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - u.save_chapter_memory(course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - -app.my_function = MyFunction() -if __name__ == '__main__': - socketio.on_namespace(VSCodeNamespace('/vscode')) - socketio.on_namespace(AgentNamespace('/agent')) - socketio.run(app, host='0.0.0.0', port=5551, debug=False,allow_unsafe_werkzeug=True) - diff --git a/Html/runs/run_20250911-092331_bvossb/code/backboardManager.py b/Html/runs/run_20250911-092331_bvossb/code/backboardManager.py deleted file mode 100644 index 7de5f19..0000000 --- a/Html/runs/run_20250911-092331_bvossb/code/backboardManager.py +++ /dev/null @@ -1,80 +0,0 @@ - - - -import time -import os - -class Backboard: - def __init__(self, user_uuid, username, course_id, lesson_id, root_path): - self.user_uuid = user_uuid - self.username = username - self.course_id = course_id - self.lesson_id = lesson_id - self.root_path = root_path - self.create_time = time.time() - self.enter_chapter_time = time.time() - self.history = [] - self.file_tree = "[]" - self.active_file_path = "" - self.active_file_content = "" - self.pasted_file_path = "" - self.pasted_content = "" - - - def next_chapter(self): - self.enter_chapter_time = time.time() - - def get_info_prompt(self): - - five_history = "" - for h in self.history[-5:]: - five_history += h['type'] + "\n" + h.get('filePath', '') + "\n\n" - - endl = "\n" - return (f"###Global Info:###{endl}" - f"Here are some info about now user's IDE, refer to it when you need to handle some code.{endl}" - f"- User's total study time is {self.get_deltatime_mmss(self.create_time, time.time())}{endl}" - f"- User's current chapter study time is {self.get_deltatime_mmss(self.enter_chapter_time, time.time())}{endl}" - f"- Activated file path: {self.active_file_path}{endl}" - f"```{endl}" - f"{self.active_file_content[-10:]}{endl}" - f"```{endl}" - f"- Last five action:{five_history}{endl}" - f"- File tree: {self.file_tree}{endl}") - # f"- Activated file content (current editing 10 lines): {endl}" - def add_history(self, realtime_action): - if(realtime_action['type']=='config'):return - if len(self.history)!=0: - if (self.history[-1]['type']=='fileEdit'): - if(self.history[-1]['filePath'] == realtime_action['filePath']): - self.history[-1]['content'] = realtime_action['content'] - return - self.history.append(realtime_action) - - - def get_deltatime_mmss(self, start_time, end_time): - elapsed_time = end_time - start_time - hours = int(elapsed_time // 3600) - minutes = int((elapsed_time % 3600) // 60) - seconds = int(elapsed_time % 60) - return f"{hours:02d}:{minutes:02d}:{seconds:02d}" - - - def get_active_file_reletive_path(self): - relative_path = os.path.relpath(self.active_file_path, self.root_path) - return relative_path - - - -class BackBoardManager: - def __init__(self): - self.backboards = {} # user_uuid: Backboard - - def add_backboard(self, user_uuid, username, course_id, lesson_id, root_path): - self.backboards[user_uuid] = Backboard(user_uuid,username, course_id, lesson_id, root_path) - - def get_backboard(self, user_uuid) -> Backboard: - return self.backboards[user_uuid] - - - diff --git a/Html/runs/run_20250911-092331_bvossb/code/bootstrap.py b/Html/runs/run_20250911-092331_bvossb/code/bootstrap.py deleted file mode 100644 index bcb15ce..0000000 --- a/Html/runs/run_20250911-092331_bvossb/code/bootstrap.py +++ /dev/null @@ -1,31 +0,0 @@ -from pathlib import Path -import sys, os - -def bootstrap_paths(): - """ - 让 'AlgoriAgent'(位于 repo_root/AlgoriAgent)可被 import; - 并提供 STUDENT_WORKSPACE_ROOT 的默认值(repo_root/study)。 - 适配当前工厂位置:repo_root/Html/apps/__init__.py - """ - here = Path(__file__).resolve() - # repo_root = .../Html/apps/../../ => parents[2] - repo_root = here.parents[2] - - # 兜底:如果目录结构变化,尝试向上搜索包含 AlgoriAgent 的目录作为 repo_root - if not (repo_root / "AlgoriAgent").exists(): - for p in here.parents: - if (p / "AlgoriAgent").is_dir(): - repo_root = p - break - - # 确保仓库根在 sys.path(这样 'AlgoriAgent' 顶层包可被发现) - repo_root_str = str(repo_root) - if repo_root_str not in sys.path: - sys.path.insert(0, repo_root_str) - - # 可选:如果你还有其它顶层包,也可在此处继续插入 - - # 默认学习工作区目录(也可放到 config.ini / 环境变量覆盖) - os.environ.setdefault("STUDENT_WORKSPACE_ROOT", str(repo_root / "study")) - - return repo_root # 方便调试/日志 \ No newline at end of file diff --git a/Html/runs/run_20250911-092331_bvossb/code/wsgi.py b/Html/runs/run_20250911-092331_bvossb/code/wsgi.py deleted file mode 100644 index bbcbe5f..0000000 --- a/Html/runs/run_20250911-092331_bvossb/code/wsgi.py +++ /dev/null @@ -1,6 +0,0 @@ -# wsgi.py -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -# 提供一个可被 WSGI/进程管理器导入的 app 对象 -app = create_app() diff --git a/Html/runs/run_20250911-092331_bvossb/logging.chat b/Html/runs/run_20250911-092331_bvossb/logging.chat deleted file mode 100644 index e69de29..0000000 diff --git a/Html/runs/run_20250911-092331_bvossb/logging.log b/Html/runs/run_20250911-092331_bvossb/logging.log deleted file mode 100644 index 828c649..0000000 --- a/Html/runs/run_20250911-092331_bvossb/logging.log +++ /dev/null @@ -1 +0,0 @@ -2025-09-11 09:23:35.694 | INFO | agentscope.models:read_model_configs:186 - Load configs for model wrapper: openai_cfg diff --git a/Html/runs/run_20250911-092722_nuvx5a/.config b/Html/runs/run_20250911-092722_nuvx5a/.config deleted file mode 100644 index 3fbd145..0000000 --- a/Html/runs/run_20250911-092722_nuvx5a/.config +++ /dev/null @@ -1,7 +0,0 @@ -{ - "project": "pS0LF8", - "name": "nuvx5a", - "run_id": "run_20250911-092722_nuvx5a", - "timestamp": "2025-09-11 09:27:22", - "pid": 15302 -} \ No newline at end of file diff --git a/Html/runs/run_20250911-092722_nuvx5a/agentscope.db b/Html/runs/run_20250911-092722_nuvx5a/agentscope.db deleted file mode 100644 index 666055b77679cda29c14fcf23b4ef1d039c5b52a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI%L2KJE6bEoS4Q(k)+glI2yjv3-0%NB!Hs&O1YUav`W0U1F<0V=#BsNLx(sSu$ z>=W&q?4#^B$!*yt2YT5l`~^0a^z(#~{ zkyg6w!t)u0!@f%5aeaJcfD9*Q_b$ozCY8>~CFA6|{Z2V!N;Z^cIq}eS$>x3HY|^=j z7lokrf1)Z$x@_R^N~@apn7OPMkZ(I<*1WJCw@v3GWy2n6&RcIQ0~zlR_x8^$%be!% zmxb7@7V;}H+K5#l(wSbZKXKY!mys6ROyi|!%aN@+%REpi?;B-K4PC3&{>iCzQnNB+ zwbW!z4iA{x(V_2L+5VJ1vMJeN;5l68yJ9?OZyl-TNCEp4P{^H8$cTGExdq$9ANE6@ zA@`ZUhb>is+Y=S?%$C1fnN{muZU1a!nMRV%#qFbMT;y3hf|KlJ)00Izz00bZa0SG_<0uX=z1a@EGHy1PL*Z=?k diff --git a/Html/runs/run_20250911-092722_nuvx5a/code/app.py b/Html/runs/run_20250911-092722_nuvx5a/code/app.py deleted file mode 100644 index c7f31f7..0000000 --- a/Html/runs/run_20250911-092722_nuvx5a/code/app.py +++ /dev/null @@ -1,21 +0,0 @@ -# app.py 0.1.1 rise to factory mode -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -from apps.extensions import socketio - -# 工厂创建 app,工厂里已经做了:加载配置/注册蓝图/注册 namespaces -app = create_app() - -if __name__ == "__main__": - # 仅本地开发用;生产不要用 werkzeug 自带的开发服务器 - socketio.run( - app, - host="0.0.0.0", - port=5551, - debug=True, # 开发期打开 - allow_unsafe_werkzeug=True, # 避免 dev server 的安全限制提示 - # ssl_context=('server.crt', 'server.key') - ) - - diff --git a/Html/runs/run_20250911-092722_nuvx5a/code/app_back.py b/Html/runs/run_20250911-092722_nuvx5a/code/app_back.py deleted file mode 100644 index 246853c..0000000 --- a/Html/runs/run_20250911-092722_nuvx5a/code/app_back.py +++ /dev/null @@ -1,480 +0,0 @@ -from bootstrap import bootstrap_paths -bootstrap_paths() -from functools import wraps -from flask import Flask, redirect, session, request, jsonify, render_template, send_from_directory, url_for -from flask_cors import CORS -from flask_socketio import SocketIO, join_room, emit, Namespace -import markdown -import os -import uuid -import shutil -import sys -import json -from apps.auth.decorators import require_role -parent_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) -sys.path.insert(0, parent_dir) -student_workspace_root_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../study')) -current_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '.')) -sys.path.insert(0, current_dir) -from AlgoriAgent.projects.algoriAgent.agent_manager import AgentManager - - -import configparser - -from db.user_list import UserList -from db.user import User, load_user_from_json, create_user_json -from db.course_list import CourseList -from db.course import Course, load_course_from_json -GLOBAL_CONFIG = configparser.ConfigParser() -GLOBAL_CONFIG.read('config.ini') -VSCODE_WEB_URL = GLOBAL_CONFIG['VSCODE_WEB']['url'] -USER_DATA_DIR = GLOBAL_CONFIG['USER_DATA']['dir'] -COURSE_DATA_DIR = GLOBAL_CONFIG['COURSE_DATA']['dir'] - -app = Flask(__name__) -socketio = SocketIO(app, cors_allowed_origins="*",ping_timeout=60, ping_interval=5) -# socketio = SocketIO(app, cors_allowed_origins="http://localhost:9888") # 设置跨域支持 -import logging -app.secret_key = 'cakebaker' -app.logger.setLevel(logging.DEBUG) -# 配置 CORS -CORS(app, resources={r"/*": {"origins": VSCODE_WEB_URL},}, supports_credentials=True) - - -userid_recorder = {} # user_id&path -> session['user_id'] - -''' -Backboard -''' -from backboardManager import BackBoardManager, Backboard - -backboard_manager = BackBoardManager() -uuid2username = {} -username2uuid = {} - - - -# 定义命名空间:用于和 VSCode 插件交流 -class VSCodeNamespace(Namespace): - def on_login(self,data): - print("VSCode client connected") - print(data) - dataconfig = data['config'] - user_id = dataconfig.get('user_id') - path = dataconfig.get('path') - course_id = dataconfig.get('course_id') - lesson_id = dataconfig.get('chapter_id') - print(f"User {user_id} connected with path: {path}") - useruuid = username2uuid[user_id] - join_room(useruuid, namespace='/vscode') - if backboard_manager.get_backboard(useruuid) == None: - backboard_manager.add_backboard(useruuid,user_id, course_id, lesson_id, path) - - - def on_message(self, data): - print(f"Received from VSCode client: {data}") - dataconfig = data['config'] - realtime_response(dataconfig, data) - # emit('response', {'message': 'Config data received and connection established'}) - def on_disconnect(self, data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - -def realtime_response(config, realtime_action): - user_id = config['user_id'] - folder_path = config['path'] - useruuid = username2uuid[user_id] - bb = backboard_manager.get_backboard(useruuid) - assert type(bb) == Backboard - - bb.add_history(realtime_action) - - if realtime_action['type'] == 'workspaceFolders': - bb.file_tree = realtime_action['fileTree'] - - if realtime_action['type'] == 'activeFile': - file_path = realtime_action['filePath'] - assert type(file_path) == str - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - if realtime_action['type'] == 'paste': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.pasted_file_path = file_path - bb.pasted_content = realtime_action['content'] - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - if realtime_action['type'] == 'fileEdit': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - - - print("config"+str(config)) - print("realtime_action"+str(realtime_action)) - pass - - -''' -Agent and Chat -''' -agent_manager = AgentManager(app = app, socketio = socketio) -user_threads = {} -import threading -from concurrent.futures import ThreadPoolExecutor, as_completed - -# 初始化线程池 -executor = ThreadPoolExecutor(max_workers=10) -class AgentNamespace(Namespace): - def on_login(self, data): - data = json.loads(data) - user = data['username'] - course_id = data['course_id'] - chapter_id = data['chapter_id'] - user_uuid = username2uuid[user] - session['user_id'] = user_uuid - print(f'User connected with session user_id: {user_uuid}') - # 从markdown、markdown_prompts、score_prompts中各读取数据folder.md并进行new_agent - with open(f'books/markdown/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fmd,\ - open(f'books/markdown_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8')as fmdp,\ - open(f'books/score_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fsp: - markdown = fmd.read() - markdown_prompts = fmdp.read() - score_prompts = fsp.read() - user_uuid, agent = agent_manager.new_agent(course_id, chapter_id, markdown, markdown_prompts, score_prompts, id=user_uuid, - root_path=f'../../study/{user}/{course_id}/{chapter_id}') - print(user_uuid) - join_room(user_uuid, namespace='/agent') # 将该用户加入以user_id为名的room - backboard_manager.add_backboard(user_uuid, user, course_id, chapter_id, root_path=f'../../study/{user}/{course_id}/{chapter_id}') - - def on_language(self, language): - id = session.get('user_id') - agent_manager.change_language(id, language) - - def on_message(self, data): - print(f"Message from client: {data}") - id = session.get('user_id') - if (type(data)==str): - data = json.loads(data) - print(id) - if data['type'] == 'text': - res = agent_manager.invoke(id, data['data'], backboard_manager.get_backboard(id).get_info_prompt()) - print('=*='*20) - print(res.content) - reply = f"{res.content['speak']}" - with app.app_context(): - emit('message',reply, room=id, namespace='/agent') - emit('request_function',res.content['function'], room=id, namespace='/agent') - - if data['type'] == 'function': - agent_manager.function_call(id, data['data']) - - def on_initiative(self,data): - print("User active function call") - user_id = session['user_id'] - if data['name'] == 'sample_judge': - agent_manager.sample_judge(user_id, backboard_manager.get_backboard(user_id)) - if data['name'] == 'judge': - agent_manager.judge(user_id, backboard_manager.get_backboard(user_id)) - - - - def on_disconnect(self,data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - - -''' -Markdown to HTML -''' -# 配置文件路径 -MARKDOWN_DIR = 'books/markdown' # 存放 markdown 文件的文件夹 -STATIC_DIR = 'static' # 存放生成的 HTML 和图片资源的文件夹 -IMAGE_DIR = 'image' # 图片资源相对于 markdown 的位置 - - - -@app.route('/--markdown', methods=['GET']) -def convert_md(course_id, filename): - md_file_path = os.path.join(MARKDOWN_DIR,course_id, f'{filename}.md') - - if not os.path.exists(md_file_path): - return jsonify({'error': 'Markdown file not found'}), 404 - - # 读取 markdown 文件内容 - with open(md_file_path, 'r', encoding='utf-8') as file: - md_content = file.read() - - # 将 markdown 转换为 HTML - html_content = markdown.markdown(md_content) - # 插入 CSS 样式,限制图片最大宽度为 100%,高度自动调整 - html_with_styles = f""" - - - - - - - {html_content} - - - """ - # 保存 HTML 文件到 static 文件夹 - html_output_path = os.path.join(STATIC_DIR, f'{filename}.html') - with open(html_output_path, 'w', encoding='utf-8') as html_file: - html_file.write(html_with_styles) - - # 处理图片资源,将 image/xxx 文件夹拷贝到 static/image/xxx - image_source_dir = os.path.join(MARKDOWN_DIR,course_id, IMAGE_DIR, filename) - image_target_dir = os.path.join(STATIC_DIR, IMAGE_DIR, filename) - print(f"Copying image resources from {image_source_dir} to {image_target_dir}") - if os.path.exists(image_source_dir): - # 确保 static/image/xxx 目录存在 - if not os.path.exists(image_target_dir): - os.makedirs(image_target_dir) - - # 拷贝图片资源 - for image_file in os.listdir(image_source_dir): - full_image_file_path = os.path.join(image_source_dir, image_file) - if os.path.isfile(full_image_file_path): - shutil.copy(full_image_file_path, image_target_dir) - - return jsonify({'html_url': f'/static/{filename}.html'}) - -# 静态文件(HTML 和图片资源)的访问 -@app.route('/static/') -def serve_static(filename): - return send_from_directory(STATIC_DIR, filename) - - -''' -Vscode -''' -@app.route('/desktop///') -def desktop(user_id, course_id, chapter_id): - if 'user_id' not in session: - # return redirect(url_for('login')) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ user_id + "uuid is"+ session['user_id']) - username2uuid[user_id] = session['user_id'] - uuid2username[session['user_id']] = user_id - userid_recorder[user_id+'&'+course_id] = session['user_id'] - - # 在学习目录下创建一个名为 user_id_path 的文件夹 - path_dir = os.path.join(student_workspace_root_path, user_id, course_id,chapter_id) - os.makedirs(path_dir, exist_ok=True) - # 在此文件夹内部创建一个.config文件,并写入 user_id=user_id\n path=path - config_path = os.path.join(path_dir, '.config') - if GLOBAL_CONFIG['VSCODE_WEB_PATH']['is_wsl']: # 如果是在 WSL 中运行,则将路径转换为 WSL 路径 - path_dir = path_dir.replace('\\', '/') - path_dir = path_dir.replace(GLOBAL_CONFIG['VSCODE_WEB_PATH']['windows_path'] , GLOBAL_CONFIG['VSCODE_WEB_PATH']['wsl_path']) - with open(config_path, 'w', encoding='utf-8') as f: - tmpd = {'user_id': user_id, 'course_id': course_id, 'chapter_id': chapter_id, 'path': path_dir} - json.dump(tmpd, f) - print('---------------------') - print(config_path) - return render_template('desktop.html', vscode_web_url=VSCODE_WEB_URL, user_id=user_id, course_id=course_id, chapter_id=chapter_id, workspace_path=path_dir) - -@app.route('/desktop_nouser//') -def desktop_nouser(course_id, chapter_id): - if 'user_id' not in session: - return redirect(url_for('login')) - user_id = session['user_id'] - username = uuid2username[user_id] - return redirect(url_for('desktop', user_id=username, course_id=course_id, chapter_id=chapter_id)) - -@app.route('/vscode_data', methods=['POST']) -def vscode_data(): - data = request.json - config = data['config'] - realtime_response(config,data) - print(f"Received data from VSCode: {data}") - return jsonify({"status": "success", "received": data}) - - - -''' -Login - -''' -users_list = UserList() -course_list = CourseList() - - -@app.route('/register') -def register(): - return render_template('register.html') - -@app.route('/register_teacher') -def register_teacher(): - return render_template('register_teacher.html') - -@app.route('/register_teacher_post', methods=['POST']) -def register_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password, teacher=True) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - -@app.route('/register_post', methods=['POST']) -def register_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - - -@app.route('/login') -def login(): - return render_template('login.html') - if 'user_id' not in session: - return render_template('login.html') - else: - return redirect(url_for('/')) - -@app.route('/login_post', methods=['POST']) -def login_post(): - # 获取请求的 JSON 数据 - data = request.get_json() - - username = data.get('username') - password = data.get('password') - - pswd = users_list.get_user_pswd(username) - - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/login_teacher_post', methods=['POST']) -def login_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - pswd = users_list.get_user_pswd(username) - is_teacher = users_list.get_user_is_teacher(username) - if is_teacher is None or is_teacher == False: - return jsonify({'success': False, 'message': '用户名不存在或非教师账号'}) - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/teacherboard') -@require_role(roles="teacher") -def teacherboard(): - return render_template('teacherboard.html') - - -@app.route('/logout') -def logout(): - session.pop('user_id', None) - return redirect(url_for('login')) - -@app.route('/get_session') -def get_session(): - user_session = session.get('user_id', 'default_session') - return jsonify({"session": user_session}) - - -''' -DashBoard -''' -user_id2UserClass = {} -@app.route('/dashboard') -@require_role -def dashboard(): - user_id = session['user_id'] - username = uuid2username[user_id] - if (user_id not in user_id2UserClass): - user_id2UserClass[user_id] = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - user_course_data = [] - for course_id in user_id2UserClass[user_id].select_course: - course_brief_info = course_list.get_course_brief_info(course_id, load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR)) - user_course_data.append(course_brief_info) - return render_template('dashboard.html',user_data = user_id2UserClass[user_id].to_json_without_dialog(), user_course_data = json.dumps(user_course_data)) - -''' -Course -''' - -@app.route('/course/') -@require_role -def course(course_id): - c = load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR) - return render_template('course.html', course_id=course_id, course_data=c) - -@app.route('/select_course', methods=['POST']) -@require_role -def select_course(): - user = user_id2UserClass[session['user_id']] - data = request.get_json() - course_id = data.get('course_id') - if course_id: - user.select_new_course(course_id, load_course_from_json(course_id, COURSE_DATA_DIR)) - return jsonify({'success': True, 'message': '课程选择成功'}) - - -@app.route('/') -@require_role -def home_index(): - selected_courses=[] - if ('user_id' in session): - if (session['user_id'] not in user_id2UserClass): return redirect(url_for('login')) - user = user_id2UserClass[session['user_id']] - for course_id in user.select_course: - selected_courses.append(course_id) - - return render_template('index.html', courses_data = course_list, selected_courses =selected_courses) - -# 一些app辅助函数,主要提供给Agent与数据库的交互能力 - -class MyFunction: - def save_chapter_memory(self, id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal): - print("-=-=-=-=-=-=-=-") - print(id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - username = uuid2username[id] - u = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - u.save_chapter_memory(course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - -app.my_function = MyFunction() -if __name__ == '__main__': - socketio.on_namespace(VSCodeNamespace('/vscode')) - socketio.on_namespace(AgentNamespace('/agent')) - socketio.run(app, host='0.0.0.0', port=5551, debug=False,allow_unsafe_werkzeug=True) - diff --git a/Html/runs/run_20250911-092722_nuvx5a/code/backboardManager.py b/Html/runs/run_20250911-092722_nuvx5a/code/backboardManager.py deleted file mode 100644 index 7de5f19..0000000 --- a/Html/runs/run_20250911-092722_nuvx5a/code/backboardManager.py +++ /dev/null @@ -1,80 +0,0 @@ - - - -import time -import os - -class Backboard: - def __init__(self, user_uuid, username, course_id, lesson_id, root_path): - self.user_uuid = user_uuid - self.username = username - self.course_id = course_id - self.lesson_id = lesson_id - self.root_path = root_path - self.create_time = time.time() - self.enter_chapter_time = time.time() - self.history = [] - self.file_tree = "[]" - self.active_file_path = "" - self.active_file_content = "" - self.pasted_file_path = "" - self.pasted_content = "" - - - def next_chapter(self): - self.enter_chapter_time = time.time() - - def get_info_prompt(self): - - five_history = "" - for h in self.history[-5:]: - five_history += h['type'] + "\n" + h.get('filePath', '') + "\n\n" - - endl = "\n" - return (f"###Global Info:###{endl}" - f"Here are some info about now user's IDE, refer to it when you need to handle some code.{endl}" - f"- User's total study time is {self.get_deltatime_mmss(self.create_time, time.time())}{endl}" - f"- User's current chapter study time is {self.get_deltatime_mmss(self.enter_chapter_time, time.time())}{endl}" - f"- Activated file path: {self.active_file_path}{endl}" - f"```{endl}" - f"{self.active_file_content[-10:]}{endl}" - f"```{endl}" - f"- Last five action:{five_history}{endl}" - f"- File tree: {self.file_tree}{endl}") - # f"- Activated file content (current editing 10 lines): {endl}" - def add_history(self, realtime_action): - if(realtime_action['type']=='config'):return - if len(self.history)!=0: - if (self.history[-1]['type']=='fileEdit'): - if(self.history[-1]['filePath'] == realtime_action['filePath']): - self.history[-1]['content'] = realtime_action['content'] - return - self.history.append(realtime_action) - - - def get_deltatime_mmss(self, start_time, end_time): - elapsed_time = end_time - start_time - hours = int(elapsed_time // 3600) - minutes = int((elapsed_time % 3600) // 60) - seconds = int(elapsed_time % 60) - return f"{hours:02d}:{minutes:02d}:{seconds:02d}" - - - def get_active_file_reletive_path(self): - relative_path = os.path.relpath(self.active_file_path, self.root_path) - return relative_path - - - -class BackBoardManager: - def __init__(self): - self.backboards = {} # user_uuid: Backboard - - def add_backboard(self, user_uuid, username, course_id, lesson_id, root_path): - self.backboards[user_uuid] = Backboard(user_uuid,username, course_id, lesson_id, root_path) - - def get_backboard(self, user_uuid) -> Backboard: - return self.backboards[user_uuid] - - - diff --git a/Html/runs/run_20250911-092722_nuvx5a/code/bootstrap.py b/Html/runs/run_20250911-092722_nuvx5a/code/bootstrap.py deleted file mode 100644 index bcb15ce..0000000 --- a/Html/runs/run_20250911-092722_nuvx5a/code/bootstrap.py +++ /dev/null @@ -1,31 +0,0 @@ -from pathlib import Path -import sys, os - -def bootstrap_paths(): - """ - 让 'AlgoriAgent'(位于 repo_root/AlgoriAgent)可被 import; - 并提供 STUDENT_WORKSPACE_ROOT 的默认值(repo_root/study)。 - 适配当前工厂位置:repo_root/Html/apps/__init__.py - """ - here = Path(__file__).resolve() - # repo_root = .../Html/apps/../../ => parents[2] - repo_root = here.parents[2] - - # 兜底:如果目录结构变化,尝试向上搜索包含 AlgoriAgent 的目录作为 repo_root - if not (repo_root / "AlgoriAgent").exists(): - for p in here.parents: - if (p / "AlgoriAgent").is_dir(): - repo_root = p - break - - # 确保仓库根在 sys.path(这样 'AlgoriAgent' 顶层包可被发现) - repo_root_str = str(repo_root) - if repo_root_str not in sys.path: - sys.path.insert(0, repo_root_str) - - # 可选:如果你还有其它顶层包,也可在此处继续插入 - - # 默认学习工作区目录(也可放到 config.ini / 环境变量覆盖) - os.environ.setdefault("STUDENT_WORKSPACE_ROOT", str(repo_root / "study")) - - return repo_root # 方便调试/日志 \ No newline at end of file diff --git a/Html/runs/run_20250911-092722_nuvx5a/code/wsgi.py b/Html/runs/run_20250911-092722_nuvx5a/code/wsgi.py deleted file mode 100644 index bbcbe5f..0000000 --- a/Html/runs/run_20250911-092722_nuvx5a/code/wsgi.py +++ /dev/null @@ -1,6 +0,0 @@ -# wsgi.py -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -# 提供一个可被 WSGI/进程管理器导入的 app 对象 -app = create_app() diff --git a/Html/runs/run_20250911-092722_nuvx5a/logging.chat b/Html/runs/run_20250911-092722_nuvx5a/logging.chat deleted file mode 100644 index e69de29..0000000 diff --git a/Html/runs/run_20250911-092722_nuvx5a/logging.log b/Html/runs/run_20250911-092722_nuvx5a/logging.log deleted file mode 100644 index 7cd93e8..0000000 --- a/Html/runs/run_20250911-092722_nuvx5a/logging.log +++ /dev/null @@ -1 +0,0 @@ -2025-09-11 09:27:29.279 | INFO | agentscope.models:read_model_configs:186 - Load configs for model wrapper: openai_cfg diff --git a/Html/runs/run_20250911-092728_5rmbf4/.config b/Html/runs/run_20250911-092728_5rmbf4/.config deleted file mode 100644 index 6629312..0000000 --- a/Html/runs/run_20250911-092728_5rmbf4/.config +++ /dev/null @@ -1,7 +0,0 @@ -{ - "project": "x3IHfz", - "name": "5rmbf4", - "run_id": "run_20250911-092728_5rmbf4", - "timestamp": "2025-09-11 09:27:28", - "pid": 15333 -} \ No newline at end of file diff --git a/Html/runs/run_20250911-092728_5rmbf4/agentscope.db b/Html/runs/run_20250911-092728_5rmbf4/agentscope.db deleted file mode 100644 index 666055b77679cda29c14fcf23b4ef1d039c5b52a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI%L2KJE6bEoS4Q(k)+glI2yjv3-0%NB!Hs&O1YUav`W0U1F<0V=#BsNLx(sSu$ z>=W&q?4#^B$!*yt2YT5l`~^0a^z(#~{ zkyg6w!t)u0!@f%5aeaJcfD9*Q_b$ozCY8>~CFA6|{Z2V!N;Z^cIq}eS$>x3HY|^=j z7lokrf1)Z$x@_R^N~@apn7OPMkZ(I<*1WJCw@v3GWy2n6&RcIQ0~zlR_x8^$%be!% zmxb7@7V;}H+K5#l(wSbZKXKY!mys6ROyi|!%aN@+%REpi?;B-K4PC3&{>iCzQnNB+ zwbW!z4iA{x(V_2L+5VJ1vMJeN;5l68yJ9?OZyl-TNCEp4P{^H8$cTGExdq$9ANE6@ zA@`ZUhb>is+Y=S?%$C1fnN{muZU1a!nMRV%#qFbMT;y3hf|KlJ)00Izz00bZa0SG_<0uX=z1a@EGHy1PL*Z=?k diff --git a/Html/runs/run_20250911-092728_5rmbf4/code/app.py b/Html/runs/run_20250911-092728_5rmbf4/code/app.py deleted file mode 100644 index c7f31f7..0000000 --- a/Html/runs/run_20250911-092728_5rmbf4/code/app.py +++ /dev/null @@ -1,21 +0,0 @@ -# app.py 0.1.1 rise to factory mode -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -from apps.extensions import socketio - -# 工厂创建 app,工厂里已经做了:加载配置/注册蓝图/注册 namespaces -app = create_app() - -if __name__ == "__main__": - # 仅本地开发用;生产不要用 werkzeug 自带的开发服务器 - socketio.run( - app, - host="0.0.0.0", - port=5551, - debug=True, # 开发期打开 - allow_unsafe_werkzeug=True, # 避免 dev server 的安全限制提示 - # ssl_context=('server.crt', 'server.key') - ) - - diff --git a/Html/runs/run_20250911-092728_5rmbf4/code/app_back.py b/Html/runs/run_20250911-092728_5rmbf4/code/app_back.py deleted file mode 100644 index 246853c..0000000 --- a/Html/runs/run_20250911-092728_5rmbf4/code/app_back.py +++ /dev/null @@ -1,480 +0,0 @@ -from bootstrap import bootstrap_paths -bootstrap_paths() -from functools import wraps -from flask import Flask, redirect, session, request, jsonify, render_template, send_from_directory, url_for -from flask_cors import CORS -from flask_socketio import SocketIO, join_room, emit, Namespace -import markdown -import os -import uuid -import shutil -import sys -import json -from apps.auth.decorators import require_role -parent_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) -sys.path.insert(0, parent_dir) -student_workspace_root_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../study')) -current_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '.')) -sys.path.insert(0, current_dir) -from AlgoriAgent.projects.algoriAgent.agent_manager import AgentManager - - -import configparser - -from db.user_list import UserList -from db.user import User, load_user_from_json, create_user_json -from db.course_list import CourseList -from db.course import Course, load_course_from_json -GLOBAL_CONFIG = configparser.ConfigParser() -GLOBAL_CONFIG.read('config.ini') -VSCODE_WEB_URL = GLOBAL_CONFIG['VSCODE_WEB']['url'] -USER_DATA_DIR = GLOBAL_CONFIG['USER_DATA']['dir'] -COURSE_DATA_DIR = GLOBAL_CONFIG['COURSE_DATA']['dir'] - -app = Flask(__name__) -socketio = SocketIO(app, cors_allowed_origins="*",ping_timeout=60, ping_interval=5) -# socketio = SocketIO(app, cors_allowed_origins="http://localhost:9888") # 设置跨域支持 -import logging -app.secret_key = 'cakebaker' -app.logger.setLevel(logging.DEBUG) -# 配置 CORS -CORS(app, resources={r"/*": {"origins": VSCODE_WEB_URL},}, supports_credentials=True) - - -userid_recorder = {} # user_id&path -> session['user_id'] - -''' -Backboard -''' -from backboardManager import BackBoardManager, Backboard - -backboard_manager = BackBoardManager() -uuid2username = {} -username2uuid = {} - - - -# 定义命名空间:用于和 VSCode 插件交流 -class VSCodeNamespace(Namespace): - def on_login(self,data): - print("VSCode client connected") - print(data) - dataconfig = data['config'] - user_id = dataconfig.get('user_id') - path = dataconfig.get('path') - course_id = dataconfig.get('course_id') - lesson_id = dataconfig.get('chapter_id') - print(f"User {user_id} connected with path: {path}") - useruuid = username2uuid[user_id] - join_room(useruuid, namespace='/vscode') - if backboard_manager.get_backboard(useruuid) == None: - backboard_manager.add_backboard(useruuid,user_id, course_id, lesson_id, path) - - - def on_message(self, data): - print(f"Received from VSCode client: {data}") - dataconfig = data['config'] - realtime_response(dataconfig, data) - # emit('response', {'message': 'Config data received and connection established'}) - def on_disconnect(self, data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - -def realtime_response(config, realtime_action): - user_id = config['user_id'] - folder_path = config['path'] - useruuid = username2uuid[user_id] - bb = backboard_manager.get_backboard(useruuid) - assert type(bb) == Backboard - - bb.add_history(realtime_action) - - if realtime_action['type'] == 'workspaceFolders': - bb.file_tree = realtime_action['fileTree'] - - if realtime_action['type'] == 'activeFile': - file_path = realtime_action['filePath'] - assert type(file_path) == str - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - if realtime_action['type'] == 'paste': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.pasted_file_path = file_path - bb.pasted_content = realtime_action['content'] - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - if realtime_action['type'] == 'fileEdit': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - - - print("config"+str(config)) - print("realtime_action"+str(realtime_action)) - pass - - -''' -Agent and Chat -''' -agent_manager = AgentManager(app = app, socketio = socketio) -user_threads = {} -import threading -from concurrent.futures import ThreadPoolExecutor, as_completed - -# 初始化线程池 -executor = ThreadPoolExecutor(max_workers=10) -class AgentNamespace(Namespace): - def on_login(self, data): - data = json.loads(data) - user = data['username'] - course_id = data['course_id'] - chapter_id = data['chapter_id'] - user_uuid = username2uuid[user] - session['user_id'] = user_uuid - print(f'User connected with session user_id: {user_uuid}') - # 从markdown、markdown_prompts、score_prompts中各读取数据folder.md并进行new_agent - with open(f'books/markdown/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fmd,\ - open(f'books/markdown_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8')as fmdp,\ - open(f'books/score_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fsp: - markdown = fmd.read() - markdown_prompts = fmdp.read() - score_prompts = fsp.read() - user_uuid, agent = agent_manager.new_agent(course_id, chapter_id, markdown, markdown_prompts, score_prompts, id=user_uuid, - root_path=f'../../study/{user}/{course_id}/{chapter_id}') - print(user_uuid) - join_room(user_uuid, namespace='/agent') # 将该用户加入以user_id为名的room - backboard_manager.add_backboard(user_uuid, user, course_id, chapter_id, root_path=f'../../study/{user}/{course_id}/{chapter_id}') - - def on_language(self, language): - id = session.get('user_id') - agent_manager.change_language(id, language) - - def on_message(self, data): - print(f"Message from client: {data}") - id = session.get('user_id') - if (type(data)==str): - data = json.loads(data) - print(id) - if data['type'] == 'text': - res = agent_manager.invoke(id, data['data'], backboard_manager.get_backboard(id).get_info_prompt()) - print('=*='*20) - print(res.content) - reply = f"{res.content['speak']}" - with app.app_context(): - emit('message',reply, room=id, namespace='/agent') - emit('request_function',res.content['function'], room=id, namespace='/agent') - - if data['type'] == 'function': - agent_manager.function_call(id, data['data']) - - def on_initiative(self,data): - print("User active function call") - user_id = session['user_id'] - if data['name'] == 'sample_judge': - agent_manager.sample_judge(user_id, backboard_manager.get_backboard(user_id)) - if data['name'] == 'judge': - agent_manager.judge(user_id, backboard_manager.get_backboard(user_id)) - - - - def on_disconnect(self,data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - - -''' -Markdown to HTML -''' -# 配置文件路径 -MARKDOWN_DIR = 'books/markdown' # 存放 markdown 文件的文件夹 -STATIC_DIR = 'static' # 存放生成的 HTML 和图片资源的文件夹 -IMAGE_DIR = 'image' # 图片资源相对于 markdown 的位置 - - - -@app.route('/--markdown', methods=['GET']) -def convert_md(course_id, filename): - md_file_path = os.path.join(MARKDOWN_DIR,course_id, f'{filename}.md') - - if not os.path.exists(md_file_path): - return jsonify({'error': 'Markdown file not found'}), 404 - - # 读取 markdown 文件内容 - with open(md_file_path, 'r', encoding='utf-8') as file: - md_content = file.read() - - # 将 markdown 转换为 HTML - html_content = markdown.markdown(md_content) - # 插入 CSS 样式,限制图片最大宽度为 100%,高度自动调整 - html_with_styles = f""" - - - - - - - {html_content} - - - """ - # 保存 HTML 文件到 static 文件夹 - html_output_path = os.path.join(STATIC_DIR, f'{filename}.html') - with open(html_output_path, 'w', encoding='utf-8') as html_file: - html_file.write(html_with_styles) - - # 处理图片资源,将 image/xxx 文件夹拷贝到 static/image/xxx - image_source_dir = os.path.join(MARKDOWN_DIR,course_id, IMAGE_DIR, filename) - image_target_dir = os.path.join(STATIC_DIR, IMAGE_DIR, filename) - print(f"Copying image resources from {image_source_dir} to {image_target_dir}") - if os.path.exists(image_source_dir): - # 确保 static/image/xxx 目录存在 - if not os.path.exists(image_target_dir): - os.makedirs(image_target_dir) - - # 拷贝图片资源 - for image_file in os.listdir(image_source_dir): - full_image_file_path = os.path.join(image_source_dir, image_file) - if os.path.isfile(full_image_file_path): - shutil.copy(full_image_file_path, image_target_dir) - - return jsonify({'html_url': f'/static/{filename}.html'}) - -# 静态文件(HTML 和图片资源)的访问 -@app.route('/static/') -def serve_static(filename): - return send_from_directory(STATIC_DIR, filename) - - -''' -Vscode -''' -@app.route('/desktop///') -def desktop(user_id, course_id, chapter_id): - if 'user_id' not in session: - # return redirect(url_for('login')) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ user_id + "uuid is"+ session['user_id']) - username2uuid[user_id] = session['user_id'] - uuid2username[session['user_id']] = user_id - userid_recorder[user_id+'&'+course_id] = session['user_id'] - - # 在学习目录下创建一个名为 user_id_path 的文件夹 - path_dir = os.path.join(student_workspace_root_path, user_id, course_id,chapter_id) - os.makedirs(path_dir, exist_ok=True) - # 在此文件夹内部创建一个.config文件,并写入 user_id=user_id\n path=path - config_path = os.path.join(path_dir, '.config') - if GLOBAL_CONFIG['VSCODE_WEB_PATH']['is_wsl']: # 如果是在 WSL 中运行,则将路径转换为 WSL 路径 - path_dir = path_dir.replace('\\', '/') - path_dir = path_dir.replace(GLOBAL_CONFIG['VSCODE_WEB_PATH']['windows_path'] , GLOBAL_CONFIG['VSCODE_WEB_PATH']['wsl_path']) - with open(config_path, 'w', encoding='utf-8') as f: - tmpd = {'user_id': user_id, 'course_id': course_id, 'chapter_id': chapter_id, 'path': path_dir} - json.dump(tmpd, f) - print('---------------------') - print(config_path) - return render_template('desktop.html', vscode_web_url=VSCODE_WEB_URL, user_id=user_id, course_id=course_id, chapter_id=chapter_id, workspace_path=path_dir) - -@app.route('/desktop_nouser//') -def desktop_nouser(course_id, chapter_id): - if 'user_id' not in session: - return redirect(url_for('login')) - user_id = session['user_id'] - username = uuid2username[user_id] - return redirect(url_for('desktop', user_id=username, course_id=course_id, chapter_id=chapter_id)) - -@app.route('/vscode_data', methods=['POST']) -def vscode_data(): - data = request.json - config = data['config'] - realtime_response(config,data) - print(f"Received data from VSCode: {data}") - return jsonify({"status": "success", "received": data}) - - - -''' -Login - -''' -users_list = UserList() -course_list = CourseList() - - -@app.route('/register') -def register(): - return render_template('register.html') - -@app.route('/register_teacher') -def register_teacher(): - return render_template('register_teacher.html') - -@app.route('/register_teacher_post', methods=['POST']) -def register_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password, teacher=True) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - -@app.route('/register_post', methods=['POST']) -def register_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - - -@app.route('/login') -def login(): - return render_template('login.html') - if 'user_id' not in session: - return render_template('login.html') - else: - return redirect(url_for('/')) - -@app.route('/login_post', methods=['POST']) -def login_post(): - # 获取请求的 JSON 数据 - data = request.get_json() - - username = data.get('username') - password = data.get('password') - - pswd = users_list.get_user_pswd(username) - - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/login_teacher_post', methods=['POST']) -def login_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - pswd = users_list.get_user_pswd(username) - is_teacher = users_list.get_user_is_teacher(username) - if is_teacher is None or is_teacher == False: - return jsonify({'success': False, 'message': '用户名不存在或非教师账号'}) - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/teacherboard') -@require_role(roles="teacher") -def teacherboard(): - return render_template('teacherboard.html') - - -@app.route('/logout') -def logout(): - session.pop('user_id', None) - return redirect(url_for('login')) - -@app.route('/get_session') -def get_session(): - user_session = session.get('user_id', 'default_session') - return jsonify({"session": user_session}) - - -''' -DashBoard -''' -user_id2UserClass = {} -@app.route('/dashboard') -@require_role -def dashboard(): - user_id = session['user_id'] - username = uuid2username[user_id] - if (user_id not in user_id2UserClass): - user_id2UserClass[user_id] = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - user_course_data = [] - for course_id in user_id2UserClass[user_id].select_course: - course_brief_info = course_list.get_course_brief_info(course_id, load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR)) - user_course_data.append(course_brief_info) - return render_template('dashboard.html',user_data = user_id2UserClass[user_id].to_json_without_dialog(), user_course_data = json.dumps(user_course_data)) - -''' -Course -''' - -@app.route('/course/') -@require_role -def course(course_id): - c = load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR) - return render_template('course.html', course_id=course_id, course_data=c) - -@app.route('/select_course', methods=['POST']) -@require_role -def select_course(): - user = user_id2UserClass[session['user_id']] - data = request.get_json() - course_id = data.get('course_id') - if course_id: - user.select_new_course(course_id, load_course_from_json(course_id, COURSE_DATA_DIR)) - return jsonify({'success': True, 'message': '课程选择成功'}) - - -@app.route('/') -@require_role -def home_index(): - selected_courses=[] - if ('user_id' in session): - if (session['user_id'] not in user_id2UserClass): return redirect(url_for('login')) - user = user_id2UserClass[session['user_id']] - for course_id in user.select_course: - selected_courses.append(course_id) - - return render_template('index.html', courses_data = course_list, selected_courses =selected_courses) - -# 一些app辅助函数,主要提供给Agent与数据库的交互能力 - -class MyFunction: - def save_chapter_memory(self, id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal): - print("-=-=-=-=-=-=-=-") - print(id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - username = uuid2username[id] - u = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - u.save_chapter_memory(course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - -app.my_function = MyFunction() -if __name__ == '__main__': - socketio.on_namespace(VSCodeNamespace('/vscode')) - socketio.on_namespace(AgentNamespace('/agent')) - socketio.run(app, host='0.0.0.0', port=5551, debug=False,allow_unsafe_werkzeug=True) - diff --git a/Html/runs/run_20250911-092728_5rmbf4/code/backboardManager.py b/Html/runs/run_20250911-092728_5rmbf4/code/backboardManager.py deleted file mode 100644 index 7de5f19..0000000 --- a/Html/runs/run_20250911-092728_5rmbf4/code/backboardManager.py +++ /dev/null @@ -1,80 +0,0 @@ - - - -import time -import os - -class Backboard: - def __init__(self, user_uuid, username, course_id, lesson_id, root_path): - self.user_uuid = user_uuid - self.username = username - self.course_id = course_id - self.lesson_id = lesson_id - self.root_path = root_path - self.create_time = time.time() - self.enter_chapter_time = time.time() - self.history = [] - self.file_tree = "[]" - self.active_file_path = "" - self.active_file_content = "" - self.pasted_file_path = "" - self.pasted_content = "" - - - def next_chapter(self): - self.enter_chapter_time = time.time() - - def get_info_prompt(self): - - five_history = "" - for h in self.history[-5:]: - five_history += h['type'] + "\n" + h.get('filePath', '') + "\n\n" - - endl = "\n" - return (f"###Global Info:###{endl}" - f"Here are some info about now user's IDE, refer to it when you need to handle some code.{endl}" - f"- User's total study time is {self.get_deltatime_mmss(self.create_time, time.time())}{endl}" - f"- User's current chapter study time is {self.get_deltatime_mmss(self.enter_chapter_time, time.time())}{endl}" - f"- Activated file path: {self.active_file_path}{endl}" - f"```{endl}" - f"{self.active_file_content[-10:]}{endl}" - f"```{endl}" - f"- Last five action:{five_history}{endl}" - f"- File tree: {self.file_tree}{endl}") - # f"- Activated file content (current editing 10 lines): {endl}" - def add_history(self, realtime_action): - if(realtime_action['type']=='config'):return - if len(self.history)!=0: - if (self.history[-1]['type']=='fileEdit'): - if(self.history[-1]['filePath'] == realtime_action['filePath']): - self.history[-1]['content'] = realtime_action['content'] - return - self.history.append(realtime_action) - - - def get_deltatime_mmss(self, start_time, end_time): - elapsed_time = end_time - start_time - hours = int(elapsed_time // 3600) - minutes = int((elapsed_time % 3600) // 60) - seconds = int(elapsed_time % 60) - return f"{hours:02d}:{minutes:02d}:{seconds:02d}" - - - def get_active_file_reletive_path(self): - relative_path = os.path.relpath(self.active_file_path, self.root_path) - return relative_path - - - -class BackBoardManager: - def __init__(self): - self.backboards = {} # user_uuid: Backboard - - def add_backboard(self, user_uuid, username, course_id, lesson_id, root_path): - self.backboards[user_uuid] = Backboard(user_uuid,username, course_id, lesson_id, root_path) - - def get_backboard(self, user_uuid) -> Backboard: - return self.backboards[user_uuid] - - - diff --git a/Html/runs/run_20250911-092728_5rmbf4/code/bootstrap.py b/Html/runs/run_20250911-092728_5rmbf4/code/bootstrap.py deleted file mode 100644 index bcb15ce..0000000 --- a/Html/runs/run_20250911-092728_5rmbf4/code/bootstrap.py +++ /dev/null @@ -1,31 +0,0 @@ -from pathlib import Path -import sys, os - -def bootstrap_paths(): - """ - 让 'AlgoriAgent'(位于 repo_root/AlgoriAgent)可被 import; - 并提供 STUDENT_WORKSPACE_ROOT 的默认值(repo_root/study)。 - 适配当前工厂位置:repo_root/Html/apps/__init__.py - """ - here = Path(__file__).resolve() - # repo_root = .../Html/apps/../../ => parents[2] - repo_root = here.parents[2] - - # 兜底:如果目录结构变化,尝试向上搜索包含 AlgoriAgent 的目录作为 repo_root - if not (repo_root / "AlgoriAgent").exists(): - for p in here.parents: - if (p / "AlgoriAgent").is_dir(): - repo_root = p - break - - # 确保仓库根在 sys.path(这样 'AlgoriAgent' 顶层包可被发现) - repo_root_str = str(repo_root) - if repo_root_str not in sys.path: - sys.path.insert(0, repo_root_str) - - # 可选:如果你还有其它顶层包,也可在此处继续插入 - - # 默认学习工作区目录(也可放到 config.ini / 环境变量覆盖) - os.environ.setdefault("STUDENT_WORKSPACE_ROOT", str(repo_root / "study")) - - return repo_root # 方便调试/日志 \ No newline at end of file diff --git a/Html/runs/run_20250911-092728_5rmbf4/code/wsgi.py b/Html/runs/run_20250911-092728_5rmbf4/code/wsgi.py deleted file mode 100644 index bbcbe5f..0000000 --- a/Html/runs/run_20250911-092728_5rmbf4/code/wsgi.py +++ /dev/null @@ -1,6 +0,0 @@ -# wsgi.py -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -# 提供一个可被 WSGI/进程管理器导入的 app 对象 -app = create_app() diff --git a/Html/runs/run_20250911-092728_5rmbf4/logging.chat b/Html/runs/run_20250911-092728_5rmbf4/logging.chat deleted file mode 100644 index e69de29..0000000 diff --git a/Html/runs/run_20250911-092728_5rmbf4/logging.log b/Html/runs/run_20250911-092728_5rmbf4/logging.log deleted file mode 100644 index ffdfc53..0000000 --- a/Html/runs/run_20250911-092728_5rmbf4/logging.log +++ /dev/null @@ -1 +0,0 @@ -2025-09-11 09:27:32.968 | INFO | agentscope.models:read_model_configs:186 - Load configs for model wrapper: openai_cfg diff --git a/Html/runs/run_20250911-104127_qlzs2b/.config b/Html/runs/run_20250911-104127_qlzs2b/.config deleted file mode 100644 index 00c9c72..0000000 --- a/Html/runs/run_20250911-104127_qlzs2b/.config +++ /dev/null @@ -1,7 +0,0 @@ -{ - "project": "QOBDih", - "name": "qlzs2b", - "run_id": "run_20250911-104127_qlzs2b", - "timestamp": "2025-09-11 10:41:27", - "pid": 16187 -} \ No newline at end of file diff --git a/Html/runs/run_20250911-104127_qlzs2b/agentscope.db b/Html/runs/run_20250911-104127_qlzs2b/agentscope.db deleted file mode 100644 index 666055b77679cda29c14fcf23b4ef1d039c5b52a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI%L2KJE6bEoS4Q(k)+glI2yjv3-0%NB!Hs&O1YUav`W0U1F<0V=#BsNLx(sSu$ z>=W&q?4#^B$!*yt2YT5l`~^0a^z(#~{ zkyg6w!t)u0!@f%5aeaJcfD9*Q_b$ozCY8>~CFA6|{Z2V!N;Z^cIq}eS$>x3HY|^=j z7lokrf1)Z$x@_R^N~@apn7OPMkZ(I<*1WJCw@v3GWy2n6&RcIQ0~zlR_x8^$%be!% zmxb7@7V;}H+K5#l(wSbZKXKY!mys6ROyi|!%aN@+%REpi?;B-K4PC3&{>iCzQnNB+ zwbW!z4iA{x(V_2L+5VJ1vMJeN;5l68yJ9?OZyl-TNCEp4P{^H8$cTGExdq$9ANE6@ zA@`ZUhb>is+Y=S?%$C1fnN{muZU1a!nMRV%#qFbMT;y3hf|KlJ)00Izz00bZa0SG_<0uX=z1a@EGHy1PL*Z=?k diff --git a/Html/runs/run_20250911-104127_qlzs2b/code/app.py b/Html/runs/run_20250911-104127_qlzs2b/code/app.py deleted file mode 100644 index c7f31f7..0000000 --- a/Html/runs/run_20250911-104127_qlzs2b/code/app.py +++ /dev/null @@ -1,21 +0,0 @@ -# app.py 0.1.1 rise to factory mode -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -from apps.extensions import socketio - -# 工厂创建 app,工厂里已经做了:加载配置/注册蓝图/注册 namespaces -app = create_app() - -if __name__ == "__main__": - # 仅本地开发用;生产不要用 werkzeug 自带的开发服务器 - socketio.run( - app, - host="0.0.0.0", - port=5551, - debug=True, # 开发期打开 - allow_unsafe_werkzeug=True, # 避免 dev server 的安全限制提示 - # ssl_context=('server.crt', 'server.key') - ) - - diff --git a/Html/runs/run_20250911-104127_qlzs2b/code/app_back.py b/Html/runs/run_20250911-104127_qlzs2b/code/app_back.py deleted file mode 100644 index 246853c..0000000 --- a/Html/runs/run_20250911-104127_qlzs2b/code/app_back.py +++ /dev/null @@ -1,480 +0,0 @@ -from bootstrap import bootstrap_paths -bootstrap_paths() -from functools import wraps -from flask import Flask, redirect, session, request, jsonify, render_template, send_from_directory, url_for -from flask_cors import CORS -from flask_socketio import SocketIO, join_room, emit, Namespace -import markdown -import os -import uuid -import shutil -import sys -import json -from apps.auth.decorators import require_role -parent_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) -sys.path.insert(0, parent_dir) -student_workspace_root_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../study')) -current_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '.')) -sys.path.insert(0, current_dir) -from AlgoriAgent.projects.algoriAgent.agent_manager import AgentManager - - -import configparser - -from db.user_list import UserList -from db.user import User, load_user_from_json, create_user_json -from db.course_list import CourseList -from db.course import Course, load_course_from_json -GLOBAL_CONFIG = configparser.ConfigParser() -GLOBAL_CONFIG.read('config.ini') -VSCODE_WEB_URL = GLOBAL_CONFIG['VSCODE_WEB']['url'] -USER_DATA_DIR = GLOBAL_CONFIG['USER_DATA']['dir'] -COURSE_DATA_DIR = GLOBAL_CONFIG['COURSE_DATA']['dir'] - -app = Flask(__name__) -socketio = SocketIO(app, cors_allowed_origins="*",ping_timeout=60, ping_interval=5) -# socketio = SocketIO(app, cors_allowed_origins="http://localhost:9888") # 设置跨域支持 -import logging -app.secret_key = 'cakebaker' -app.logger.setLevel(logging.DEBUG) -# 配置 CORS -CORS(app, resources={r"/*": {"origins": VSCODE_WEB_URL},}, supports_credentials=True) - - -userid_recorder = {} # user_id&path -> session['user_id'] - -''' -Backboard -''' -from backboardManager import BackBoardManager, Backboard - -backboard_manager = BackBoardManager() -uuid2username = {} -username2uuid = {} - - - -# 定义命名空间:用于和 VSCode 插件交流 -class VSCodeNamespace(Namespace): - def on_login(self,data): - print("VSCode client connected") - print(data) - dataconfig = data['config'] - user_id = dataconfig.get('user_id') - path = dataconfig.get('path') - course_id = dataconfig.get('course_id') - lesson_id = dataconfig.get('chapter_id') - print(f"User {user_id} connected with path: {path}") - useruuid = username2uuid[user_id] - join_room(useruuid, namespace='/vscode') - if backboard_manager.get_backboard(useruuid) == None: - backboard_manager.add_backboard(useruuid,user_id, course_id, lesson_id, path) - - - def on_message(self, data): - print(f"Received from VSCode client: {data}") - dataconfig = data['config'] - realtime_response(dataconfig, data) - # emit('response', {'message': 'Config data received and connection established'}) - def on_disconnect(self, data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - -def realtime_response(config, realtime_action): - user_id = config['user_id'] - folder_path = config['path'] - useruuid = username2uuid[user_id] - bb = backboard_manager.get_backboard(useruuid) - assert type(bb) == Backboard - - bb.add_history(realtime_action) - - if realtime_action['type'] == 'workspaceFolders': - bb.file_tree = realtime_action['fileTree'] - - if realtime_action['type'] == 'activeFile': - file_path = realtime_action['filePath'] - assert type(file_path) == str - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - if realtime_action['type'] == 'paste': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.pasted_file_path = file_path - bb.pasted_content = realtime_action['content'] - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - if realtime_action['type'] == 'fileEdit': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - - - print("config"+str(config)) - print("realtime_action"+str(realtime_action)) - pass - - -''' -Agent and Chat -''' -agent_manager = AgentManager(app = app, socketio = socketio) -user_threads = {} -import threading -from concurrent.futures import ThreadPoolExecutor, as_completed - -# 初始化线程池 -executor = ThreadPoolExecutor(max_workers=10) -class AgentNamespace(Namespace): - def on_login(self, data): - data = json.loads(data) - user = data['username'] - course_id = data['course_id'] - chapter_id = data['chapter_id'] - user_uuid = username2uuid[user] - session['user_id'] = user_uuid - print(f'User connected with session user_id: {user_uuid}') - # 从markdown、markdown_prompts、score_prompts中各读取数据folder.md并进行new_agent - with open(f'books/markdown/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fmd,\ - open(f'books/markdown_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8')as fmdp,\ - open(f'books/score_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fsp: - markdown = fmd.read() - markdown_prompts = fmdp.read() - score_prompts = fsp.read() - user_uuid, agent = agent_manager.new_agent(course_id, chapter_id, markdown, markdown_prompts, score_prompts, id=user_uuid, - root_path=f'../../study/{user}/{course_id}/{chapter_id}') - print(user_uuid) - join_room(user_uuid, namespace='/agent') # 将该用户加入以user_id为名的room - backboard_manager.add_backboard(user_uuid, user, course_id, chapter_id, root_path=f'../../study/{user}/{course_id}/{chapter_id}') - - def on_language(self, language): - id = session.get('user_id') - agent_manager.change_language(id, language) - - def on_message(self, data): - print(f"Message from client: {data}") - id = session.get('user_id') - if (type(data)==str): - data = json.loads(data) - print(id) - if data['type'] == 'text': - res = agent_manager.invoke(id, data['data'], backboard_manager.get_backboard(id).get_info_prompt()) - print('=*='*20) - print(res.content) - reply = f"{res.content['speak']}" - with app.app_context(): - emit('message',reply, room=id, namespace='/agent') - emit('request_function',res.content['function'], room=id, namespace='/agent') - - if data['type'] == 'function': - agent_manager.function_call(id, data['data']) - - def on_initiative(self,data): - print("User active function call") - user_id = session['user_id'] - if data['name'] == 'sample_judge': - agent_manager.sample_judge(user_id, backboard_manager.get_backboard(user_id)) - if data['name'] == 'judge': - agent_manager.judge(user_id, backboard_manager.get_backboard(user_id)) - - - - def on_disconnect(self,data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - - -''' -Markdown to HTML -''' -# 配置文件路径 -MARKDOWN_DIR = 'books/markdown' # 存放 markdown 文件的文件夹 -STATIC_DIR = 'static' # 存放生成的 HTML 和图片资源的文件夹 -IMAGE_DIR = 'image' # 图片资源相对于 markdown 的位置 - - - -@app.route('/--markdown', methods=['GET']) -def convert_md(course_id, filename): - md_file_path = os.path.join(MARKDOWN_DIR,course_id, f'{filename}.md') - - if not os.path.exists(md_file_path): - return jsonify({'error': 'Markdown file not found'}), 404 - - # 读取 markdown 文件内容 - with open(md_file_path, 'r', encoding='utf-8') as file: - md_content = file.read() - - # 将 markdown 转换为 HTML - html_content = markdown.markdown(md_content) - # 插入 CSS 样式,限制图片最大宽度为 100%,高度自动调整 - html_with_styles = f""" - - - - - - - {html_content} - - - """ - # 保存 HTML 文件到 static 文件夹 - html_output_path = os.path.join(STATIC_DIR, f'{filename}.html') - with open(html_output_path, 'w', encoding='utf-8') as html_file: - html_file.write(html_with_styles) - - # 处理图片资源,将 image/xxx 文件夹拷贝到 static/image/xxx - image_source_dir = os.path.join(MARKDOWN_DIR,course_id, IMAGE_DIR, filename) - image_target_dir = os.path.join(STATIC_DIR, IMAGE_DIR, filename) - print(f"Copying image resources from {image_source_dir} to {image_target_dir}") - if os.path.exists(image_source_dir): - # 确保 static/image/xxx 目录存在 - if not os.path.exists(image_target_dir): - os.makedirs(image_target_dir) - - # 拷贝图片资源 - for image_file in os.listdir(image_source_dir): - full_image_file_path = os.path.join(image_source_dir, image_file) - if os.path.isfile(full_image_file_path): - shutil.copy(full_image_file_path, image_target_dir) - - return jsonify({'html_url': f'/static/{filename}.html'}) - -# 静态文件(HTML 和图片资源)的访问 -@app.route('/static/') -def serve_static(filename): - return send_from_directory(STATIC_DIR, filename) - - -''' -Vscode -''' -@app.route('/desktop///') -def desktop(user_id, course_id, chapter_id): - if 'user_id' not in session: - # return redirect(url_for('login')) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ user_id + "uuid is"+ session['user_id']) - username2uuid[user_id] = session['user_id'] - uuid2username[session['user_id']] = user_id - userid_recorder[user_id+'&'+course_id] = session['user_id'] - - # 在学习目录下创建一个名为 user_id_path 的文件夹 - path_dir = os.path.join(student_workspace_root_path, user_id, course_id,chapter_id) - os.makedirs(path_dir, exist_ok=True) - # 在此文件夹内部创建一个.config文件,并写入 user_id=user_id\n path=path - config_path = os.path.join(path_dir, '.config') - if GLOBAL_CONFIG['VSCODE_WEB_PATH']['is_wsl']: # 如果是在 WSL 中运行,则将路径转换为 WSL 路径 - path_dir = path_dir.replace('\\', '/') - path_dir = path_dir.replace(GLOBAL_CONFIG['VSCODE_WEB_PATH']['windows_path'] , GLOBAL_CONFIG['VSCODE_WEB_PATH']['wsl_path']) - with open(config_path, 'w', encoding='utf-8') as f: - tmpd = {'user_id': user_id, 'course_id': course_id, 'chapter_id': chapter_id, 'path': path_dir} - json.dump(tmpd, f) - print('---------------------') - print(config_path) - return render_template('desktop.html', vscode_web_url=VSCODE_WEB_URL, user_id=user_id, course_id=course_id, chapter_id=chapter_id, workspace_path=path_dir) - -@app.route('/desktop_nouser//') -def desktop_nouser(course_id, chapter_id): - if 'user_id' not in session: - return redirect(url_for('login')) - user_id = session['user_id'] - username = uuid2username[user_id] - return redirect(url_for('desktop', user_id=username, course_id=course_id, chapter_id=chapter_id)) - -@app.route('/vscode_data', methods=['POST']) -def vscode_data(): - data = request.json - config = data['config'] - realtime_response(config,data) - print(f"Received data from VSCode: {data}") - return jsonify({"status": "success", "received": data}) - - - -''' -Login - -''' -users_list = UserList() -course_list = CourseList() - - -@app.route('/register') -def register(): - return render_template('register.html') - -@app.route('/register_teacher') -def register_teacher(): - return render_template('register_teacher.html') - -@app.route('/register_teacher_post', methods=['POST']) -def register_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password, teacher=True) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - -@app.route('/register_post', methods=['POST']) -def register_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - - -@app.route('/login') -def login(): - return render_template('login.html') - if 'user_id' not in session: - return render_template('login.html') - else: - return redirect(url_for('/')) - -@app.route('/login_post', methods=['POST']) -def login_post(): - # 获取请求的 JSON 数据 - data = request.get_json() - - username = data.get('username') - password = data.get('password') - - pswd = users_list.get_user_pswd(username) - - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/login_teacher_post', methods=['POST']) -def login_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - pswd = users_list.get_user_pswd(username) - is_teacher = users_list.get_user_is_teacher(username) - if is_teacher is None or is_teacher == False: - return jsonify({'success': False, 'message': '用户名不存在或非教师账号'}) - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/teacherboard') -@require_role(roles="teacher") -def teacherboard(): - return render_template('teacherboard.html') - - -@app.route('/logout') -def logout(): - session.pop('user_id', None) - return redirect(url_for('login')) - -@app.route('/get_session') -def get_session(): - user_session = session.get('user_id', 'default_session') - return jsonify({"session": user_session}) - - -''' -DashBoard -''' -user_id2UserClass = {} -@app.route('/dashboard') -@require_role -def dashboard(): - user_id = session['user_id'] - username = uuid2username[user_id] - if (user_id not in user_id2UserClass): - user_id2UserClass[user_id] = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - user_course_data = [] - for course_id in user_id2UserClass[user_id].select_course: - course_brief_info = course_list.get_course_brief_info(course_id, load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR)) - user_course_data.append(course_brief_info) - return render_template('dashboard.html',user_data = user_id2UserClass[user_id].to_json_without_dialog(), user_course_data = json.dumps(user_course_data)) - -''' -Course -''' - -@app.route('/course/') -@require_role -def course(course_id): - c = load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR) - return render_template('course.html', course_id=course_id, course_data=c) - -@app.route('/select_course', methods=['POST']) -@require_role -def select_course(): - user = user_id2UserClass[session['user_id']] - data = request.get_json() - course_id = data.get('course_id') - if course_id: - user.select_new_course(course_id, load_course_from_json(course_id, COURSE_DATA_DIR)) - return jsonify({'success': True, 'message': '课程选择成功'}) - - -@app.route('/') -@require_role -def home_index(): - selected_courses=[] - if ('user_id' in session): - if (session['user_id'] not in user_id2UserClass): return redirect(url_for('login')) - user = user_id2UserClass[session['user_id']] - for course_id in user.select_course: - selected_courses.append(course_id) - - return render_template('index.html', courses_data = course_list, selected_courses =selected_courses) - -# 一些app辅助函数,主要提供给Agent与数据库的交互能力 - -class MyFunction: - def save_chapter_memory(self, id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal): - print("-=-=-=-=-=-=-=-") - print(id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - username = uuid2username[id] - u = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - u.save_chapter_memory(course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - -app.my_function = MyFunction() -if __name__ == '__main__': - socketio.on_namespace(VSCodeNamespace('/vscode')) - socketio.on_namespace(AgentNamespace('/agent')) - socketio.run(app, host='0.0.0.0', port=5551, debug=False,allow_unsafe_werkzeug=True) - diff --git a/Html/runs/run_20250911-104127_qlzs2b/code/backboardManager.py b/Html/runs/run_20250911-104127_qlzs2b/code/backboardManager.py deleted file mode 100644 index 7de5f19..0000000 --- a/Html/runs/run_20250911-104127_qlzs2b/code/backboardManager.py +++ /dev/null @@ -1,80 +0,0 @@ - - - -import time -import os - -class Backboard: - def __init__(self, user_uuid, username, course_id, lesson_id, root_path): - self.user_uuid = user_uuid - self.username = username - self.course_id = course_id - self.lesson_id = lesson_id - self.root_path = root_path - self.create_time = time.time() - self.enter_chapter_time = time.time() - self.history = [] - self.file_tree = "[]" - self.active_file_path = "" - self.active_file_content = "" - self.pasted_file_path = "" - self.pasted_content = "" - - - def next_chapter(self): - self.enter_chapter_time = time.time() - - def get_info_prompt(self): - - five_history = "" - for h in self.history[-5:]: - five_history += h['type'] + "\n" + h.get('filePath', '') + "\n\n" - - endl = "\n" - return (f"###Global Info:###{endl}" - f"Here are some info about now user's IDE, refer to it when you need to handle some code.{endl}" - f"- User's total study time is {self.get_deltatime_mmss(self.create_time, time.time())}{endl}" - f"- User's current chapter study time is {self.get_deltatime_mmss(self.enter_chapter_time, time.time())}{endl}" - f"- Activated file path: {self.active_file_path}{endl}" - f"```{endl}" - f"{self.active_file_content[-10:]}{endl}" - f"```{endl}" - f"- Last five action:{five_history}{endl}" - f"- File tree: {self.file_tree}{endl}") - # f"- Activated file content (current editing 10 lines): {endl}" - def add_history(self, realtime_action): - if(realtime_action['type']=='config'):return - if len(self.history)!=0: - if (self.history[-1]['type']=='fileEdit'): - if(self.history[-1]['filePath'] == realtime_action['filePath']): - self.history[-1]['content'] = realtime_action['content'] - return - self.history.append(realtime_action) - - - def get_deltatime_mmss(self, start_time, end_time): - elapsed_time = end_time - start_time - hours = int(elapsed_time // 3600) - minutes = int((elapsed_time % 3600) // 60) - seconds = int(elapsed_time % 60) - return f"{hours:02d}:{minutes:02d}:{seconds:02d}" - - - def get_active_file_reletive_path(self): - relative_path = os.path.relpath(self.active_file_path, self.root_path) - return relative_path - - - -class BackBoardManager: - def __init__(self): - self.backboards = {} # user_uuid: Backboard - - def add_backboard(self, user_uuid, username, course_id, lesson_id, root_path): - self.backboards[user_uuid] = Backboard(user_uuid,username, course_id, lesson_id, root_path) - - def get_backboard(self, user_uuid) -> Backboard: - return self.backboards[user_uuid] - - - diff --git a/Html/runs/run_20250911-104127_qlzs2b/code/bootstrap.py b/Html/runs/run_20250911-104127_qlzs2b/code/bootstrap.py deleted file mode 100644 index bcb15ce..0000000 --- a/Html/runs/run_20250911-104127_qlzs2b/code/bootstrap.py +++ /dev/null @@ -1,31 +0,0 @@ -from pathlib import Path -import sys, os - -def bootstrap_paths(): - """ - 让 'AlgoriAgent'(位于 repo_root/AlgoriAgent)可被 import; - 并提供 STUDENT_WORKSPACE_ROOT 的默认值(repo_root/study)。 - 适配当前工厂位置:repo_root/Html/apps/__init__.py - """ - here = Path(__file__).resolve() - # repo_root = .../Html/apps/../../ => parents[2] - repo_root = here.parents[2] - - # 兜底:如果目录结构变化,尝试向上搜索包含 AlgoriAgent 的目录作为 repo_root - if not (repo_root / "AlgoriAgent").exists(): - for p in here.parents: - if (p / "AlgoriAgent").is_dir(): - repo_root = p - break - - # 确保仓库根在 sys.path(这样 'AlgoriAgent' 顶层包可被发现) - repo_root_str = str(repo_root) - if repo_root_str not in sys.path: - sys.path.insert(0, repo_root_str) - - # 可选:如果你还有其它顶层包,也可在此处继续插入 - - # 默认学习工作区目录(也可放到 config.ini / 环境变量覆盖) - os.environ.setdefault("STUDENT_WORKSPACE_ROOT", str(repo_root / "study")) - - return repo_root # 方便调试/日志 \ No newline at end of file diff --git a/Html/runs/run_20250911-104127_qlzs2b/code/wsgi.py b/Html/runs/run_20250911-104127_qlzs2b/code/wsgi.py deleted file mode 100644 index bbcbe5f..0000000 --- a/Html/runs/run_20250911-104127_qlzs2b/code/wsgi.py +++ /dev/null @@ -1,6 +0,0 @@ -# wsgi.py -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -# 提供一个可被 WSGI/进程管理器导入的 app 对象 -app = create_app() diff --git a/Html/runs/run_20250911-104127_qlzs2b/logging.chat b/Html/runs/run_20250911-104127_qlzs2b/logging.chat deleted file mode 100644 index e69de29..0000000 diff --git a/Html/runs/run_20250911-104127_qlzs2b/logging.log b/Html/runs/run_20250911-104127_qlzs2b/logging.log deleted file mode 100644 index 656fcbd..0000000 --- a/Html/runs/run_20250911-104127_qlzs2b/logging.log +++ /dev/null @@ -1 +0,0 @@ -2025-09-11 10:41:34.396 | INFO | agentscope.models:read_model_configs:186 - Load configs for model wrapper: openai_cfg diff --git a/Html/runs/run_20250911-104133_7ghm53/.config b/Html/runs/run_20250911-104133_7ghm53/.config deleted file mode 100644 index 276c651..0000000 --- a/Html/runs/run_20250911-104133_7ghm53/.config +++ /dev/null @@ -1,7 +0,0 @@ -{ - "project": "RcPxCa", - "name": "7ghm53", - "run_id": "run_20250911-104133_7ghm53", - "timestamp": "2025-09-11 10:41:33", - "pid": 16208 -} \ No newline at end of file diff --git a/Html/runs/run_20250911-104133_7ghm53/agentscope.db b/Html/runs/run_20250911-104133_7ghm53/agentscope.db deleted file mode 100644 index 666055b77679cda29c14fcf23b4ef1d039c5b52a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI%L2KJE6bEoS4Q(k)+glI2yjv3-0%NB!Hs&O1YUav`W0U1F<0V=#BsNLx(sSu$ z>=W&q?4#^B$!*yt2YT5l`~^0a^z(#~{ zkyg6w!t)u0!@f%5aeaJcfD9*Q_b$ozCY8>~CFA6|{Z2V!N;Z^cIq}eS$>x3HY|^=j z7lokrf1)Z$x@_R^N~@apn7OPMkZ(I<*1WJCw@v3GWy2n6&RcIQ0~zlR_x8^$%be!% zmxb7@7V;}H+K5#l(wSbZKXKY!mys6ROyi|!%aN@+%REpi?;B-K4PC3&{>iCzQnNB+ zwbW!z4iA{x(V_2L+5VJ1vMJeN;5l68yJ9?OZyl-TNCEp4P{^H8$cTGExdq$9ANE6@ zA@`ZUhb>is+Y=S?%$C1fnN{muZU1a!nMRV%#qFbMT;y3hf|KlJ)00Izz00bZa0SG_<0uX=z1a@EGHy1PL*Z=?k diff --git a/Html/runs/run_20250911-104133_7ghm53/code/app.py b/Html/runs/run_20250911-104133_7ghm53/code/app.py deleted file mode 100644 index c7f31f7..0000000 --- a/Html/runs/run_20250911-104133_7ghm53/code/app.py +++ /dev/null @@ -1,21 +0,0 @@ -# app.py 0.1.1 rise to factory mode -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -from apps.extensions import socketio - -# 工厂创建 app,工厂里已经做了:加载配置/注册蓝图/注册 namespaces -app = create_app() - -if __name__ == "__main__": - # 仅本地开发用;生产不要用 werkzeug 自带的开发服务器 - socketio.run( - app, - host="0.0.0.0", - port=5551, - debug=True, # 开发期打开 - allow_unsafe_werkzeug=True, # 避免 dev server 的安全限制提示 - # ssl_context=('server.crt', 'server.key') - ) - - diff --git a/Html/runs/run_20250911-104133_7ghm53/code/app_back.py b/Html/runs/run_20250911-104133_7ghm53/code/app_back.py deleted file mode 100644 index 246853c..0000000 --- a/Html/runs/run_20250911-104133_7ghm53/code/app_back.py +++ /dev/null @@ -1,480 +0,0 @@ -from bootstrap import bootstrap_paths -bootstrap_paths() -from functools import wraps -from flask import Flask, redirect, session, request, jsonify, render_template, send_from_directory, url_for -from flask_cors import CORS -from flask_socketio import SocketIO, join_room, emit, Namespace -import markdown -import os -import uuid -import shutil -import sys -import json -from apps.auth.decorators import require_role -parent_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) -sys.path.insert(0, parent_dir) -student_workspace_root_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../study')) -current_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '.')) -sys.path.insert(0, current_dir) -from AlgoriAgent.projects.algoriAgent.agent_manager import AgentManager - - -import configparser - -from db.user_list import UserList -from db.user import User, load_user_from_json, create_user_json -from db.course_list import CourseList -from db.course import Course, load_course_from_json -GLOBAL_CONFIG = configparser.ConfigParser() -GLOBAL_CONFIG.read('config.ini') -VSCODE_WEB_URL = GLOBAL_CONFIG['VSCODE_WEB']['url'] -USER_DATA_DIR = GLOBAL_CONFIG['USER_DATA']['dir'] -COURSE_DATA_DIR = GLOBAL_CONFIG['COURSE_DATA']['dir'] - -app = Flask(__name__) -socketio = SocketIO(app, cors_allowed_origins="*",ping_timeout=60, ping_interval=5) -# socketio = SocketIO(app, cors_allowed_origins="http://localhost:9888") # 设置跨域支持 -import logging -app.secret_key = 'cakebaker' -app.logger.setLevel(logging.DEBUG) -# 配置 CORS -CORS(app, resources={r"/*": {"origins": VSCODE_WEB_URL},}, supports_credentials=True) - - -userid_recorder = {} # user_id&path -> session['user_id'] - -''' -Backboard -''' -from backboardManager import BackBoardManager, Backboard - -backboard_manager = BackBoardManager() -uuid2username = {} -username2uuid = {} - - - -# 定义命名空间:用于和 VSCode 插件交流 -class VSCodeNamespace(Namespace): - def on_login(self,data): - print("VSCode client connected") - print(data) - dataconfig = data['config'] - user_id = dataconfig.get('user_id') - path = dataconfig.get('path') - course_id = dataconfig.get('course_id') - lesson_id = dataconfig.get('chapter_id') - print(f"User {user_id} connected with path: {path}") - useruuid = username2uuid[user_id] - join_room(useruuid, namespace='/vscode') - if backboard_manager.get_backboard(useruuid) == None: - backboard_manager.add_backboard(useruuid,user_id, course_id, lesson_id, path) - - - def on_message(self, data): - print(f"Received from VSCode client: {data}") - dataconfig = data['config'] - realtime_response(dataconfig, data) - # emit('response', {'message': 'Config data received and connection established'}) - def on_disconnect(self, data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - -def realtime_response(config, realtime_action): - user_id = config['user_id'] - folder_path = config['path'] - useruuid = username2uuid[user_id] - bb = backboard_manager.get_backboard(useruuid) - assert type(bb) == Backboard - - bb.add_history(realtime_action) - - if realtime_action['type'] == 'workspaceFolders': - bb.file_tree = realtime_action['fileTree'] - - if realtime_action['type'] == 'activeFile': - file_path = realtime_action['filePath'] - assert type(file_path) == str - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - if realtime_action['type'] == 'paste': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.pasted_file_path = file_path - bb.pasted_content = realtime_action['content'] - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - if realtime_action['type'] == 'fileEdit': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - - - print("config"+str(config)) - print("realtime_action"+str(realtime_action)) - pass - - -''' -Agent and Chat -''' -agent_manager = AgentManager(app = app, socketio = socketio) -user_threads = {} -import threading -from concurrent.futures import ThreadPoolExecutor, as_completed - -# 初始化线程池 -executor = ThreadPoolExecutor(max_workers=10) -class AgentNamespace(Namespace): - def on_login(self, data): - data = json.loads(data) - user = data['username'] - course_id = data['course_id'] - chapter_id = data['chapter_id'] - user_uuid = username2uuid[user] - session['user_id'] = user_uuid - print(f'User connected with session user_id: {user_uuid}') - # 从markdown、markdown_prompts、score_prompts中各读取数据folder.md并进行new_agent - with open(f'books/markdown/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fmd,\ - open(f'books/markdown_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8')as fmdp,\ - open(f'books/score_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fsp: - markdown = fmd.read() - markdown_prompts = fmdp.read() - score_prompts = fsp.read() - user_uuid, agent = agent_manager.new_agent(course_id, chapter_id, markdown, markdown_prompts, score_prompts, id=user_uuid, - root_path=f'../../study/{user}/{course_id}/{chapter_id}') - print(user_uuid) - join_room(user_uuid, namespace='/agent') # 将该用户加入以user_id为名的room - backboard_manager.add_backboard(user_uuid, user, course_id, chapter_id, root_path=f'../../study/{user}/{course_id}/{chapter_id}') - - def on_language(self, language): - id = session.get('user_id') - agent_manager.change_language(id, language) - - def on_message(self, data): - print(f"Message from client: {data}") - id = session.get('user_id') - if (type(data)==str): - data = json.loads(data) - print(id) - if data['type'] == 'text': - res = agent_manager.invoke(id, data['data'], backboard_manager.get_backboard(id).get_info_prompt()) - print('=*='*20) - print(res.content) - reply = f"{res.content['speak']}" - with app.app_context(): - emit('message',reply, room=id, namespace='/agent') - emit('request_function',res.content['function'], room=id, namespace='/agent') - - if data['type'] == 'function': - agent_manager.function_call(id, data['data']) - - def on_initiative(self,data): - print("User active function call") - user_id = session['user_id'] - if data['name'] == 'sample_judge': - agent_manager.sample_judge(user_id, backboard_manager.get_backboard(user_id)) - if data['name'] == 'judge': - agent_manager.judge(user_id, backboard_manager.get_backboard(user_id)) - - - - def on_disconnect(self,data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - - -''' -Markdown to HTML -''' -# 配置文件路径 -MARKDOWN_DIR = 'books/markdown' # 存放 markdown 文件的文件夹 -STATIC_DIR = 'static' # 存放生成的 HTML 和图片资源的文件夹 -IMAGE_DIR = 'image' # 图片资源相对于 markdown 的位置 - - - -@app.route('/--markdown', methods=['GET']) -def convert_md(course_id, filename): - md_file_path = os.path.join(MARKDOWN_DIR,course_id, f'{filename}.md') - - if not os.path.exists(md_file_path): - return jsonify({'error': 'Markdown file not found'}), 404 - - # 读取 markdown 文件内容 - with open(md_file_path, 'r', encoding='utf-8') as file: - md_content = file.read() - - # 将 markdown 转换为 HTML - html_content = markdown.markdown(md_content) - # 插入 CSS 样式,限制图片最大宽度为 100%,高度自动调整 - html_with_styles = f""" - - - - - - - {html_content} - - - """ - # 保存 HTML 文件到 static 文件夹 - html_output_path = os.path.join(STATIC_DIR, f'{filename}.html') - with open(html_output_path, 'w', encoding='utf-8') as html_file: - html_file.write(html_with_styles) - - # 处理图片资源,将 image/xxx 文件夹拷贝到 static/image/xxx - image_source_dir = os.path.join(MARKDOWN_DIR,course_id, IMAGE_DIR, filename) - image_target_dir = os.path.join(STATIC_DIR, IMAGE_DIR, filename) - print(f"Copying image resources from {image_source_dir} to {image_target_dir}") - if os.path.exists(image_source_dir): - # 确保 static/image/xxx 目录存在 - if not os.path.exists(image_target_dir): - os.makedirs(image_target_dir) - - # 拷贝图片资源 - for image_file in os.listdir(image_source_dir): - full_image_file_path = os.path.join(image_source_dir, image_file) - if os.path.isfile(full_image_file_path): - shutil.copy(full_image_file_path, image_target_dir) - - return jsonify({'html_url': f'/static/{filename}.html'}) - -# 静态文件(HTML 和图片资源)的访问 -@app.route('/static/') -def serve_static(filename): - return send_from_directory(STATIC_DIR, filename) - - -''' -Vscode -''' -@app.route('/desktop///') -def desktop(user_id, course_id, chapter_id): - if 'user_id' not in session: - # return redirect(url_for('login')) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ user_id + "uuid is"+ session['user_id']) - username2uuid[user_id] = session['user_id'] - uuid2username[session['user_id']] = user_id - userid_recorder[user_id+'&'+course_id] = session['user_id'] - - # 在学习目录下创建一个名为 user_id_path 的文件夹 - path_dir = os.path.join(student_workspace_root_path, user_id, course_id,chapter_id) - os.makedirs(path_dir, exist_ok=True) - # 在此文件夹内部创建一个.config文件,并写入 user_id=user_id\n path=path - config_path = os.path.join(path_dir, '.config') - if GLOBAL_CONFIG['VSCODE_WEB_PATH']['is_wsl']: # 如果是在 WSL 中运行,则将路径转换为 WSL 路径 - path_dir = path_dir.replace('\\', '/') - path_dir = path_dir.replace(GLOBAL_CONFIG['VSCODE_WEB_PATH']['windows_path'] , GLOBAL_CONFIG['VSCODE_WEB_PATH']['wsl_path']) - with open(config_path, 'w', encoding='utf-8') as f: - tmpd = {'user_id': user_id, 'course_id': course_id, 'chapter_id': chapter_id, 'path': path_dir} - json.dump(tmpd, f) - print('---------------------') - print(config_path) - return render_template('desktop.html', vscode_web_url=VSCODE_WEB_URL, user_id=user_id, course_id=course_id, chapter_id=chapter_id, workspace_path=path_dir) - -@app.route('/desktop_nouser//') -def desktop_nouser(course_id, chapter_id): - if 'user_id' not in session: - return redirect(url_for('login')) - user_id = session['user_id'] - username = uuid2username[user_id] - return redirect(url_for('desktop', user_id=username, course_id=course_id, chapter_id=chapter_id)) - -@app.route('/vscode_data', methods=['POST']) -def vscode_data(): - data = request.json - config = data['config'] - realtime_response(config,data) - print(f"Received data from VSCode: {data}") - return jsonify({"status": "success", "received": data}) - - - -''' -Login - -''' -users_list = UserList() -course_list = CourseList() - - -@app.route('/register') -def register(): - return render_template('register.html') - -@app.route('/register_teacher') -def register_teacher(): - return render_template('register_teacher.html') - -@app.route('/register_teacher_post', methods=['POST']) -def register_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password, teacher=True) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - -@app.route('/register_post', methods=['POST']) -def register_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - - -@app.route('/login') -def login(): - return render_template('login.html') - if 'user_id' not in session: - return render_template('login.html') - else: - return redirect(url_for('/')) - -@app.route('/login_post', methods=['POST']) -def login_post(): - # 获取请求的 JSON 数据 - data = request.get_json() - - username = data.get('username') - password = data.get('password') - - pswd = users_list.get_user_pswd(username) - - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/login_teacher_post', methods=['POST']) -def login_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - pswd = users_list.get_user_pswd(username) - is_teacher = users_list.get_user_is_teacher(username) - if is_teacher is None or is_teacher == False: - return jsonify({'success': False, 'message': '用户名不存在或非教师账号'}) - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/teacherboard') -@require_role(roles="teacher") -def teacherboard(): - return render_template('teacherboard.html') - - -@app.route('/logout') -def logout(): - session.pop('user_id', None) - return redirect(url_for('login')) - -@app.route('/get_session') -def get_session(): - user_session = session.get('user_id', 'default_session') - return jsonify({"session": user_session}) - - -''' -DashBoard -''' -user_id2UserClass = {} -@app.route('/dashboard') -@require_role -def dashboard(): - user_id = session['user_id'] - username = uuid2username[user_id] - if (user_id not in user_id2UserClass): - user_id2UserClass[user_id] = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - user_course_data = [] - for course_id in user_id2UserClass[user_id].select_course: - course_brief_info = course_list.get_course_brief_info(course_id, load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR)) - user_course_data.append(course_brief_info) - return render_template('dashboard.html',user_data = user_id2UserClass[user_id].to_json_without_dialog(), user_course_data = json.dumps(user_course_data)) - -''' -Course -''' - -@app.route('/course/') -@require_role -def course(course_id): - c = load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR) - return render_template('course.html', course_id=course_id, course_data=c) - -@app.route('/select_course', methods=['POST']) -@require_role -def select_course(): - user = user_id2UserClass[session['user_id']] - data = request.get_json() - course_id = data.get('course_id') - if course_id: - user.select_new_course(course_id, load_course_from_json(course_id, COURSE_DATA_DIR)) - return jsonify({'success': True, 'message': '课程选择成功'}) - - -@app.route('/') -@require_role -def home_index(): - selected_courses=[] - if ('user_id' in session): - if (session['user_id'] not in user_id2UserClass): return redirect(url_for('login')) - user = user_id2UserClass[session['user_id']] - for course_id in user.select_course: - selected_courses.append(course_id) - - return render_template('index.html', courses_data = course_list, selected_courses =selected_courses) - -# 一些app辅助函数,主要提供给Agent与数据库的交互能力 - -class MyFunction: - def save_chapter_memory(self, id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal): - print("-=-=-=-=-=-=-=-") - print(id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - username = uuid2username[id] - u = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - u.save_chapter_memory(course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - -app.my_function = MyFunction() -if __name__ == '__main__': - socketio.on_namespace(VSCodeNamespace('/vscode')) - socketio.on_namespace(AgentNamespace('/agent')) - socketio.run(app, host='0.0.0.0', port=5551, debug=False,allow_unsafe_werkzeug=True) - diff --git a/Html/runs/run_20250911-104133_7ghm53/code/backboardManager.py b/Html/runs/run_20250911-104133_7ghm53/code/backboardManager.py deleted file mode 100644 index 7de5f19..0000000 --- a/Html/runs/run_20250911-104133_7ghm53/code/backboardManager.py +++ /dev/null @@ -1,80 +0,0 @@ - - - -import time -import os - -class Backboard: - def __init__(self, user_uuid, username, course_id, lesson_id, root_path): - self.user_uuid = user_uuid - self.username = username - self.course_id = course_id - self.lesson_id = lesson_id - self.root_path = root_path - self.create_time = time.time() - self.enter_chapter_time = time.time() - self.history = [] - self.file_tree = "[]" - self.active_file_path = "" - self.active_file_content = "" - self.pasted_file_path = "" - self.pasted_content = "" - - - def next_chapter(self): - self.enter_chapter_time = time.time() - - def get_info_prompt(self): - - five_history = "" - for h in self.history[-5:]: - five_history += h['type'] + "\n" + h.get('filePath', '') + "\n\n" - - endl = "\n" - return (f"###Global Info:###{endl}" - f"Here are some info about now user's IDE, refer to it when you need to handle some code.{endl}" - f"- User's total study time is {self.get_deltatime_mmss(self.create_time, time.time())}{endl}" - f"- User's current chapter study time is {self.get_deltatime_mmss(self.enter_chapter_time, time.time())}{endl}" - f"- Activated file path: {self.active_file_path}{endl}" - f"```{endl}" - f"{self.active_file_content[-10:]}{endl}" - f"```{endl}" - f"- Last five action:{five_history}{endl}" - f"- File tree: {self.file_tree}{endl}") - # f"- Activated file content (current editing 10 lines): {endl}" - def add_history(self, realtime_action): - if(realtime_action['type']=='config'):return - if len(self.history)!=0: - if (self.history[-1]['type']=='fileEdit'): - if(self.history[-1]['filePath'] == realtime_action['filePath']): - self.history[-1]['content'] = realtime_action['content'] - return - self.history.append(realtime_action) - - - def get_deltatime_mmss(self, start_time, end_time): - elapsed_time = end_time - start_time - hours = int(elapsed_time // 3600) - minutes = int((elapsed_time % 3600) // 60) - seconds = int(elapsed_time % 60) - return f"{hours:02d}:{minutes:02d}:{seconds:02d}" - - - def get_active_file_reletive_path(self): - relative_path = os.path.relpath(self.active_file_path, self.root_path) - return relative_path - - - -class BackBoardManager: - def __init__(self): - self.backboards = {} # user_uuid: Backboard - - def add_backboard(self, user_uuid, username, course_id, lesson_id, root_path): - self.backboards[user_uuid] = Backboard(user_uuid,username, course_id, lesson_id, root_path) - - def get_backboard(self, user_uuid) -> Backboard: - return self.backboards[user_uuid] - - - diff --git a/Html/runs/run_20250911-104133_7ghm53/code/bootstrap.py b/Html/runs/run_20250911-104133_7ghm53/code/bootstrap.py deleted file mode 100644 index bcb15ce..0000000 --- a/Html/runs/run_20250911-104133_7ghm53/code/bootstrap.py +++ /dev/null @@ -1,31 +0,0 @@ -from pathlib import Path -import sys, os - -def bootstrap_paths(): - """ - 让 'AlgoriAgent'(位于 repo_root/AlgoriAgent)可被 import; - 并提供 STUDENT_WORKSPACE_ROOT 的默认值(repo_root/study)。 - 适配当前工厂位置:repo_root/Html/apps/__init__.py - """ - here = Path(__file__).resolve() - # repo_root = .../Html/apps/../../ => parents[2] - repo_root = here.parents[2] - - # 兜底:如果目录结构变化,尝试向上搜索包含 AlgoriAgent 的目录作为 repo_root - if not (repo_root / "AlgoriAgent").exists(): - for p in here.parents: - if (p / "AlgoriAgent").is_dir(): - repo_root = p - break - - # 确保仓库根在 sys.path(这样 'AlgoriAgent' 顶层包可被发现) - repo_root_str = str(repo_root) - if repo_root_str not in sys.path: - sys.path.insert(0, repo_root_str) - - # 可选:如果你还有其它顶层包,也可在此处继续插入 - - # 默认学习工作区目录(也可放到 config.ini / 环境变量覆盖) - os.environ.setdefault("STUDENT_WORKSPACE_ROOT", str(repo_root / "study")) - - return repo_root # 方便调试/日志 \ No newline at end of file diff --git a/Html/runs/run_20250911-104133_7ghm53/code/wsgi.py b/Html/runs/run_20250911-104133_7ghm53/code/wsgi.py deleted file mode 100644 index bbcbe5f..0000000 --- a/Html/runs/run_20250911-104133_7ghm53/code/wsgi.py +++ /dev/null @@ -1,6 +0,0 @@ -# wsgi.py -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -# 提供一个可被 WSGI/进程管理器导入的 app 对象 -app = create_app() diff --git a/Html/runs/run_20250911-104133_7ghm53/logging.chat b/Html/runs/run_20250911-104133_7ghm53/logging.chat deleted file mode 100644 index e69de29..0000000 diff --git a/Html/runs/run_20250911-104133_7ghm53/logging.log b/Html/runs/run_20250911-104133_7ghm53/logging.log deleted file mode 100644 index 268615d..0000000 --- a/Html/runs/run_20250911-104133_7ghm53/logging.log +++ /dev/null @@ -1 +0,0 @@ -2025-09-11 10:41:37.858 | INFO | agentscope.models:read_model_configs:186 - Load configs for model wrapper: openai_cfg diff --git a/Html/runs/run_20250911-132607_r8195b/.config b/Html/runs/run_20250911-132607_r8195b/.config deleted file mode 100644 index 857bbe5..0000000 --- a/Html/runs/run_20250911-132607_r8195b/.config +++ /dev/null @@ -1,7 +0,0 @@ -{ - "project": "YWVI7s", - "name": "r8195b", - "run_id": "run_20250911-132607_r8195b", - "timestamp": "2025-09-11 13:26:07", - "pid": 17659 -} \ No newline at end of file diff --git a/Html/runs/run_20250911-132607_r8195b/agentscope.db b/Html/runs/run_20250911-132607_r8195b/agentscope.db deleted file mode 100644 index 666055b77679cda29c14fcf23b4ef1d039c5b52a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI%L2KJE6bEoS4Q(k)+glI2yjv3-0%NB!Hs&O1YUav`W0U1F<0V=#BsNLx(sSu$ z>=W&q?4#^B$!*yt2YT5l`~^0a^z(#~{ zkyg6w!t)u0!@f%5aeaJcfD9*Q_b$ozCY8>~CFA6|{Z2V!N;Z^cIq}eS$>x3HY|^=j z7lokrf1)Z$x@_R^N~@apn7OPMkZ(I<*1WJCw@v3GWy2n6&RcIQ0~zlR_x8^$%be!% zmxb7@7V;}H+K5#l(wSbZKXKY!mys6ROyi|!%aN@+%REpi?;B-K4PC3&{>iCzQnNB+ zwbW!z4iA{x(V_2L+5VJ1vMJeN;5l68yJ9?OZyl-TNCEp4P{^H8$cTGExdq$9ANE6@ zA@`ZUhb>is+Y=S?%$C1fnN{muZU1a!nMRV%#qFbMT;y3hf|KlJ)00Izz00bZa0SG_<0uX=z1a@EGHy1PL*Z=?k diff --git a/Html/runs/run_20250911-132607_r8195b/code/app.py b/Html/runs/run_20250911-132607_r8195b/code/app.py deleted file mode 100644 index c7f31f7..0000000 --- a/Html/runs/run_20250911-132607_r8195b/code/app.py +++ /dev/null @@ -1,21 +0,0 @@ -# app.py 0.1.1 rise to factory mode -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -from apps.extensions import socketio - -# 工厂创建 app,工厂里已经做了:加载配置/注册蓝图/注册 namespaces -app = create_app() - -if __name__ == "__main__": - # 仅本地开发用;生产不要用 werkzeug 自带的开发服务器 - socketio.run( - app, - host="0.0.0.0", - port=5551, - debug=True, # 开发期打开 - allow_unsafe_werkzeug=True, # 避免 dev server 的安全限制提示 - # ssl_context=('server.crt', 'server.key') - ) - - diff --git a/Html/runs/run_20250911-132607_r8195b/code/app_back.py b/Html/runs/run_20250911-132607_r8195b/code/app_back.py deleted file mode 100644 index 246853c..0000000 --- a/Html/runs/run_20250911-132607_r8195b/code/app_back.py +++ /dev/null @@ -1,480 +0,0 @@ -from bootstrap import bootstrap_paths -bootstrap_paths() -from functools import wraps -from flask import Flask, redirect, session, request, jsonify, render_template, send_from_directory, url_for -from flask_cors import CORS -from flask_socketio import SocketIO, join_room, emit, Namespace -import markdown -import os -import uuid -import shutil -import sys -import json -from apps.auth.decorators import require_role -parent_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) -sys.path.insert(0, parent_dir) -student_workspace_root_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../study')) -current_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '.')) -sys.path.insert(0, current_dir) -from AlgoriAgent.projects.algoriAgent.agent_manager import AgentManager - - -import configparser - -from db.user_list import UserList -from db.user import User, load_user_from_json, create_user_json -from db.course_list import CourseList -from db.course import Course, load_course_from_json -GLOBAL_CONFIG = configparser.ConfigParser() -GLOBAL_CONFIG.read('config.ini') -VSCODE_WEB_URL = GLOBAL_CONFIG['VSCODE_WEB']['url'] -USER_DATA_DIR = GLOBAL_CONFIG['USER_DATA']['dir'] -COURSE_DATA_DIR = GLOBAL_CONFIG['COURSE_DATA']['dir'] - -app = Flask(__name__) -socketio = SocketIO(app, cors_allowed_origins="*",ping_timeout=60, ping_interval=5) -# socketio = SocketIO(app, cors_allowed_origins="http://localhost:9888") # 设置跨域支持 -import logging -app.secret_key = 'cakebaker' -app.logger.setLevel(logging.DEBUG) -# 配置 CORS -CORS(app, resources={r"/*": {"origins": VSCODE_WEB_URL},}, supports_credentials=True) - - -userid_recorder = {} # user_id&path -> session['user_id'] - -''' -Backboard -''' -from backboardManager import BackBoardManager, Backboard - -backboard_manager = BackBoardManager() -uuid2username = {} -username2uuid = {} - - - -# 定义命名空间:用于和 VSCode 插件交流 -class VSCodeNamespace(Namespace): - def on_login(self,data): - print("VSCode client connected") - print(data) - dataconfig = data['config'] - user_id = dataconfig.get('user_id') - path = dataconfig.get('path') - course_id = dataconfig.get('course_id') - lesson_id = dataconfig.get('chapter_id') - print(f"User {user_id} connected with path: {path}") - useruuid = username2uuid[user_id] - join_room(useruuid, namespace='/vscode') - if backboard_manager.get_backboard(useruuid) == None: - backboard_manager.add_backboard(useruuid,user_id, course_id, lesson_id, path) - - - def on_message(self, data): - print(f"Received from VSCode client: {data}") - dataconfig = data['config'] - realtime_response(dataconfig, data) - # emit('response', {'message': 'Config data received and connection established'}) - def on_disconnect(self, data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - -def realtime_response(config, realtime_action): - user_id = config['user_id'] - folder_path = config['path'] - useruuid = username2uuid[user_id] - bb = backboard_manager.get_backboard(useruuid) - assert type(bb) == Backboard - - bb.add_history(realtime_action) - - if realtime_action['type'] == 'workspaceFolders': - bb.file_tree = realtime_action['fileTree'] - - if realtime_action['type'] == 'activeFile': - file_path = realtime_action['filePath'] - assert type(file_path) == str - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - if realtime_action['type'] == 'paste': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.pasted_file_path = file_path - bb.pasted_content = realtime_action['content'] - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - if realtime_action['type'] == 'fileEdit': - file_path = realtime_action['filePath'] - assert type(file_path) == str - bb.active_file_path = file_path - with open(f"{file_path}") as f: - bb.active_file_content = f.read() - - - - - print("config"+str(config)) - print("realtime_action"+str(realtime_action)) - pass - - -''' -Agent and Chat -''' -agent_manager = AgentManager(app = app, socketio = socketio) -user_threads = {} -import threading -from concurrent.futures import ThreadPoolExecutor, as_completed - -# 初始化线程池 -executor = ThreadPoolExecutor(max_workers=10) -class AgentNamespace(Namespace): - def on_login(self, data): - data = json.loads(data) - user = data['username'] - course_id = data['course_id'] - chapter_id = data['chapter_id'] - user_uuid = username2uuid[user] - session['user_id'] = user_uuid - print(f'User connected with session user_id: {user_uuid}') - # 从markdown、markdown_prompts、score_prompts中各读取数据folder.md并进行new_agent - with open(f'books/markdown/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fmd,\ - open(f'books/markdown_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8')as fmdp,\ - open(f'books/score_prompts/{course_id}/{chapter_id}.md','r',encoding='UTF-8') as fsp: - markdown = fmd.read() - markdown_prompts = fmdp.read() - score_prompts = fsp.read() - user_uuid, agent = agent_manager.new_agent(course_id, chapter_id, markdown, markdown_prompts, score_prompts, id=user_uuid, - root_path=f'../../study/{user}/{course_id}/{chapter_id}') - print(user_uuid) - join_room(user_uuid, namespace='/agent') # 将该用户加入以user_id为名的room - backboard_manager.add_backboard(user_uuid, user, course_id, chapter_id, root_path=f'../../study/{user}/{course_id}/{chapter_id}') - - def on_language(self, language): - id = session.get('user_id') - agent_manager.change_language(id, language) - - def on_message(self, data): - print(f"Message from client: {data}") - id = session.get('user_id') - if (type(data)==str): - data = json.loads(data) - print(id) - if data['type'] == 'text': - res = agent_manager.invoke(id, data['data'], backboard_manager.get_backboard(id).get_info_prompt()) - print('=*='*20) - print(res.content) - reply = f"{res.content['speak']}" - with app.app_context(): - emit('message',reply, room=id, namespace='/agent') - emit('request_function',res.content['function'], room=id, namespace='/agent') - - if data['type'] == 'function': - agent_manager.function_call(id, data['data']) - - def on_initiative(self,data): - print("User active function call") - user_id = session['user_id'] - if data['name'] == 'sample_judge': - agent_manager.sample_judge(user_id, backboard_manager.get_backboard(user_id)) - if data['name'] == 'judge': - agent_manager.judge(user_id, backboard_manager.get_backboard(user_id)) - - - - def on_disconnect(self,data): - print("VSCode client disconnected") - print("Disconnect reason:"+str(data)) - - - -''' -Markdown to HTML -''' -# 配置文件路径 -MARKDOWN_DIR = 'books/markdown' # 存放 markdown 文件的文件夹 -STATIC_DIR = 'static' # 存放生成的 HTML 和图片资源的文件夹 -IMAGE_DIR = 'image' # 图片资源相对于 markdown 的位置 - - - -@app.route('/--markdown', methods=['GET']) -def convert_md(course_id, filename): - md_file_path = os.path.join(MARKDOWN_DIR,course_id, f'{filename}.md') - - if not os.path.exists(md_file_path): - return jsonify({'error': 'Markdown file not found'}), 404 - - # 读取 markdown 文件内容 - with open(md_file_path, 'r', encoding='utf-8') as file: - md_content = file.read() - - # 将 markdown 转换为 HTML - html_content = markdown.markdown(md_content) - # 插入 CSS 样式,限制图片最大宽度为 100%,高度自动调整 - html_with_styles = f""" - - - - - - - {html_content} - - - """ - # 保存 HTML 文件到 static 文件夹 - html_output_path = os.path.join(STATIC_DIR, f'{filename}.html') - with open(html_output_path, 'w', encoding='utf-8') as html_file: - html_file.write(html_with_styles) - - # 处理图片资源,将 image/xxx 文件夹拷贝到 static/image/xxx - image_source_dir = os.path.join(MARKDOWN_DIR,course_id, IMAGE_DIR, filename) - image_target_dir = os.path.join(STATIC_DIR, IMAGE_DIR, filename) - print(f"Copying image resources from {image_source_dir} to {image_target_dir}") - if os.path.exists(image_source_dir): - # 确保 static/image/xxx 目录存在 - if not os.path.exists(image_target_dir): - os.makedirs(image_target_dir) - - # 拷贝图片资源 - for image_file in os.listdir(image_source_dir): - full_image_file_path = os.path.join(image_source_dir, image_file) - if os.path.isfile(full_image_file_path): - shutil.copy(full_image_file_path, image_target_dir) - - return jsonify({'html_url': f'/static/{filename}.html'}) - -# 静态文件(HTML 和图片资源)的访问 -@app.route('/static/') -def serve_static(filename): - return send_from_directory(STATIC_DIR, filename) - - -''' -Vscode -''' -@app.route('/desktop///') -def desktop(user_id, course_id, chapter_id): - if 'user_id' not in session: - # return redirect(url_for('login')) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ user_id + "uuid is"+ session['user_id']) - username2uuid[user_id] = session['user_id'] - uuid2username[session['user_id']] = user_id - userid_recorder[user_id+'&'+course_id] = session['user_id'] - - # 在学习目录下创建一个名为 user_id_path 的文件夹 - path_dir = os.path.join(student_workspace_root_path, user_id, course_id,chapter_id) - os.makedirs(path_dir, exist_ok=True) - # 在此文件夹内部创建一个.config文件,并写入 user_id=user_id\n path=path - config_path = os.path.join(path_dir, '.config') - if GLOBAL_CONFIG['VSCODE_WEB_PATH']['is_wsl']: # 如果是在 WSL 中运行,则将路径转换为 WSL 路径 - path_dir = path_dir.replace('\\', '/') - path_dir = path_dir.replace(GLOBAL_CONFIG['VSCODE_WEB_PATH']['windows_path'] , GLOBAL_CONFIG['VSCODE_WEB_PATH']['wsl_path']) - with open(config_path, 'w', encoding='utf-8') as f: - tmpd = {'user_id': user_id, 'course_id': course_id, 'chapter_id': chapter_id, 'path': path_dir} - json.dump(tmpd, f) - print('---------------------') - print(config_path) - return render_template('desktop.html', vscode_web_url=VSCODE_WEB_URL, user_id=user_id, course_id=course_id, chapter_id=chapter_id, workspace_path=path_dir) - -@app.route('/desktop_nouser//') -def desktop_nouser(course_id, chapter_id): - if 'user_id' not in session: - return redirect(url_for('login')) - user_id = session['user_id'] - username = uuid2username[user_id] - return redirect(url_for('desktop', user_id=username, course_id=course_id, chapter_id=chapter_id)) - -@app.route('/vscode_data', methods=['POST']) -def vscode_data(): - data = request.json - config = data['config'] - realtime_response(config,data) - print(f"Received data from VSCode: {data}") - return jsonify({"status": "success", "received": data}) - - - -''' -Login - -''' -users_list = UserList() -course_list = CourseList() - - -@app.route('/register') -def register(): - return render_template('register.html') - -@app.route('/register_teacher') -def register_teacher(): - return render_template('register_teacher.html') - -@app.route('/register_teacher_post', methods=['POST']) -def register_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password, teacher=True) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - -@app.route('/register_post', methods=['POST']) -def register_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - if users_list.has_user(username) is not None: - users_list.add_user(username, password) - create_user_json(username, USER_DATA_DIR) - return jsonify({'success': True, 'message': '注册成功'}) - else: return jsonify({'success': False, 'message': '用户已存在,请更换用户名'}) - - -@app.route('/login') -def login(): - return render_template('login.html') - if 'user_id' not in session: - return render_template('login.html') - else: - return redirect(url_for('/')) - -@app.route('/login_post', methods=['POST']) -def login_post(): - # 获取请求的 JSON 数据 - data = request.get_json() - - username = data.get('username') - password = data.get('password') - - pswd = users_list.get_user_pswd(username) - - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/login_teacher_post', methods=['POST']) -def login_teacher_post(): - data = request.get_json() - username = data.get('username') - password = data.get('password') - pswd = users_list.get_user_pswd(username) - is_teacher = users_list.get_user_is_teacher(username) - if is_teacher is None or is_teacher == False: - return jsonify({'success': False, 'message': '用户名不存在或非教师账号'}) - if pswd is None: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - if pswd != password: - return jsonify({'success': False, 'message': '用户名或密码错误'}) - session['user_id'] = 'user_' + str(uuid.uuid4()) - print("user "+ username + "uuid is"+ session['user_id']) - username2uuid[username] = session['user_id'] - uuid2username[session['user_id']] = username - return jsonify({'success': True, 'message': '登录成功'}) - -@app.route('/teacherboard') -@require_role(roles="teacher") -def teacherboard(): - return render_template('teacherboard.html') - - -@app.route('/logout') -def logout(): - session.pop('user_id', None) - return redirect(url_for('login')) - -@app.route('/get_session') -def get_session(): - user_session = session.get('user_id', 'default_session') - return jsonify({"session": user_session}) - - -''' -DashBoard -''' -user_id2UserClass = {} -@app.route('/dashboard') -@require_role -def dashboard(): - user_id = session['user_id'] - username = uuid2username[user_id] - if (user_id not in user_id2UserClass): - user_id2UserClass[user_id] = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - user_course_data = [] - for course_id in user_id2UserClass[user_id].select_course: - course_brief_info = course_list.get_course_brief_info(course_id, load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR)) - user_course_data.append(course_brief_info) - return render_template('dashboard.html',user_data = user_id2UserClass[user_id].to_json_without_dialog(), user_course_data = json.dumps(user_course_data)) - -''' -Course -''' - -@app.route('/course/') -@require_role -def course(course_id): - c = load_course_from_json(course_id, course_data_dir = COURSE_DATA_DIR) - return render_template('course.html', course_id=course_id, course_data=c) - -@app.route('/select_course', methods=['POST']) -@require_role -def select_course(): - user = user_id2UserClass[session['user_id']] - data = request.get_json() - course_id = data.get('course_id') - if course_id: - user.select_new_course(course_id, load_course_from_json(course_id, COURSE_DATA_DIR)) - return jsonify({'success': True, 'message': '课程选择成功'}) - - -@app.route('/') -@require_role -def home_index(): - selected_courses=[] - if ('user_id' in session): - if (session['user_id'] not in user_id2UserClass): return redirect(url_for('login')) - user = user_id2UserClass[session['user_id']] - for course_id in user.select_course: - selected_courses.append(course_id) - - return render_template('index.html', courses_data = course_list, selected_courses =selected_courses) - -# 一些app辅助函数,主要提供给Agent与数据库的交互能力 - -class MyFunction: - def save_chapter_memory(self, id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal): - print("-=-=-=-=-=-=-=-") - print(id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - username = uuid2username[id] - u = load_user_from_json(username, user_data_dir = USER_DATA_DIR) - u.save_chapter_memory(course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal) - -app.my_function = MyFunction() -if __name__ == '__main__': - socketio.on_namespace(VSCodeNamespace('/vscode')) - socketio.on_namespace(AgentNamespace('/agent')) - socketio.run(app, host='0.0.0.0', port=5551, debug=False,allow_unsafe_werkzeug=True) - diff --git a/Html/runs/run_20250911-132607_r8195b/code/backboardManager.py b/Html/runs/run_20250911-132607_r8195b/code/backboardManager.py deleted file mode 100644 index 7de5f19..0000000 --- a/Html/runs/run_20250911-132607_r8195b/code/backboardManager.py +++ /dev/null @@ -1,80 +0,0 @@ - - - -import time -import os - -class Backboard: - def __init__(self, user_uuid, username, course_id, lesson_id, root_path): - self.user_uuid = user_uuid - self.username = username - self.course_id = course_id - self.lesson_id = lesson_id - self.root_path = root_path - self.create_time = time.time() - self.enter_chapter_time = time.time() - self.history = [] - self.file_tree = "[]" - self.active_file_path = "" - self.active_file_content = "" - self.pasted_file_path = "" - self.pasted_content = "" - - - def next_chapter(self): - self.enter_chapter_time = time.time() - - def get_info_prompt(self): - - five_history = "" - for h in self.history[-5:]: - five_history += h['type'] + "\n" + h.get('filePath', '') + "\n\n" - - endl = "\n" - return (f"###Global Info:###{endl}" - f"Here are some info about now user's IDE, refer to it when you need to handle some code.{endl}" - f"- User's total study time is {self.get_deltatime_mmss(self.create_time, time.time())}{endl}" - f"- User's current chapter study time is {self.get_deltatime_mmss(self.enter_chapter_time, time.time())}{endl}" - f"- Activated file path: {self.active_file_path}{endl}" - f"```{endl}" - f"{self.active_file_content[-10:]}{endl}" - f"```{endl}" - f"- Last five action:{five_history}{endl}" - f"- File tree: {self.file_tree}{endl}") - # f"- Activated file content (current editing 10 lines): {endl}" - def add_history(self, realtime_action): - if(realtime_action['type']=='config'):return - if len(self.history)!=0: - if (self.history[-1]['type']=='fileEdit'): - if(self.history[-1]['filePath'] == realtime_action['filePath']): - self.history[-1]['content'] = realtime_action['content'] - return - self.history.append(realtime_action) - - - def get_deltatime_mmss(self, start_time, end_time): - elapsed_time = end_time - start_time - hours = int(elapsed_time // 3600) - minutes = int((elapsed_time % 3600) // 60) - seconds = int(elapsed_time % 60) - return f"{hours:02d}:{minutes:02d}:{seconds:02d}" - - - def get_active_file_reletive_path(self): - relative_path = os.path.relpath(self.active_file_path, self.root_path) - return relative_path - - - -class BackBoardManager: - def __init__(self): - self.backboards = {} # user_uuid: Backboard - - def add_backboard(self, user_uuid, username, course_id, lesson_id, root_path): - self.backboards[user_uuid] = Backboard(user_uuid,username, course_id, lesson_id, root_path) - - def get_backboard(self, user_uuid) -> Backboard: - return self.backboards[user_uuid] - - - diff --git a/Html/runs/run_20250911-132607_r8195b/code/bootstrap.py b/Html/runs/run_20250911-132607_r8195b/code/bootstrap.py deleted file mode 100644 index bcb15ce..0000000 --- a/Html/runs/run_20250911-132607_r8195b/code/bootstrap.py +++ /dev/null @@ -1,31 +0,0 @@ -from pathlib import Path -import sys, os - -def bootstrap_paths(): - """ - 让 'AlgoriAgent'(位于 repo_root/AlgoriAgent)可被 import; - 并提供 STUDENT_WORKSPACE_ROOT 的默认值(repo_root/study)。 - 适配当前工厂位置:repo_root/Html/apps/__init__.py - """ - here = Path(__file__).resolve() - # repo_root = .../Html/apps/../../ => parents[2] - repo_root = here.parents[2] - - # 兜底:如果目录结构变化,尝试向上搜索包含 AlgoriAgent 的目录作为 repo_root - if not (repo_root / "AlgoriAgent").exists(): - for p in here.parents: - if (p / "AlgoriAgent").is_dir(): - repo_root = p - break - - # 确保仓库根在 sys.path(这样 'AlgoriAgent' 顶层包可被发现) - repo_root_str = str(repo_root) - if repo_root_str not in sys.path: - sys.path.insert(0, repo_root_str) - - # 可选:如果你还有其它顶层包,也可在此处继续插入 - - # 默认学习工作区目录(也可放到 config.ini / 环境变量覆盖) - os.environ.setdefault("STUDENT_WORKSPACE_ROOT", str(repo_root / "study")) - - return repo_root # 方便调试/日志 \ No newline at end of file diff --git a/Html/runs/run_20250911-132607_r8195b/code/wsgi.py b/Html/runs/run_20250911-132607_r8195b/code/wsgi.py deleted file mode 100644 index bbcbe5f..0000000 --- a/Html/runs/run_20250911-132607_r8195b/code/wsgi.py +++ /dev/null @@ -1,6 +0,0 @@ -# wsgi.py -from bootstrap import bootstrap_paths -bootstrap_paths() -from apps import create_app -# 提供一个可被 WSGI/进程管理器导入的 app 对象 -app = create_app() diff --git a/Html/runs/run_20250911-132607_r8195b/logging.chat b/Html/runs/run_20250911-132607_r8195b/logging.chat deleted file mode 100644 index e69de29..0000000 diff --git a/Html/runs/run_20250911-132607_r8195b/logging.log b/Html/runs/run_20250911-132607_r8195b/logging.log deleted file mode 100644 index 6dd397b..0000000 --- a/Html/runs/run_20250911-132607_r8195b/logging.log +++ /dev/null @@ -1 +0,0 @@ -2025-09-11 13:26:12.648 | INFO | agentscope.models:read_model_configs:186 - Load configs for model wrapper: openai_cfg