zrb 1.0.0a20__py3-none-any.whl → 1.0.0b3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (195) hide show
  1. zrb/__init__.py +2 -1
  2. zrb/__main__.py +3 -3
  3. zrb/builtin/__init__.py +3 -0
  4. zrb/builtin/group.py +1 -0
  5. zrb/builtin/llm/llm_chat.py +5 -3
  6. zrb/builtin/llm/tool/cli.py +1 -1
  7. zrb/builtin/llm/tool/rag.py +108 -145
  8. zrb/builtin/llm/tool/web.py +1 -1
  9. zrb/builtin/project/add/fastapp/fastapp_task.py +2 -0
  10. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/config.py +5 -2
  11. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/add_entity_task.py +80 -20
  12. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/add_entity_util.py +150 -42
  13. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/template/app_template/module/my_module/service/my_entity/my_entity_service.py +113 -0
  14. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/template/app_template/module/my_module/service/my_entity/my_entity_service_factory.py +9 -0
  15. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/template/app_template/module/my_module/service/my_entity/repository/my_entity_db_repository.py +0 -10
  16. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/template/app_template/module/my_module/service/my_entity/repository/my_entity_repository.py +37 -16
  17. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/template/app_template/module/my_module/service/my_entity/repository/{factory.py → my_entity_repository_factory.py} +2 -2
  18. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/template/app_template/schema/my_entity.py +16 -6
  19. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/template/client_method.py +57 -0
  20. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/template/gateway_subroute.py +74 -0
  21. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/format_task.py +1 -1
  22. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/input.py +13 -0
  23. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/add_module_task.py +23 -0
  24. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/add_module_util.py +42 -0
  25. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/gateway/subroute/my_module.py +7 -0
  26. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/my_module/client/my_module_api_client.py +6 -0
  27. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/my_module/client/{any_client.py → my_module_client.py} +1 -1
  28. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/my_module/client/my_module_client_factory.py +11 -0
  29. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/my_module/client/my_module_direct_client.py +5 -0
  30. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/my_module/route.py +11 -11
  31. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/template/module_task_definition.py +2 -2
  32. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/task.py +8 -8
  33. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/util.py +47 -20
  34. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/common/app_factory.py +29 -0
  35. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/common/base_db_repository.py +230 -102
  36. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/common/base_service.py +236 -0
  37. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/common/{db_engine.py → db_engine_factory.py} +1 -1
  38. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/common/error.py +12 -0
  39. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/common/logger_factory.py +10 -0
  40. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/common/parser_factory.py +7 -0
  41. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/common/util/app.py +47 -0
  42. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/common/util/parser.py +105 -0
  43. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/common/util/user_agent.py +58 -0
  44. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/common/util/view.py +37 -0
  45. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/config.py +37 -1
  46. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/main.py +1 -1
  47. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/client/auth_api_client.py +16 -0
  48. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/client/auth_client.py +169 -0
  49. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/client/auth_client_factory.py +9 -0
  50. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/client/auth_direct_client.py +15 -0
  51. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/migration/versions/3093c7336477_add_auth_tables.py +160 -0
  52. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/migration_metadata.py +18 -1
  53. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/route.py +7 -3
  54. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/permission/permission_service.py +117 -0
  55. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/permission/permission_service_factory.py +11 -0
  56. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/permission/repository/permission_db_repository.py +26 -0
  57. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/permission/repository/permission_repository.py +61 -0
  58. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/permission/repository/permission_repository_factory.py +13 -0
  59. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/role/repository/role_db_repository.py +89 -0
  60. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/role/repository/role_repository.py +67 -0
  61. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/role/repository/role_repository_factory.py +13 -0
  62. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/role/role_service.py +137 -0
  63. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/role/role_service_factory.py +7 -0
  64. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/repository/user_db_repository.py +179 -12
  65. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/repository/user_repository.py +67 -17
  66. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/repository/user_repository_factory.py +2 -2
  67. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/user_service.py +127 -0
  68. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/user_service_factory.py +7 -0
  69. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/route.py +43 -14
  70. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/subroute/auth.py +200 -30
  71. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/util/view.py +74 -0
  72. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/content/error.html +6 -0
  73. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/content/homepage.html +6 -0
  74. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/images/android-chrome-192x192.png +0 -0
  75. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/images/android-chrome-512x512.png +0 -0
  76. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/images/favicon-32x32.png +0 -0
  77. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.amber.min.css +4 -0
  78. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.blue.min.css +4 -0
  79. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.cyan.min.css +4 -0
  80. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.fuchsia.min.css +4 -0
  81. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.green.min.css +4 -0
  82. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.grey.min.css +4 -0
  83. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.indigo.min.css +4 -0
  84. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.jade.min.css +4 -0
  85. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.lime.min.css +4 -0
  86. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.min.css +4 -0
  87. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.orange.min.css +4 -0
  88. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.pink.min.css +4 -0
  89. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.pumpkin.min.css +4 -0
  90. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.purple.min.css +4 -0
  91. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.red.min.css +4 -0
  92. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.sand.min.css +4 -0
  93. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.slate.min.css +4 -0
  94. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.violet.min.css +4 -0
  95. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.yellow.min.css +4 -0
  96. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.zinc.min.css +4 -0
  97. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/template/default.html +34 -0
  98. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/requirements.txt +1 -0
  99. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/schema/permission.py +17 -5
  100. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/schema/role.py +78 -4
  101. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/schema/session.py +48 -0
  102. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/schema/user.py +69 -5
  103. zrb/builtin/python.py +1 -1
  104. zrb/builtin/random.py +61 -0
  105. zrb/cmd/cmd_val.py +6 -5
  106. zrb/config.py +16 -3
  107. zrb/content_transformer/any_content_transformer.py +7 -0
  108. zrb/content_transformer/content_transformer.py +6 -0
  109. zrb/runner/cli.py +14 -7
  110. zrb/runner/web_app.py +28 -238
  111. zrb/runner/web_config/config.py +91 -0
  112. zrb/runner/web_config/config_factory.py +26 -0
  113. zrb/runner/web_route/docs_route.py +17 -0
  114. zrb/runner/web_route/error_page/serve_default_404.py +28 -0
  115. zrb/runner/{web_controller/error_page/controller.py → web_route/error_page/show_error_page.py} +4 -3
  116. zrb/runner/{web_controller → web_route}/error_page/view.html +6 -0
  117. zrb/runner/web_route/home_page/home_page_route.py +51 -0
  118. zrb/runner/{web_controller → web_route}/home_page/view.html +1 -0
  119. zrb/runner/web_route/login_api_route.py +31 -0
  120. zrb/runner/web_route/login_page/login_page_route.py +39 -0
  121. zrb/runner/{web_controller → web_route}/login_page/view.html +1 -0
  122. zrb/runner/web_route/logout_api_route.py +18 -0
  123. zrb/runner/web_route/logout_page/logout_page_route.py +40 -0
  124. zrb/runner/{web_controller → web_route}/logout_page/view.html +1 -0
  125. zrb/runner/{web_controller/group_info_page/controller.py → web_route/node_page/group/show_group_page.py} +3 -3
  126. zrb/runner/{web_controller/group_info_page → web_route/node_page/group}/view.html +1 -0
  127. zrb/runner/web_route/node_page/node_page_route.py +50 -0
  128. zrb/runner/{web_controller/session_page/controller.py → web_route/node_page/task/show_task_page.py} +5 -5
  129. zrb/runner/{web_controller/session_page → web_route/node_page/task}/view.html +1 -0
  130. zrb/runner/web_route/refresh_token_api_route.py +38 -0
  131. zrb/runner/web_route/static/refresh-token.template.js +22 -0
  132. zrb/runner/{web_controller/static → web_route/static/resources}/session/current-session.js +6 -3
  133. zrb/runner/{web_controller/static → web_route/static/resources}/session/event.js +10 -8
  134. zrb/runner/{web_controller/static → web_route/static/resources}/session/past-session.js +9 -3
  135. zrb/runner/web_route/static/static_route.py +44 -0
  136. zrb/runner/web_route/task_input_api_route.py +47 -0
  137. zrb/runner/web_route/task_session_api_route.py +147 -0
  138. zrb/runner/web_schema/session.py +5 -0
  139. zrb/runner/web_schema/token.py +11 -0
  140. zrb/runner/web_schema/user.py +32 -0
  141. zrb/runner/web_util/cookie.py +29 -0
  142. zrb/runner/{web_util.py → web_util/html.py} +1 -18
  143. zrb/runner/web_util/token.py +72 -0
  144. zrb/runner/web_util/user.py +63 -0
  145. zrb/session/session.py +6 -4
  146. zrb/session_state_logger/{default_session_state_logger.py → session_state_logger_factory.py} +1 -1
  147. zrb/task/base_task.py +56 -8
  148. zrb/task/base_trigger.py +2 -0
  149. zrb/task/cmd_task.py +9 -5
  150. zrb/task/http_check.py +2 -0
  151. zrb/task/llm_task.py +184 -71
  152. zrb/task/make_task.py +2 -0
  153. zrb/task/rsync_task.py +2 -0
  154. zrb/task/scaffolder.py +8 -5
  155. zrb/task/scheduler.py +2 -0
  156. zrb/task/tcp_check.py +2 -0
  157. zrb/task_status/task_status.py +4 -3
  158. zrb/util/cmd/command.py +1 -0
  159. zrb/util/file.py +7 -1
  160. zrb/util/llm/tool.py +3 -7
  161. {zrb-1.0.0a20.dist-info → zrb-1.0.0b3.dist-info}/METADATA +9 -52
  162. zrb-1.0.0b3.dist-info/RECORD +307 -0
  163. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/template/any_client_method.py +0 -27
  164. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/template/app_template/module/my_module/service/my_entity/my_entity_usecase.py +0 -65
  165. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/my_module/client/api_client.py +0 -6
  166. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/my_module/client/direct_client.py +0 -6
  167. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/my_module/client/factory.py +0 -9
  168. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/common/app.py +0 -20
  169. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/common/base_usecase.py +0 -245
  170. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/client/any_client.py +0 -33
  171. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/client/api_client.py +0 -7
  172. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/client/direct_client.py +0 -6
  173. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/client/factory.py +0 -9
  174. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/migration/versions/3093c7336477_add_user_table.py +0 -37
  175. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/user_usecase.py +0 -53
  176. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/user_usecase_factory.py +0 -6
  177. zrb/runner/web_config.py +0 -288
  178. zrb/runner/web_controller/home_page/controller.py +0 -33
  179. zrb/runner/web_controller/login_page/controller.py +0 -25
  180. zrb/runner/web_controller/logout_page/controller.py +0 -26
  181. zrb-1.0.0a20.dist-info/RECORD +0 -243
  182. /zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/column/{create_column_task.py → add_column_task.py} +0 -0
  183. /zrb/{runner/web_controller → builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/permission}/__init__.py +0 -0
  184. /zrb/{runner/web_controller/group_info_page → builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/role}/__init__.py +0 -0
  185. /zrb/runner/{web_controller/home_page → web_route}/__init__.py +0 -0
  186. /zrb/runner/{web_controller/session_page → web_route/home_page}/__init__.py +0 -0
  187. /zrb/runner/{web_controller/session_page → web_route/node_page/task}/partial/input.html +0 -0
  188. /zrb/runner/{web_controller/static → web_route/static/resources}/common.css +0 -0
  189. /zrb/runner/{web_controller/static → web_route/static/resources}/favicon-32x32.png +0 -0
  190. /zrb/runner/{web_controller/static → web_route/static/resources}/login/event.js +0 -0
  191. /zrb/runner/{web_controller/static → web_route/static/resources}/logout/event.js +0 -0
  192. /zrb/runner/{web_controller/static → web_route/static/resources}/pico.min.css +0 -0
  193. /zrb/runner/{web_controller/static → web_route/static/resources}/session/common-util.js +0 -0
  194. {zrb-1.0.0a20.dist-info → zrb-1.0.0b3.dist-info}/WHEEL +0 -0
  195. {zrb-1.0.0a20.dist-info → zrb-1.0.0b3.dist-info}/entry_points.txt +0 -0
