zrb 1.0.0a21__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.
- zrb/__init__.py +2 -1
- zrb/__main__.py +3 -3
- zrb/builtin/__init__.py +3 -0
- zrb/builtin/group.py +1 -0
- zrb/builtin/llm/llm_chat.py +5 -3
- zrb/builtin/llm/tool/cli.py +1 -1
- zrb/builtin/llm/tool/rag.py +108 -145
- zrb/builtin/llm/tool/web.py +1 -1
- zrb/builtin/project/add/fastapp/fastapp_task.py +2 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/config.py +5 -2
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/add_entity_task.py +80 -20
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/add_entity_util.py +150 -42
- 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
- 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
- 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
- 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
- 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
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/template/app_template/schema/my_entity.py +16 -6
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/template/client_method.py +57 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/template/gateway_subroute.py +74 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/format_task.py +1 -1
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/input.py +13 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/add_module_task.py +23 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/add_module_util.py +42 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/gateway/subroute/my_module.py +7 -0
- 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
- 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
- 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
- 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
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/my_module/route.py +11 -11
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/template/module_task_definition.py +2 -2
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/task.py +8 -8
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/util.py +47 -20
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/common/app_factory.py +29 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/common/base_db_repository.py +230 -102
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/common/base_service.py +236 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/common/{db_engine.py → db_engine_factory.py} +1 -1
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/common/error.py +12 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/common/logger_factory.py +10 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/common/parser_factory.py +7 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/common/util/app.py +47 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/common/util/parser.py +105 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/common/util/user_agent.py +58 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/common/util/view.py +37 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/config.py +37 -1
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/main.py +1 -1
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/client/auth_api_client.py +16 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/client/auth_client.py +169 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/client/auth_client_factory.py +9 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/client/auth_direct_client.py +15 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/migration/versions/3093c7336477_add_auth_tables.py +160 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/migration_metadata.py +18 -1
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/route.py +7 -3
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/permission/permission_service.py +117 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/permission/permission_service_factory.py +11 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/permission/repository/permission_db_repository.py +26 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/permission/repository/permission_repository.py +61 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/permission/repository/permission_repository_factory.py +13 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/role/repository/role_db_repository.py +89 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/role/repository/role_repository.py +67 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/role/repository/role_repository_factory.py +13 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/role/role_service.py +137 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/role/role_service_factory.py +7 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/repository/user_db_repository.py +179 -12
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/repository/user_repository.py +67 -17
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/repository/user_repository_factory.py +2 -2
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/user_service.py +127 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/user_service_factory.py +7 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/route.py +43 -14
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/subroute/auth.py +200 -30
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/util/view.py +74 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/content/error.html +6 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/content/homepage.html +6 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/images/android-chrome-192x192.png +0 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/images/android-chrome-512x512.png +0 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/images/favicon-32x32.png +0 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.amber.min.css +4 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.blue.min.css +4 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.cyan.min.css +4 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.fuchsia.min.css +4 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.green.min.css +4 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.grey.min.css +4 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.indigo.min.css +4 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.jade.min.css +4 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.lime.min.css +4 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.min.css +4 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.orange.min.css +4 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.pink.min.css +4 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.pumpkin.min.css +4 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.purple.min.css +4 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.red.min.css +4 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.sand.min.css +4 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.slate.min.css +4 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.violet.min.css +4 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.yellow.min.css +4 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.zinc.min.css +4 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/template/default.html +34 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/requirements.txt +1 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/schema/permission.py +17 -5
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/schema/role.py +78 -4
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/schema/session.py +48 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/schema/user.py +69 -5
- zrb/builtin/python.py +1 -1
- zrb/builtin/random.py +61 -0
- zrb/cmd/cmd_val.py +6 -5
- zrb/config.py +14 -1
- zrb/content_transformer/any_content_transformer.py +7 -0
- zrb/content_transformer/content_transformer.py +6 -0
- zrb/runner/cli.py +14 -7
- zrb/runner/web_app.py +28 -280
- zrb/runner/web_config/config.py +91 -0
- zrb/runner/web_config/config_factory.py +26 -0
- zrb/runner/web_route/docs_route.py +17 -0
- zrb/runner/web_route/error_page/serve_default_404.py +28 -0
- zrb/runner/{web_controller/error_page/controller.py → web_route/error_page/show_error_page.py} +4 -3
- zrb/runner/{web_controller → web_route}/error_page/view.html +5 -0
- zrb/runner/web_route/home_page/home_page_route.py +51 -0
- zrb/runner/web_route/login_api_route.py +31 -0
- zrb/runner/web_route/login_page/login_page_route.py +39 -0
- zrb/runner/web_route/logout_api_route.py +18 -0
- zrb/runner/web_route/logout_page/logout_page_route.py +40 -0
- zrb/runner/{web_controller/group_info_page/controller.py → web_route/node_page/group/show_group_page.py} +3 -3
- zrb/runner/web_route/node_page/node_page_route.py +50 -0
- zrb/runner/{web_controller/session_page/controller.py → web_route/node_page/task/show_task_page.py} +3 -3
- zrb/runner/web_route/refresh_token_api_route.py +38 -0
- zrb/runner/{web_controller/static → web_route/static/resources}/session/current-session.js +5 -2
- zrb/runner/{web_controller/static → web_route/static/resources}/session/event.js +5 -2
- zrb/runner/web_route/static/static_route.py +44 -0
- zrb/runner/web_route/task_input_api_route.py +47 -0
- zrb/runner/web_route/task_session_api_route.py +147 -0
- zrb/runner/web_schema/session.py +5 -0
- zrb/runner/web_schema/token.py +11 -0
- zrb/runner/web_schema/user.py +32 -0
- zrb/runner/web_util/cookie.py +29 -0
- zrb/runner/{web_util.py → web_util/html.py} +1 -23
- zrb/runner/web_util/token.py +72 -0
- zrb/runner/web_util/user.py +63 -0
- zrb/session/session.py +6 -4
- zrb/session_state_logger/{default_session_state_logger.py → session_state_logger_factory.py} +1 -1
- zrb/task/base_task.py +56 -8
- zrb/task/base_trigger.py +2 -0
- zrb/task/cmd_task.py +9 -5
- zrb/task/http_check.py +2 -0
- zrb/task/llm_task.py +184 -71
- zrb/task/make_task.py +2 -0
- zrb/task/rsync_task.py +2 -0
- zrb/task/scaffolder.py +8 -5
- zrb/task/scheduler.py +2 -0
- zrb/task/tcp_check.py +2 -0
- zrb/task_status/task_status.py +4 -3
- zrb/util/cmd/command.py +1 -0
- zrb/util/file.py +7 -1
- zrb/util/llm/tool.py +3 -7
- {zrb-1.0.0a21.dist-info → zrb-1.0.0b3.dist-info}/METADATA +2 -1
- zrb-1.0.0b3.dist-info/RECORD +307 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/template/any_client_method.py +0 -27
- 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
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/my_module/client/api_client.py +0 -6
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/my_module/client/direct_client.py +0 -6
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/my_module/client/factory.py +0 -9
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/common/app.py +0 -20
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/common/base_usecase.py +0 -245
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/client/any_client.py +0 -33
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/client/api_client.py +0 -7
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/client/direct_client.py +0 -6
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/client/factory.py +0 -9
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/migration/versions/3093c7336477_add_user_table.py +0 -37
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/user_usecase.py +0 -53
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/user_usecase_factory.py +0 -6
- zrb/runner/web_config.py +0 -274
- zrb/runner/web_controller/home_page/controller.py +0 -33
- zrb/runner/web_controller/login_page/controller.py +0 -25
- zrb/runner/web_controller/logout_page/controller.py +0 -26
- zrb-1.0.0a21.dist-info/RECORD +0 -244
- /zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/column/{create_column_task.py → add_column_task.py} +0 -0
- /zrb/{runner/web_controller → builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/permission}/__init__.py +0 -0
- /zrb/{runner/web_controller/group_info_page → builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/role}/__init__.py +0 -0
- /zrb/runner/{web_controller/home_page → web_route}/__init__.py +0 -0
- /zrb/runner/{web_controller/session_page → web_route/home_page}/__init__.py +0 -0
- /zrb/runner/{web_controller → web_route}/home_page/view.html +0 -0
- /zrb/runner/{web_controller → web_route}/login_page/view.html +0 -0
- /zrb/runner/{web_controller → web_route}/logout_page/view.html +0 -0
- /zrb/runner/{web_controller/group_info_page → web_route/node_page/group}/view.html +0 -0
- /zrb/runner/{web_controller/session_page → web_route/node_page/task}/partial/input.html +0 -0
- /zrb/runner/{web_controller/session_page → web_route/node_page/task}/view.html +0 -0
- /zrb/runner/{refresh-token.template.js → web_route/static/refresh-token.template.js} +0 -0
- /zrb/runner/{web_controller/static → web_route/static/resources}/common.css +0 -0
- /zrb/runner/{web_controller/static → web_route/static/resources}/favicon-32x32.png +0 -0
- /zrb/runner/{web_controller/static → web_route/static/resources}/login/event.js +0 -0
- /zrb/runner/{web_controller/static → web_route/static/resources}/logout/event.js +0 -0
- /zrb/runner/{web_controller/static → web_route/static/resources}/pico.min.css +0 -0
- /zrb/runner/{web_controller/static → web_route/static/resources}/session/common-util.js +0 -0
- /zrb/runner/{web_controller/static → web_route/static/resources}/session/past-session.js +0 -0
- {zrb-1.0.0a21.dist-info → zrb-1.0.0b3.dist-info}/WHEEL +0 -0
- {zrb-1.0.0a21.dist-info → zrb-1.0.0b3.dist-info}/entry_points.txt +0 -0
zrb/task/llm_task.py
CHANGED
@@ -17,6 +17,7 @@ from zrb.util.attr import get_str_attr
|
|
17
17
|
from zrb.util.cli.style import stylize_faint
|
18
18
|
from zrb.util.file import read_file, write_file
|
19
19
|
from zrb.util.llm.tool import callable_to_tool_schema
|
20
|
+
from zrb.util.run import run_async
|
20
21
|
|
21
22
|
ListOfDict = list[dict[str, Any]]
|
22
23
|
|
@@ -24,7 +25,6 @@ ListOfDict = list[dict[str, Any]]
|
|
24
25
|
class AdditionalTool(BaseModel):
|
25
26
|
fn: Callable
|
26
27
|
name: str | None
|
27
|
-
description: str | None
|
28
28
|
|
29
29
|
|
30
30
|
def scratchpad(thought: str) -> str:
|
@@ -32,6 +32,11 @@ def scratchpad(thought: str) -> str:
|
|
32
32
|
return thought
|
33
33
|
|
34
34
|
|
35
|
+
def end_conversation(final_answer: str) -> str:
|
36
|
+
"""End conversation with a final answer containing all necessary information"""
|
37
|
+
return final_answer
|
38
|
+
|
39
|
+
|
35
40
|
class LLMTask(BaseTask):
|
36
41
|
def __init__(
|
37
42
|
self,
|
@@ -47,9 +52,7 @@ class LLMTask(BaseTask):
|
|
47
52
|
system_prompt: StrAttr | None = LLM_SYSTEM_PROMPT,
|
48
53
|
render_system_prompt: bool = True,
|
49
54
|
message: StrAttr | None = None,
|
50
|
-
tools:
|
51
|
-
dict[str, Callable] | Callable[[AnySharedContext], dict[str, Callable]]
|
52
|
-
) = {},
|
55
|
+
tools: list[Callable] | Callable[[AnySharedContext], list[Callable]] = [],
|
53
56
|
history: ListOfDict | Callable[[AnySharedContext], ListOfDict] = [],
|
54
57
|
history_file: StrAttr | None = None,
|
55
58
|
render_history_file: bool = True,
|
@@ -67,6 +70,7 @@ class LLMTask(BaseTask):
|
|
67
70
|
monitor_readiness: bool = False,
|
68
71
|
upstream: list[AnyTask] | AnyTask | None = None,
|
69
72
|
fallback: list[AnyTask] | AnyTask | None = None,
|
73
|
+
successor: list[AnyTask] | AnyTask | None = None,
|
70
74
|
):
|
71
75
|
super().__init__(
|
72
76
|
name=name,
|
@@ -87,6 +91,7 @@ class LLMTask(BaseTask):
|
|
87
91
|
monitor_readiness=monitor_readiness,
|
88
92
|
upstream=upstream,
|
89
93
|
fallback=fallback,
|
94
|
+
successor=successor,
|
90
95
|
)
|
91
96
|
self._model = model
|
92
97
|
self._render_model = render_model
|
@@ -98,81 +103,156 @@ class LLMTask(BaseTask):
|
|
98
103
|
self._history = history
|
99
104
|
self._history_file = history_file
|
100
105
|
self._render_history_file = render_history_file
|
101
|
-
self._additional_tools: list[AdditionalTool] = []
|
102
106
|
|
103
|
-
def add_tool(
|
104
|
-
self
|
105
|
-
):
|
106
|
-
self._additional_tools.append(
|
107
|
-
AdditionalTool(fn=tool, name=name, description=description)
|
108
|
-
)
|
107
|
+
def add_tool(self, tool: Callable):
|
108
|
+
self._tools.append(tool)
|
109
109
|
|
110
110
|
async def _exec_action(self, ctx: AnyContext) -> Any:
|
111
|
-
|
111
|
+
import litellm
|
112
|
+
from litellm.utils import supports_function_calling
|
112
113
|
|
114
|
+
user_message = {"role": "user", "content": self._get_message(ctx)}
|
115
|
+
ctx.print(stylize_faint(f"{user_message}"))
|
113
116
|
model = self._get_model(ctx)
|
114
117
|
try:
|
115
|
-
|
118
|
+
is_function_call_supported = supports_function_calling(model=model)
|
116
119
|
except Exception:
|
117
|
-
|
118
|
-
|
120
|
+
is_function_call_supported = False
|
121
|
+
litellm.add_function_to_prompt = True
|
122
|
+
if not is_function_call_supported:
|
123
|
+
ctx.log_warning(f"Model {model} doesn't support function call")
|
124
|
+
available_tools = self._get_available_tools(
|
125
|
+
ctx, include_end_conversation=not is_function_call_supported
|
126
|
+
)
|
127
|
+
model_kwargs = self._get_model_kwargs(ctx, available_tools)
|
119
128
|
ctx.log_debug("MODEL KWARGS", model_kwargs)
|
120
129
|
system_prompt = self._get_system_prompt(ctx)
|
121
130
|
ctx.log_debug("SYSTEM PROMPT", system_prompt)
|
122
131
|
history = self._get_history(ctx)
|
123
132
|
ctx.log_debug("HISTORY PROMPT", history)
|
124
|
-
|
125
|
-
ctx.print(stylize_faint(f"{user_message}"))
|
126
|
-
messages = history + [user_message]
|
127
|
-
available_tools = self._get_tools(ctx)
|
128
|
-
available_tools["scratchpad"] = scratchpad
|
129
|
-
if allow_function_call:
|
130
|
-
tool_schema = [
|
131
|
-
callable_to_tool_schema(tool, name)
|
132
|
-
for name, tool in available_tools.items()
|
133
|
-
]
|
134
|
-
for additional_tool in self._additional_tools:
|
135
|
-
fn = additional_tool.fn
|
136
|
-
tool_name = additional_tool.name or fn.__name__
|
137
|
-
tool_description = additional_tool.description
|
138
|
-
available_tools[tool_name] = additional_tool.fn
|
139
|
-
tool_schema.append(
|
140
|
-
callable_to_tool_schema(
|
141
|
-
fn, name=tool_name, description=tool_description
|
142
|
-
)
|
143
|
-
)
|
144
|
-
model_kwargs["tools"] = tool_schema
|
145
|
-
ctx.log_debug("TOOL SCHEMA", tool_schema)
|
133
|
+
conversations = history + [user_message]
|
146
134
|
history_file = self._get_history_file(ctx)
|
147
135
|
while True:
|
148
|
-
|
149
|
-
model
|
150
|
-
|
151
|
-
|
136
|
+
llm_response = await self._get_llm_response(
|
137
|
+
model, system_prompt, conversations, model_kwargs
|
138
|
+
)
|
139
|
+
llm_response_dict = llm_response.to_dict()
|
140
|
+
ctx.print(stylize_faint(f"{llm_response_dict}"))
|
141
|
+
conversations.append(llm_response_dict)
|
142
|
+
ctx.log_debug("RESPONSE MESSAGE", llm_response)
|
143
|
+
if is_function_call_supported:
|
144
|
+
if not llm_response.tool_calls:
|
145
|
+
# No tool call, end conversation
|
146
|
+
self._save_conversation(history_file, conversations)
|
147
|
+
return llm_response.content
|
148
|
+
await self._handle_tool_calls(
|
149
|
+
ctx, available_tools, conversations, llm_response
|
150
|
+
)
|
151
|
+
if not is_function_call_supported:
|
152
|
+
try:
|
153
|
+
json_payload = json.loads(llm_response.content)
|
154
|
+
function_name = _get_fallback_function_name(json_payload)
|
155
|
+
function_kwargs = _get_fallback_function_kwargs(json_payload)
|
156
|
+
tool_execution_message = (
|
157
|
+
await self._create_fallback_tool_exec_message(
|
158
|
+
available_tools, function_name, function_kwargs
|
159
|
+
)
|
160
|
+
)
|
161
|
+
ctx.print(stylize_faint(f"{tool_execution_message}"))
|
162
|
+
conversations.append(tool_execution_message)
|
163
|
+
if function_name == "end_conversation":
|
164
|
+
self._save_conversation(history_file, conversations)
|
165
|
+
return function_kwargs.get("final_answer", "")
|
166
|
+
except Exception as e:
|
167
|
+
ctx.log_error(e)
|
168
|
+
tool_execution_message = self._create_exec_scratchpad_message(
|
169
|
+
f"{e}"
|
170
|
+
)
|
171
|
+
conversations.append(tool_execution_message)
|
172
|
+
|
173
|
+
async def _handle_tool_calls(
|
174
|
+
self,
|
175
|
+
ctx: AnyContext,
|
176
|
+
available_tools: dict[str, Callable],
|
177
|
+
conversations: list[dict[str, Any]],
|
178
|
+
llm_response: Any,
|
179
|
+
):
|
180
|
+
# noqa Reference: https://docs.litellm.ai/docs/completion/function_call#full-code---parallel-function-calling-with-gpt-35-turbo-1106
|
181
|
+
for tool_call in llm_response.tool_calls:
|
182
|
+
tool_execution_message = await self._create_tool_exec_message(
|
183
|
+
available_tools, tool_call
|
152
184
|
)
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
185
|
+
ctx.print(stylize_faint(f"{tool_execution_message}"))
|
186
|
+
conversations.append(tool_execution_message)
|
187
|
+
|
188
|
+
def _save_conversation(self, history_file: str, conversations: list[Any]):
|
189
|
+
if history_file != "":
|
190
|
+
write_file(history_file, json.dumps(conversations, indent=2))
|
191
|
+
|
192
|
+
async def _get_llm_response(
|
193
|
+
self,
|
194
|
+
model: str,
|
195
|
+
system_prompt: str,
|
196
|
+
conversations: list[Any],
|
197
|
+
model_kwargs: dict[str, Any],
|
198
|
+
) -> Any:
|
199
|
+
from litellm import acompletion
|
200
|
+
|
201
|
+
llm_response = await acompletion(
|
202
|
+
model=model,
|
203
|
+
messages=[{"role": "system", "content": system_prompt}] + conversations,
|
204
|
+
**model_kwargs,
|
205
|
+
)
|
206
|
+
return llm_response.choices[0].message
|
207
|
+
|
208
|
+
async def _create_tool_exec_message(
|
209
|
+
self, available_tools: dict[str, Callable], tool_call: Any
|
210
|
+
) -> dict[str, Any]:
|
211
|
+
function_name = tool_call.function.name
|
212
|
+
function_kwargs = json.loads(tool_call.function.arguments)
|
213
|
+
return {
|
214
|
+
"tool_call_id": tool_call.id,
|
215
|
+
"role": "tool",
|
216
|
+
"name": function_name,
|
217
|
+
"content": await self._get_exec_tool_result(
|
218
|
+
available_tools, function_name, function_kwargs
|
219
|
+
),
|
220
|
+
}
|
221
|
+
|
222
|
+
async def _create_fallback_tool_exec_message(
|
223
|
+
self,
|
224
|
+
available_tools: dict[str, Callable],
|
225
|
+
function_name: str,
|
226
|
+
function_kwargs: dict[str, Any],
|
227
|
+
) -> dict[str, Any]:
|
228
|
+
result = await self._get_exec_tool_result(
|
229
|
+
available_tools, function_name, function_kwargs
|
230
|
+
)
|
231
|
+
return self._create_exec_scratchpad_message(
|
232
|
+
f"Result of {function_name} call: {result}"
|
233
|
+
)
|
234
|
+
|
235
|
+
def _create_exec_scratchpad_message(self, message: str) -> dict[str, Any]:
|
236
|
+
return {
|
237
|
+
"role": "assistant",
|
238
|
+
"content": json.dumps(
|
239
|
+
{"name": "scratchpad", "arguments": {"thought": message}}
|
240
|
+
),
|
241
|
+
}
|
242
|
+
|
243
|
+
async def _get_exec_tool_result(
|
244
|
+
self,
|
245
|
+
available_tools: dict[str, Callable],
|
246
|
+
function_name: str,
|
247
|
+
function_kwargs: dict[str, Any],
|
248
|
+
) -> str:
|
249
|
+
if function_name not in available_tools:
|
250
|
+
return f"[ERROR] Invalid tool: {function_name}"
|
251
|
+
function_to_call = available_tools[function_name]
|
252
|
+
try:
|
253
|
+
return await run_async(function_to_call(**function_kwargs))
|
254
|
+
except Exception as e:
|
255
|
+
return f"[ERROR] {e}"
|
176
256
|
|
177
257
|
def _get_model(self, ctx: AnyContext) -> str:
|
178
258
|
return get_str_attr(
|
@@ -190,15 +270,29 @@ class LLMTask(BaseTask):
|
|
190
270
|
def _get_message(self, ctx: AnyContext) -> str:
|
191
271
|
return get_str_attr(ctx, self._message, "How are you?", auto_render=True)
|
192
272
|
|
193
|
-
def _get_model_kwargs(
|
273
|
+
def _get_model_kwargs(
|
274
|
+
self, ctx: AnyContext, available_tools: dict[str, Callable]
|
275
|
+
) -> dict[str, Any]:
|
276
|
+
model_kwargs = {}
|
194
277
|
if callable(self._model_kwargs):
|
195
|
-
|
196
|
-
|
278
|
+
model_kwargs = self._model_kwargs(ctx)
|
279
|
+
else:
|
280
|
+
model_kwargs = self._model_kwargs
|
281
|
+
model_kwargs["tools"] = [
|
282
|
+
callable_to_tool_schema(tool) for tool in available_tools.values()
|
283
|
+
]
|
284
|
+
return model_kwargs
|
197
285
|
|
198
|
-
def
|
199
|
-
|
200
|
-
|
201
|
-
|
286
|
+
def _get_available_tools(
|
287
|
+
self, ctx: AnyContext, include_end_conversation: bool
|
288
|
+
) -> dict[str, Callable]:
|
289
|
+
tools = {"scratchpad": scratchpad}
|
290
|
+
if include_end_conversation:
|
291
|
+
tools["end_conversation"] = end_conversation
|
292
|
+
tool_list = self._tools(ctx) if callable(self._tools) else self._tools
|
293
|
+
for tool in tool_list:
|
294
|
+
tools[tool.__name__] = tool
|
295
|
+
return tools
|
202
296
|
|
203
297
|
def _get_history(self, ctx: AnyContext) -> ListOfDict:
|
204
298
|
if callable(self._history):
|
@@ -216,3 +310,22 @@ class LLMTask(BaseTask):
|
|
216
310
|
return get_str_attr(
|
217
311
|
ctx, self._history_file, "", auto_render=self._render_history_file
|
218
312
|
)
|
313
|
+
|
314
|
+
|
315
|
+
def _get_fallback_function_name(json_payload: dict[str, Any]) -> str:
|
316
|
+
for key in ("name",):
|
317
|
+
if key in json_payload:
|
318
|
+
return json_payload[key]
|
319
|
+
raise ValueError("Function name not provided")
|
320
|
+
|
321
|
+
|
322
|
+
def _get_fallback_function_kwargs(json_payload: dict[str, Any]) -> str:
|
323
|
+
for key in (
|
324
|
+
"arguments",
|
325
|
+
"args",
|
326
|
+
"parameters",
|
327
|
+
"params",
|
328
|
+
):
|
329
|
+
if key in json_payload:
|
330
|
+
return json_payload[key]
|
331
|
+
raise ValueError("Function arguments not provided")
|
zrb/task/make_task.py
CHANGED
@@ -29,6 +29,7 @@ def make_task(
|
|
29
29
|
monitor_readiness: bool = False,
|
30
30
|
upstream: list[AnyTask] | AnyTask | None = None,
|
31
31
|
fallback: list[AnyTask] | AnyTask | None = None,
|
32
|
+
successor: list[AnyTask] | AnyTask | None = None,
|
32
33
|
group: AnyGroup | None = None,
|
33
34
|
alias: str | None = None,
|
34
35
|
) -> Callable[[Callable[[AnyContext], Any]], AnyTask]:
|
@@ -53,6 +54,7 @@ def make_task(
|
|
53
54
|
monitor_readiness=monitor_readiness,
|
54
55
|
upstream=upstream,
|
55
56
|
fallback=fallback,
|
57
|
+
successor=successor,
|
56
58
|
)
|
57
59
|
if group is not None:
|
58
60
|
return group.add_task(task, alias=alias)
|
zrb/task/rsync_task.py
CHANGED
@@ -49,6 +49,7 @@ class RsyncTask(CmdTask):
|
|
49
49
|
readiness_check: list[AnyTask] | AnyTask | None = None,
|
50
50
|
upstream: list[AnyTask] | AnyTask | None = None,
|
51
51
|
fallback: list[AnyTask] | AnyTask | None = None,
|
52
|
+
successor: list[AnyTask] | AnyTask | None = None,
|
52
53
|
):
|
53
54
|
super().__init__(
|
54
55
|
name=name,
|
@@ -80,6 +81,7 @@ class RsyncTask(CmdTask):
|
|
80
81
|
readiness_check=readiness_check,
|
81
82
|
upstream=upstream,
|
82
83
|
fallback=fallback,
|
84
|
+
successor=successor,
|
83
85
|
)
|
84
86
|
self._remote_source_path = remote_source_path
|
85
87
|
self._render_remote_source_path = render_remote_source_path
|
zrb/task/scaffolder.py
CHANGED
@@ -11,6 +11,7 @@ from zrb.input.any_input import AnyInput
|
|
11
11
|
from zrb.task.any_task import AnyTask
|
12
12
|
from zrb.task.base_task import BaseTask
|
13
13
|
from zrb.util.attr import get_str_attr
|
14
|
+
from zrb.util.cli.style import stylize_faint
|
14
15
|
|
15
16
|
TransformConfig = dict[str, str] | Callable[[AnyContext, str], str]
|
16
17
|
|
@@ -46,6 +47,7 @@ class Scaffolder(BaseTask):
|
|
46
47
|
monitor_readiness: bool = False,
|
47
48
|
upstream: list[AnyTask] | AnyTask | None = None,
|
48
49
|
fallback: list[AnyTask] | AnyTask | None = None,
|
50
|
+
successor: list[AnyTask] | AnyTask | None = None,
|
49
51
|
):
|
50
52
|
super().__init__(
|
51
53
|
name=name,
|
@@ -66,6 +68,7 @@ class Scaffolder(BaseTask):
|
|
66
68
|
monitor_readiness=monitor_readiness,
|
67
69
|
upstream=upstream,
|
68
70
|
fallback=fallback,
|
71
|
+
successor=successor,
|
69
72
|
)
|
70
73
|
self._source_path = source_path
|
71
74
|
self._render_source_path = render_source_path
|
@@ -83,13 +86,12 @@ class Scaffolder(BaseTask):
|
|
83
86
|
return get_str_attr(ctx, self._destination_path, "", auto_render=True)
|
84
87
|
|
85
88
|
def _get_content_transformers(self) -> list[AnyContentTransformer]:
|
86
|
-
if callable(self._content_transformers)
|
87
|
-
|
88
|
-
|
89
|
-
]
|
90
|
-
if isinstance(self._content_transformers, dict):
|
89
|
+
if callable(self._content_transformers) or isinstance(
|
90
|
+
self._content_transformers, dict
|
91
|
+
):
|
91
92
|
return [
|
92
93
|
ContentTransformer(
|
94
|
+
name="default-transform",
|
93
95
|
match=".*",
|
94
96
|
transform=self._content_transformers,
|
95
97
|
auto_render=self._render_content_transformers,
|
@@ -109,6 +111,7 @@ class Scaffolder(BaseTask):
|
|
109
111
|
for transformer in transformers:
|
110
112
|
if transformer.match(ctx, file_path):
|
111
113
|
try:
|
114
|
+
ctx.print(stylize_faint(f"{transformer.name}: {file_path}"))
|
112
115
|
transformer.transform_file(ctx, file_path)
|
113
116
|
except UnicodeDecodeError:
|
114
117
|
pass
|
zrb/task/scheduler.py
CHANGED
@@ -39,6 +39,7 @@ class Scheduler(BaseTrigger):
|
|
39
39
|
monitor_readiness: bool = False,
|
40
40
|
upstream: list[AnyTask] | AnyTask | None = None,
|
41
41
|
fallback: list[AnyTask] | AnyTask | None = None,
|
42
|
+
successor: list[AnyTask] | AnyTask | None = None,
|
42
43
|
):
|
43
44
|
super().__init__(
|
44
45
|
name=name,
|
@@ -61,6 +62,7 @@ class Scheduler(BaseTrigger):
|
|
61
62
|
monitor_readiness=monitor_readiness,
|
62
63
|
upstream=upstream,
|
63
64
|
fallback=fallback,
|
65
|
+
successor=successor,
|
64
66
|
)
|
65
67
|
self._cron_pattern = schedule
|
66
68
|
|
zrb/task/tcp_check.py
CHANGED
@@ -28,6 +28,7 @@ class TcpCheck(BaseTask):
|
|
28
28
|
execute_condition: bool | str | Callable[[Context], bool] = True,
|
29
29
|
upstream: list[AnyTask] | AnyTask | None = None,
|
30
30
|
fallback: list[AnyTask] | AnyTask | None = None,
|
31
|
+
successor: list[AnyTask] | AnyTask | None = None,
|
31
32
|
):
|
32
33
|
super().__init__(
|
33
34
|
name=name,
|
@@ -41,6 +42,7 @@ class TcpCheck(BaseTask):
|
|
41
42
|
retries=0,
|
42
43
|
upstream=upstream,
|
43
44
|
fallback=fallback,
|
45
|
+
successor=successor,
|
44
46
|
)
|
45
47
|
self._host = host
|
46
48
|
self._render_host = render_host
|
zrb/task_status/task_status.py
CHANGED
@@ -62,9 +62,10 @@ class TaskStatus:
|
|
62
62
|
self._history.append((TASK_PERMANENTLY_FAILED, datetime.datetime.now()))
|
63
63
|
|
64
64
|
def mark_as_terminated(self):
|
65
|
-
self._is_terminated
|
66
|
-
|
67
|
-
self.
|
65
|
+
if not self._is_terminated:
|
66
|
+
self._is_terminated = True
|
67
|
+
if not (self.is_skipped or self.is_completed or self.is_permanently_failed):
|
68
|
+
self._history.append((TASK_TERMINATED, datetime.datetime.now()))
|
68
69
|
|
69
70
|
@property
|
70
71
|
def is_started(self) -> bool:
|
zrb/util/cmd/command.py
CHANGED
zrb/util/file.py
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
import os
|
2
|
+
import re
|
2
3
|
|
3
4
|
|
4
5
|
def read_file(file_path: str, replace_map: dict[str, str] = {}) -> str:
|
@@ -14,5 +15,10 @@ def write_file(file_path: str, content: str | list[str]):
|
|
14
15
|
content = "\n".join([line for line in content if line is not None])
|
15
16
|
dir_path = os.path.dirname(file_path)
|
16
17
|
os.makedirs(dir_path, exist_ok=True)
|
18
|
+
content = re.sub(r"\n{3,}$", "\n\n", content)
|
19
|
+
# Remove trailing newlines, but keep one if it exists
|
20
|
+
content = content.rstrip("\n")
|
21
|
+
if content.endswith("\n"):
|
22
|
+
content += "\n"
|
17
23
|
with open(file_path, "w") as f:
|
18
|
-
f.write(content
|
24
|
+
f.write(content)
|
zrb/util/llm/tool.py
CHANGED
@@ -3,22 +3,18 @@ from collections.abc import Callable
|
|
3
3
|
from typing import Any, get_type_hints
|
4
4
|
|
5
5
|
|
6
|
-
def callable_to_tool_schema(
|
7
|
-
callable_obj: Callable, name: str | None = None, description: str | None = None
|
8
|
-
) -> dict[str, Any]:
|
6
|
+
def callable_to_tool_schema(callable_obj: Callable) -> dict[str, Any]:
|
9
7
|
"""
|
10
8
|
Convert a callable into a tool schema dictionary by deriving the parameter schema.
|
11
9
|
|
12
10
|
:param callable_obj: The callable object (e.g., a function).
|
13
|
-
:param name: The name to assign to the function in the schema.
|
14
|
-
:param description: A description of the function.
|
15
11
|
:return: A dictionary representing the tool schema.
|
16
12
|
"""
|
17
13
|
if not callable(callable_obj):
|
18
14
|
raise ValueError("Provided object is not callable")
|
19
15
|
# Derive name and description
|
20
|
-
name =
|
21
|
-
description =
|
16
|
+
name = callable_obj.__name__
|
17
|
+
description = (callable_obj.__doc__ or "").strip()
|
22
18
|
# Get function signature
|
23
19
|
sig = inspect.signature(callable_obj)
|
24
20
|
hints = get_type_hints(callable_obj)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: zrb
|
3
|
-
Version: 1.0.
|
3
|
+
Version: 1.0.0b3
|
4
4
|
Summary: Your Automation Powerhouse
|
5
5
|
Home-page: https://github.com/state-alchemists/zrb
|
6
6
|
License: AGPL-3.0-or-later
|
@@ -26,6 +26,7 @@ Requires-Dist: pdfplumber (>=0.11.4,<0.12.0) ; extra == "rag"
|
|
26
26
|
Requires-Dist: python-dotenv (>=1.0.1,<2.0.0)
|
27
27
|
Requires-Dist: python-jose[cryptography] (>=3.3.0,<4.0.0)
|
28
28
|
Requires-Dist: requests (>=2.32.3,<3.0.0)
|
29
|
+
Requires-Dist: ulid-py (>=1.1.0,<2.0.0)
|
29
30
|
Project-URL: Documentation, https://github.com/state-alchemists/zrb
|
30
31
|
Project-URL: Repository, https://github.com/state-alchemists/zrb
|
31
32
|
Description-Content-Type: text/markdown
|