zrb/__init__.py CHANGED
@@ -34,7 +34,8 @@ from zrb.input.password_input import PasswordInput
34
34
  from zrb.input.str_input import StrInput
35
35
  from zrb.input.text_input import TextInput
36
36
  from zrb.runner.cli import cli
37
- from zrb.runner.web_config import User, web_config
37
+ from zrb.runner.web_config.config_factory import web_config
38
+ from zrb.runner.web_schema.user import User
38
39
  from zrb.session.session import Session
39
40
  from zrb.task.any_task import AnyTask
40
41
  from zrb.task.base_task import BaseTask
zrb/__main__.py CHANGED
@@ -14,10 +14,10 @@ def serve_cli():
14
14
  for init_script in INIT_SCRIPTS:
15
15
  load_file(init_script, -1)
16
16
  cli.run(sys.argv[1:])
17
- except RuntimeError as e:
18
- if "Event loop is closed" not in f"{e}":
19
- raise e
20
17
  except KeyboardInterrupt:
21
18
  print(stylize_warning("\nStopped"), file=sys.stderr)
19
+ except RuntimeError as e:
20
+ if f"{e}".lower() != "event loop is closed":
21
+ raise e
22
22
  except NodeNotFoundError as e:
23
23
  print(stylize_error(f"{e}"), file=sys.stderr)
zrb/builtin/__init__.py CHANGED
@@ -12,6 +12,7 @@ from zrb.builtin.md5 import hash_md5, sum_md5
12
12
  from zrb.builtin.project.add.fastapp.fastapp_task import add_fastapp_to_project
13
13
  from zrb.builtin.project.create.project_task import create_project
14
14
  from zrb.builtin.python import format_python_code
15
+ from zrb.builtin.random import shuffle_values, throw_dice
15
16
  from zrb.builtin.setup.asdf.asdf import setup_asdf
16
17
  from zrb.builtin.setup.latex.ubuntu import setup_latex_on_ubuntu
17
18
  from zrb.builtin.setup.tmux.tmux import setup_tmux
@@ -55,6 +56,8 @@ assert edit_todo
55
56
  assert complete_todo
56
57
  assert log_todo
57
58
  assert show_todo
59
+ assert throw_dice
60
+ assert shuffle_values
58
61
  assert setup_ubuntu
59
62
  assert setup_latex_on_ubuntu
60
63
  assert setup_asdf
zrb/builtin/group.py CHANGED
@@ -2,6 +2,7 @@ from zrb.group.group import Group
2
2
  from zrb.runner.cli import cli
3
3
 
4
4
  base64_group = cli.add_group(Group(name="base64", description="📄 Base64 operations"))
5
+ random_group = cli.add_group(Group(name="random", description="🔀 Random operation"))
5
6
  git_group = cli.add_group(Group(name="git", description="🌱 Git related commands"))
6
7
  git_branch_group = git_group.add_group(
7
8
  Group(name="branch", description="🌿 Git branch related commands")
@@ -1,6 +1,7 @@
1
1
  from zrb.builtin.group import llm_group
2
2
  from zrb.builtin.llm.tool.cli import run_shell_command
3
- from zrb.builtin.llm.tool.web import open_web_page, query_internet
3
+ from zrb.builtin.llm.tool.rag import create_rag_from_directory
4
+ from zrb.builtin.llm.tool.web import open_web_route, query_internet
4
5
  from zrb.config import (
5
6
  LLM_ALLOW_ACCESS_SHELL,
6
7
  LLM_ALLOW_ACCESS_WEB,
@@ -22,7 +23,7 @@ llm_chat: LLMTask = llm_group.add_task(
22
23
  prompt="LLM Model",
23
24
  default_str=LLM_MODEL,
24
25
  ),
25
- StrInput(
26
+ TextInput(
26
27
  "system-prompt",
27
28
  description="System prompt",
28
29
  prompt="System prompt",
@@ -35,6 +36,7 @@ llm_chat: LLMTask = llm_group.add_task(
35
36
  model="{ctx.input.model}",
36
37
  system_prompt="{ctx.input['system-prompt']}",
37
38
  message="{ctx.input.message}",
39
+ retries=0,
38
40
  ),
39
41
  alias="chat",
40
42
  )
@@ -43,5 +45,5 @@ if LLM_ALLOW_ACCESS_SHELL:
43
45
  llm_chat.add_tool(run_shell_command)
44
46
 
45
47
  if LLM_ALLOW_ACCESS_WEB:
46
- llm_chat.add_tool(open_web_page)
48
+ llm_chat.add_tool(open_web_route)
47
49
  llm_chat.add_tool(query_internet)
@@ -2,7 +2,7 @@ import subprocess
2
2
 
3
3
 
4
4
  def run_shell_command(command: str) -> str:
5
- """Running a shell command"""
5
+ """Running an actual shell command on user's computer."""
6
6
  output = subprocess.check_output(
7
7
  command, shell=True, stderr=subprocess.STDOUT, text=True
8
8
  )
@@ -1,9 +1,10 @@
1
+ import hashlib
1
2
  import json
2
3
  import os
3
4
  import sys
4
- from collections.abc import Callable, Iterable
5
5
 
6
6
  import litellm
7
+ import ulid
7
8
 
8
9
  from zrb.config import (
9
10
  RAG_CHUNK_SIZE,
@@ -13,10 +14,6 @@ from zrb.config import (
13
14
  )
14
15
  from zrb.util.cli.style import stylize_error, stylize_faint
15
16
  from zrb.util.file import read_file
16
- from zrb.util.run import run_async
17
-
18
- Document = str | Callable[[], str]
19
- Documents = Callable[[], Iterable[Document]] | Iterable[Document]
20
17
 
21
18
 
22
19
  def create_rag_from_directory(
@@ -30,86 +27,87 @@ def create_rag_from_directory(
30
27
  overlap: int = RAG_OVERLAP,
31
28
  max_result_count: int = RAG_MAX_RESULT_COUNT,
32
29
  ):
33
- return create_rag(
34
- tool_name=tool_name,
35
- tool_description=tool_description,
36
- documents=get_rag_documents(os.path.expanduser(document_dir_path)),
37
- model=model,
38
- vector_db_path=vector_db_path,
39
- vector_db_collection=vector_db_collection,
40
- reset_db=get_rag_reset_db(
41
- document_dir_path=os.path.expanduser(document_dir_path),
42
- vector_db_path=os.path.expanduser(vector_db_path),
43
- ),
44
- chunk_size=chunk_size,
45
- overlap=overlap,
46
- max_result_count=max_result_count,
47
- )
48
-
49
-
50
- def create_rag(
51
- tool_name: str,
52
- tool_description: str,
53
- documents: Documents = [],
54
- model: str = RAG_EMBEDDING_MODEL,
55
- vector_db_path: str = "./chroma",
56
- vector_db_collection: str = "documents",
57
- reset_db: Callable[[], bool] | bool = False,
58
- chunk_size: int = RAG_CHUNK_SIZE,
59
- overlap: int = RAG_OVERLAP,
60
- max_result_count: int = RAG_MAX_RESULT_COUNT,
61
- ) -> Callable[[str], str]:
62
30
  async def retrieve(query: str) -> str:
63
- import chromadb
31
+ from chromadb import PersistentClient
64
32
  from chromadb.config import Settings
65
33
 
66
- is_db_exist = os.path.isdir(vector_db_path)
67
- client = chromadb.PersistentClient(
34
+ client = PersistentClient(
68
35
  path=vector_db_path, settings=Settings(allow_reset=True)
69
36
  )
70
- should_reset_db = (
71
- await run_async(reset_db()) if callable(reset_db) else reset_db
72
- )
73
- if (not is_db_exist) or should_reset_db:
74
- client.reset()
75
- collection = client.get_or_create_collection(vector_db_collection)
76
- chunk_index = 0
77
- print(stylize_faint("Scanning documents"), file=sys.stderr)
78
- docs = await run_async(documents()) if callable(documents) else documents
79
- for document in docs:
80
- if callable(document):
81
- try:
82
- document = await run_async(document())
83
- except Exception as error:
84
- print(stylize_error(f"Error: {error}"), file=sys.stderr)
85
- continue
86
- for i in range(0, len(document), chunk_size - overlap):
87
- chunk = document[i : i + chunk_size]
88
- if len(chunk) > 0:
89
- print(
90
- stylize_faint(f"Vectorize chunk {chunk_index}"),
91
- file=sys.stderr,
92
- )
93
- response = await litellm.aembedding(model=model, input=[chunk])
94
- vector = response["data"][0]["embedding"]
95
- print(
96
- stylize_faint(f"Adding chunk {chunk_index} to db"),
97
- file=sys.stderr,
98
- )
99
- collection.upsert(
100
- ids=[f"id{chunk_index}"],
101
- embeddings=[vector],
102
- documents=[chunk],
103
- )
104
- chunk_index += 1
105
37
  collection = client.get_or_create_collection(vector_db_collection)
106
- # Generate embedding for the query
107
- print(stylize_faint("Vectorize query"), file=sys.stderr)
38
+
39
+ # Track file changes using a hash-based approach
40
+ hash_file_path = os.path.join(vector_db_path, "file_hashes.json")
41
+ previous_hashes = _load_hashes(hash_file_path)
42
+ current_hashes = {}
43
+
44
+ updated_files = []
45
+
46
+ for root, _, files in os.walk(document_dir_path):
47
+ for file in files:
48
+ file_path = os.path.join(root, file)
49
+ file_hash = _compute_file_hash(file_path)
50
+ relative_path = os.path.relpath(file_path, document_dir_path)
51
+ current_hashes[relative_path] = file_hash
52
+
53
+ if previous_hashes.get(relative_path) != file_hash:
54
+ updated_files.append(file_path)
55
+
56
+ if updated_files:
57
+ print(
58
+ stylize_faint(f"Updating {len(updated_files)} changed files"),
59
+ file=sys.stderr,
60
+ )
61
+
62
+ for file_path in updated_files:
63
+ try:
64
+ relative_path = os.path.relpath(file_path, document_dir_path)
65
+ collection.delete(where={"file_path": relative_path})
66
+ content = _read_file_content(file_path)
67
+ file_id = ulid.new().str
68
+ for i in range(0, len(content), chunk_size - overlap):
69
+ chunk = content[i : i + chunk_size]
70
+ if chunk:
71
+ chunk_id = ulid.new().str
72
+ print(
73
+ stylize_faint(
74
+ f"Vectorizing {relative_path} chunk {chunk_id}"
75
+ ),
76
+ file=sys.stderr,
77
+ )
78
+ response = await litellm.aembedding(
79
+ model=model, input=[chunk]
80
+ )
81
+ vector = response["data"][0]["embedding"]
82
+ collection.upsert(
83
+ ids=[chunk_id],
84
+ embeddings=[vector],
85
+ documents=[chunk],
86
+ metadatas={
87
+ "file_path": relative_path,
88
+ "file_id": file_id,
89
+ },
90
+ )
91
+ except Exception as e:
92
+ print(
93
+ stylize_error(f"Error processing {file_path}: {e}"),
94
+ file=sys.stderr,
95
+ )
96
+
97
+ _save_hashes(hash_file_path, current_hashes)
98
+ else:
99
+ print(
100
+ stylize_faint("No changes detected. Skipping database update."),
101
+ file=sys.stderr,
102
+ )
103
+
104
+ print(stylize_faint("Vectorizing query"), file=sys.stderr)
108
105
  query_response = await litellm.aembedding(model=model, input=[query])
109
- print(stylize_faint("Search documents"), file=sys.stderr)
110
- # Search for the top_k most similar documents
106
+ query_vector = query_response["data"][0]["embedding"]
107
+
108
+ print(stylize_faint("Searching documents"), file=sys.stderr)
111
109
  results = collection.query(
112
- query_embeddings=query_response["data"][0]["embedding"],
110
+ query_embeddings=query_vector,
113
111
  n_results=max_result_count,
114
112
  )
115
113
  return json.dumps(results)
@@ -119,71 +117,36 @@ def create_rag(
119
117
  return retrieve
120
118
 
121
119
 
122
- def get_rag_documents(document_dir_path: str) -> Callable[[], list[Callable[[], str]]]:
123
- def get_documents() -> list[Callable[[], str]]:
124
- # Walk through the directory
125
- readers = []
126
- for root, _, files in os.walk(document_dir_path):
127
- for file in files:
128
- file_path = os.path.join(root, file)
129
- if file_path.lower().endswith(".pdf"):
130
- readers.append(_get_pdf_reader(file_path))
131
- continue
132
- readers.append(_get_text_reader(file_path))
133
- return readers
134
-
135
- return get_documents
136
-
137
-
138
- def _get_text_reader(file_path: str):
139
- def read():
140
- print(stylize_faint(f"Start reading {file_path}"), file=sys.stderr)
141
- content = read_file(file_path)
142
- print(stylize_faint(f"Complete reading {file_path}"), file=sys.stderr)
143
- return content
144
-
145
- return read
146
-
147
-
148
- def _get_pdf_reader(file_path):
149
- def read():
150
- import pdfplumber
151
-
152
- print(stylize_faint(f"Start reading {file_path}"), file=sys.stderr)
153
- contents = []
154
- with pdfplumber.open(file_path) as pdf:
155
- for page in pdf.pages:
156
- contents.append(page.extract_text())
157
- print(stylize_faint(f"Complete reading {file_path}"), file=sys.stderr)
158
- return "\n".join(contents)
159
-
160
- return read
161
-
162
-
163
- def get_rag_reset_db(
164
- document_dir_path: str, vector_db_path: str = "./chroma"
165
- ) -> Callable[[], bool]:
166
- def should_reset_db() -> bool:
167
- document_exist = os.path.isdir(document_dir_path)
168
- if not document_exist:
169
- raise ValueError(f"Document directory not exists: {document_dir_path}")
170
- vector_db_exist = os.path.isdir(vector_db_path)
171
- if not vector_db_exist:
172
- return True
173
- document_mtime = _get_most_recent_mtime(document_dir_path)
174
- vector_db_mtime = _get_most_recent_mtime(vector_db_path)
175
- return document_mtime > vector_db_mtime
176
-
177
- return should_reset_db
178
-
179
-
180
- def _get_most_recent_mtime(directory):
181
- most_recent_mtime = 0
182
- for root, dirs, files in os.walk(directory):
183
- # Check mtime for directories
184
- for name in dirs + files:
185
- file_path = os.path.join(root, name)
186
- mtime = os.path.getmtime(file_path)
187
- if mtime > most_recent_mtime:
188
- most_recent_mtime = mtime
189
- return most_recent_mtime
120
+ def _compute_file_hash(file_path: str) -> str:
121
+ hash_md5 = hashlib.md5()
122
+ with open(file_path, "rb") as f:
123
+ for chunk in iter(lambda: f.read(4096), b""):
124
+ hash_md5.update(chunk)
125
+ return hash_md5.hexdigest()
126
+
127
+
128
+ def _read_file_content(file_path: str) -> str:
129
+ if file_path.lower().endswith(".pdf"):
130
+ return _read_pdf(file_path)
131
+ return read_file(file_path)
132
+
133
+
134
+ def _read_pdf(file_path: str) -> str:
135
+ import pdfplumber
136
+
137
+ with pdfplumber.open(file_path) as pdf:
138
+ return "\n".join(
139
+ page.extract_text() for page in pdf.pages if page.extract_text()
140
+ )
141
+
142
+
143
+ def _load_hashes(file_path: str) -> dict:
144
+ if os.path.exists(file_path):
145
+ with open(file_path, "r") as f:
146
+ return json.load(f)
147
+ return {}
148
+
149
+
150
+ def _save_hashes(file_path: str, hashes: dict):
151
+ with open(file_path, "w") as f:
152
+ json.dump(hashes, f)
@@ -2,7 +2,7 @@ import json
2
2
  from typing import Annotated
3
3
 
4
4
 
5
- def open_web_page(url: str) -> str:
5
+ def open_web_route(url: str) -> str:
6
6
  """Get content from a web page."""
7
7
  import requests
8
8
 
@@ -49,6 +49,7 @@ scaffold_fastapp = Scaffolder(
49
49
  transform_content=[
50
50
  # Common transformation (project_dir/app_dir/**/*)
51
51
  ContentTransformer(
52
+ name="transform-app-dir",
52
53
  match=is_in_project_app_dir,
53
54
  transform={
54
55
  "My App Name": "{ctx.input.app.title()}",
@@ -60,6 +61,7 @@ scaffold_fastapp = Scaffolder(
60
61
  ),
61
62
  # Register fastapp's tasks to project's zrb_init (project_dir/zrb_init.py)
62
63
  ContentTransformer(
64
+ name="trasnform-zrb-init",
63
65
  match=is_project_zrb_init_file,
64
66
  transform=update_project_zrb_init_file,
65
67
  ),
@@ -9,9 +9,12 @@ MICROSERVICES_ENV_VARS = {
9
9
  "MY_APP_NAME_MODE": "microservices",
10
10
  "MY_APP_NAME_AUTH_BASE_URL": "http://localhost:3002",
11
11
  }
12
- MONOLITH_ENV_VARS = {"MY_APP_NAME_MODE": "monolith"}
12
+ MONOLITH_ENV_VARS = {
13
+ "MY_APP_NAME_MODE": "monolith",
14
+ "MY_APP_NAME_MODULES": "",
15
+ }
13
16
 
14
17
  if platform.system() == "Windows":
15
18
  ACTIVATE_VENV_SCRIPT = "Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser; . .venv\\Scripts\\Activate" # noqa
16
19
  else:
17
- ACTIVATE_VENV_SCRIPT = "source .venv/bin/activate"
20
+ ACTIVATE_VENV_SCRIPT = ". .venv/bin/activate"
@@ -1,19 +1,21 @@
1
1
  import os
2
2
 
3
- from my_app_name._zrb.config import APP_DIR
3
+ from my_app_name._zrb.config import ACTIVATE_VENV_SCRIPT, APP_DIR
4
4
  from my_app_name._zrb.entity.add_entity_util import (
5
5
  is_in_app_schema_dir,
6
6
  is_in_module_entity_dir,
7
- is_module_any_client_file,
8
7
  is_module_api_client_file,
8
+ is_module_client_file,
9
9
  is_module_direct_client_file,
10
+ is_module_gateway_subroute_file,
10
11
  is_module_migration_metadata_file,
11
12
  is_module_route_file,
12
- update_any_client,
13
- update_api_client,
14
- update_direct_client,
15
- update_migration_metadata,
16
- update_route,
13
+ update_api_client_file,
14
+ update_client_file,
15
+ update_direct_client_file,
16
+ update_gateway_subroute_file,
17
+ update_migration_metadata_file,
18
+ update_route_file,
17
19
  )
18
20
  from my_app_name._zrb.format_task import format_my_app_name_code
19
21
  from my_app_name._zrb.group import app_create_group
@@ -23,9 +25,25 @@ from my_app_name._zrb.input import (
23
25
  new_entity_input,
24
26
  plural_entity_input,
25
27
  )
26
- from my_app_name._zrb.util import get_existing_module_names, get_existing_schema_names
28
+ from my_app_name._zrb.util import (
29
+ cd_module_script,
30
+ get_existing_module_names,
31
+ get_existing_schema_names,
32
+ set_create_migration_db_url_env,
33
+ set_env,
34
+ )
35
+ from my_app_name._zrb.venv_task import prepare_venv
27
36
 
28
- from zrb import AnyContext, ContentTransformer, Scaffolder, Task, make_task
37
+ from zrb import (
38
+ AnyContext,
39
+ Cmd,
40
+ CmdTask,
41
+ ContentTransformer,
42
+ EnvFile,
43
+ Scaffolder,
44
+ Task,
45
+ make_task,
46
+ )
29
47
  from zrb.util.string.conversion import to_snake_case
30
48
 
31
49
 
@@ -66,6 +84,7 @@ scaffold_my_app_name_entity = Scaffolder(
66
84
  transform_content=[
67
85
  # Schema tranformation (my_app_name/schema/snake_entity_name)
68
86
  ContentTransformer(
87
+ name="transform-schema-file",
69
88
  match=is_in_app_schema_dir,
70
89
  transform={
71
90
  "MyEntity": "{to_pascal_case(ctx.input.entity)}",
@@ -75,6 +94,7 @@ scaffold_my_app_name_entity = Scaffolder(
75
94
  # Common module's entity transformation
76
95
  # (my_app_name/module/snake_module_name/service/snake_entity_name)
77
96
  ContentTransformer(
97
+ name="transform-module-entity-dir",
78
98
  match=is_in_module_entity_dir,
79
99
  transform={
80
100
  "my_module": "{to_snake_case(ctx.input.module)}",
@@ -87,40 +107,80 @@ scaffold_my_app_name_entity = Scaffolder(
87
107
  # Add entity to migration metadata
88
108
  # (my_app_name/module/snake_module_name/migration_metadata.py)
89
109
  ContentTransformer(
110
+ name="transform-module-migration-metadata",
90
111
  match=is_module_migration_metadata_file,
91
- transform=update_migration_metadata,
112
+ transform=update_migration_metadata_file,
92
113
  ),
93
- # Update API Client (my_app_name/module/snake_module_name/client/api_client.py)
114
+ # Update API Client
115
+ # (my_app_name/module/snake_module_name/client/snake_module_name_api_client.py)
94
116
  ContentTransformer(
117
+ name="transform-module-api-client",
95
118
  match=is_module_api_client_file,
96
- transform=update_api_client,
119
+ transform=update_api_client_file,
97
120
  ),
98
- # Update Direct Client (my_app_name/module/snake_module_name/client/direct_client.py)
121
+ # Update Direct Client
122
+ # (my_app_name/module/snake_module_name/client/snake_module_name_direct_client.py)
99
123
  ContentTransformer(
124
+ name="transform-module-direct-client",
100
125
  match=is_module_direct_client_file,
101
- transform=update_direct_client,
126
+ transform=update_direct_client_file,
102
127
  ),
103
- # Update Any Client (my_app_name/module/snake_module_name/client/any_client.py)
128
+ # Update Client
129
+ # (my_app_name/module/snake_module_name/client/snake_module_name_client.py)
104
130
  ContentTransformer(
105
- match=is_module_any_client_file,
106
- transform=update_any_client,
131
+ name="transform-module-any-client",
132
+ match=is_module_client_file,
133
+ transform=update_client_file,
107
134
  ),
108
135
  # Update module route (my_app_name/module/route.py)
109
136
  ContentTransformer(
137
+ name="transform-module-route",
110
138
  match=is_module_route_file,
111
- transform=update_route,
139
+ transform=update_route_file,
140
+ ),
141
+ # Update module gateway subroute
142
+ # (my_app_name/module/gateway/subroute/snake_module_name.py)
143
+ ContentTransformer(
144
+ name="transform-module-gateway-subroute",
145
+ match=is_module_gateway_subroute_file,
146
+ transform=update_gateway_subroute_file,
112
147
  ),
113
- # TODO: Register gateway route
114
148
  ],
115
149
  retries=0,
116
150
  upstream=validate_create_my_app_name_entity,
117
151
  )
118
152
 
153
+ create_my_app_name_entity_migration = CmdTask(
154
+ name="create-my-app-name-entity-migration",
155
+ input=[
156
+ existing_module_input,
157
+ new_entity_input,
158
+ ],
159
+ env=EnvFile(path=os.path.join(APP_DIR, "template.env")),
160
+ cwd=APP_DIR,
161
+ cmd=[
162
+ ACTIVATE_VENV_SCRIPT,
163
+ Cmd(lambda ctx: set_create_migration_db_url_env(ctx.input.module)),
164
+ Cmd(lambda ctx: set_env("MY_APP_NAME_MODULES", ctx.input.module)),
165
+ Cmd(lambda ctx: cd_module_script(ctx.input.module)),
166
+ "alembic upgrade head",
167
+ Cmd(
168
+ 'alembic revision --autogenerate -m "create_{to_snake_case(ctx.input.entity)}_table"', # noqa
169
+ ),
170
+ ],
171
+ render_cmd=False,
172
+ retries=0,
173
+ upstream=[
174
+ prepare_venv,
175
+ scaffold_my_app_name_entity,
176
+ ],
177
+ )
178
+
119
179
  add_my_app_name_entity = app_create_group.add_task(
120
180
  Task(
121
181
  name="add-my-app-name-entity",
122
182
  description="🏗️ Create new entity on a module",
123
- upstream=scaffold_my_app_name_entity,
183
+ upstream=create_my_app_name_entity_migration,
124
184
  successor=format_my_app_name_code,
125
185
  retries=0,
126
186
  ),