zrb 1.21.29__py3-none-any.whl → 2.0.0a4__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.
Potentially problematic release.
This version of zrb might be problematic. Click here for more details.
- zrb/__init__.py +118 -129
- zrb/builtin/__init__.py +54 -2
- zrb/builtin/llm/chat.py +147 -0
- zrb/callback/callback.py +8 -1
- zrb/cmd/cmd_result.py +2 -1
- zrb/config/config.py +491 -280
- zrb/config/helper.py +84 -0
- zrb/config/web_auth_config.py +50 -35
- zrb/context/any_shared_context.py +13 -2
- zrb/context/context.py +31 -3
- zrb/context/print_fn.py +13 -0
- zrb/context/shared_context.py +14 -1
- zrb/input/option_input.py +30 -2
- zrb/llm/agent/__init__.py +9 -0
- zrb/llm/agent/agent.py +215 -0
- zrb/llm/agent/summarizer.py +20 -0
- zrb/llm/app/__init__.py +10 -0
- zrb/llm/app/completion.py +281 -0
- zrb/llm/app/confirmation/allow_tool.py +66 -0
- zrb/llm/app/confirmation/handler.py +178 -0
- zrb/llm/app/confirmation/replace_confirmation.py +77 -0
- zrb/llm/app/keybinding.py +34 -0
- zrb/llm/app/layout.py +117 -0
- zrb/llm/app/lexer.py +155 -0
- zrb/llm/app/redirection.py +28 -0
- zrb/llm/app/style.py +16 -0
- zrb/llm/app/ui.py +733 -0
- zrb/llm/config/__init__.py +4 -0
- zrb/llm/config/config.py +122 -0
- zrb/llm/config/limiter.py +247 -0
- zrb/llm/history_manager/__init__.py +4 -0
- zrb/llm/history_manager/any_history_manager.py +23 -0
- zrb/llm/history_manager/file_history_manager.py +91 -0
- zrb/llm/history_processor/summarizer.py +108 -0
- zrb/llm/note/__init__.py +3 -0
- zrb/llm/note/manager.py +122 -0
- zrb/llm/prompt/__init__.py +29 -0
- zrb/llm/prompt/claude_compatibility.py +92 -0
- zrb/llm/prompt/compose.py +55 -0
- zrb/llm/prompt/default.py +51 -0
- zrb/llm/prompt/markdown/mandate.md +23 -0
- zrb/llm/prompt/markdown/persona.md +3 -0
- zrb/llm/prompt/markdown/summarizer.md +21 -0
- zrb/llm/prompt/note.py +41 -0
- zrb/llm/prompt/system_context.py +46 -0
- zrb/llm/prompt/zrb.py +41 -0
- zrb/llm/skill/__init__.py +3 -0
- zrb/llm/skill/manager.py +86 -0
- zrb/llm/task/__init__.py +4 -0
- zrb/llm/task/llm_chat_task.py +316 -0
- zrb/llm/task/llm_task.py +245 -0
- zrb/llm/tool/__init__.py +39 -0
- zrb/llm/tool/bash.py +75 -0
- zrb/llm/tool/code.py +266 -0
- zrb/llm/tool/file.py +419 -0
- zrb/llm/tool/note.py +70 -0
- zrb/{builtin/llm → llm}/tool/rag.py +8 -5
- zrb/llm/tool/search/brave.py +53 -0
- zrb/llm/tool/search/searxng.py +47 -0
- zrb/llm/tool/search/serpapi.py +47 -0
- zrb/llm/tool/skill.py +19 -0
- zrb/llm/tool/sub_agent.py +70 -0
- zrb/llm/tool/web.py +97 -0
- zrb/llm/tool/zrb_task.py +66 -0
- zrb/llm/util/attachment.py +101 -0
- zrb/llm/util/prompt.py +104 -0
- zrb/llm/util/stream_response.py +178 -0
- zrb/session/any_session.py +0 -3
- zrb/session/session.py +1 -1
- zrb/task/base/context.py +25 -13
- zrb/task/base/execution.py +52 -47
- zrb/task/base/lifecycle.py +7 -4
- zrb/task/base_task.py +48 -49
- zrb/task/base_trigger.py +4 -1
- zrb/task/cmd_task.py +6 -0
- zrb/task/http_check.py +11 -5
- zrb/task/make_task.py +3 -0
- zrb/task/rsync_task.py +5 -0
- zrb/task/scaffolder.py +7 -4
- zrb/task/scheduler.py +3 -0
- zrb/task/tcp_check.py +6 -4
- zrb/util/ascii_art/art/bee.txt +17 -0
- zrb/util/ascii_art/art/cat.txt +9 -0
- zrb/util/ascii_art/art/ghost.txt +16 -0
- zrb/util/ascii_art/art/panda.txt +17 -0
- zrb/util/ascii_art/art/rose.txt +14 -0
- zrb/util/ascii_art/art/unicorn.txt +15 -0
- zrb/util/ascii_art/banner.py +92 -0
- zrb/util/cli/markdown.py +22 -2
- zrb/util/cmd/command.py +33 -10
- zrb/util/file.py +51 -32
- zrb/util/match.py +78 -0
- zrb/util/run.py +3 -3
- {zrb-1.21.29.dist-info → zrb-2.0.0a4.dist-info}/METADATA +9 -15
- {zrb-1.21.29.dist-info → zrb-2.0.0a4.dist-info}/RECORD +100 -128
- zrb/attr/__init__.py +0 -0
- zrb/builtin/llm/attachment.py +0 -40
- zrb/builtin/llm/chat_completion.py +0 -274
- zrb/builtin/llm/chat_session.py +0 -270
- zrb/builtin/llm/chat_session_cmd.py +0 -288
- zrb/builtin/llm/chat_trigger.py +0 -79
- zrb/builtin/llm/history.py +0 -71
- zrb/builtin/llm/input.py +0 -27
- zrb/builtin/llm/llm_ask.py +0 -269
- zrb/builtin/llm/previous-session.js +0 -21
- zrb/builtin/llm/tool/__init__.py +0 -0
- zrb/builtin/llm/tool/api.py +0 -75
- zrb/builtin/llm/tool/cli.py +0 -52
- zrb/builtin/llm/tool/code.py +0 -236
- zrb/builtin/llm/tool/file.py +0 -560
- zrb/builtin/llm/tool/note.py +0 -84
- zrb/builtin/llm/tool/sub_agent.py +0 -150
- zrb/builtin/llm/tool/web.py +0 -171
- zrb/builtin/project/__init__.py +0 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/__init__.py +0 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/my_module/service/__init__.py +0 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/common/__init__.py +0 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/__init__.py +0 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/__init__.py +0 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/permission/__init__.py +0 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/role/__init__.py +0 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/__init__.py +0 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/schema/__init__.py +0 -0
- zrb/builtin/project/create/__init__.py +0 -0
- zrb/builtin/shell/__init__.py +0 -0
- zrb/builtin/shell/autocomplete/__init__.py +0 -0
- zrb/callback/__init__.py +0 -0
- zrb/cmd/__init__.py +0 -0
- zrb/config/default_prompt/interactive_system_prompt.md +0 -29
- zrb/config/default_prompt/persona.md +0 -1
- zrb/config/default_prompt/summarization_prompt.md +0 -57
- zrb/config/default_prompt/system_prompt.md +0 -38
- zrb/config/llm_config.py +0 -339
- zrb/config/llm_context/config.py +0 -166
- zrb/config/llm_context/config_parser.py +0 -40
- zrb/config/llm_context/workflow.py +0 -81
- zrb/config/llm_rate_limitter.py +0 -190
- zrb/content_transformer/__init__.py +0 -0
- zrb/context/__init__.py +0 -0
- zrb/dot_dict/__init__.py +0 -0
- zrb/env/__init__.py +0 -0
- zrb/group/__init__.py +0 -0
- zrb/input/__init__.py +0 -0
- zrb/runner/__init__.py +0 -0
- zrb/runner/web_route/__init__.py +0 -0
- zrb/runner/web_route/home_page/__init__.py +0 -0
- zrb/session/__init__.py +0 -0
- zrb/session_state_log/__init__.py +0 -0
- zrb/session_state_logger/__init__.py +0 -0
- zrb/task/__init__.py +0 -0
- zrb/task/base/__init__.py +0 -0
- zrb/task/llm/__init__.py +0 -0
- zrb/task/llm/agent.py +0 -204
- zrb/task/llm/agent_runner.py +0 -152
- zrb/task/llm/config.py +0 -122
- zrb/task/llm/conversation_history.py +0 -209
- zrb/task/llm/conversation_history_model.py +0 -67
- zrb/task/llm/default_workflow/coding/workflow.md +0 -41
- zrb/task/llm/default_workflow/copywriting/workflow.md +0 -68
- zrb/task/llm/default_workflow/git/workflow.md +0 -118
- zrb/task/llm/default_workflow/golang/workflow.md +0 -128
- zrb/task/llm/default_workflow/html-css/workflow.md +0 -135
- zrb/task/llm/default_workflow/java/workflow.md +0 -146
- zrb/task/llm/default_workflow/javascript/workflow.md +0 -158
- zrb/task/llm/default_workflow/python/workflow.md +0 -160
- zrb/task/llm/default_workflow/researching/workflow.md +0 -153
- zrb/task/llm/default_workflow/rust/workflow.md +0 -162
- zrb/task/llm/default_workflow/shell/workflow.md +0 -299
- zrb/task/llm/error.py +0 -95
- zrb/task/llm/file_replacement.py +0 -206
- zrb/task/llm/file_tool_model.py +0 -57
- zrb/task/llm/history_processor.py +0 -206
- zrb/task/llm/history_summarization.py +0 -25
- zrb/task/llm/print_node.py +0 -221
- zrb/task/llm/prompt.py +0 -321
- zrb/task/llm/subagent_conversation_history.py +0 -41
- zrb/task/llm/tool_wrapper.py +0 -361
- zrb/task/llm/typing.py +0 -3
- zrb/task/llm/workflow.py +0 -76
- zrb/task/llm_task.py +0 -379
- zrb/task_status/__init__.py +0 -0
- zrb/util/__init__.py +0 -0
- zrb/util/cli/__init__.py +0 -0
- zrb/util/cmd/__init__.py +0 -0
- zrb/util/codemod/__init__.py +0 -0
- zrb/util/string/__init__.py +0 -0
- zrb/xcom/__init__.py +0 -0
- /zrb/{config/default_prompt/file_extractor_system_prompt.md → llm/prompt/markdown/file_extractor.md} +0 -0
- /zrb/{config/default_prompt/repo_extractor_system_prompt.md → llm/prompt/markdown/repo_extractor.md} +0 -0
- /zrb/{config/default_prompt/repo_summarizer_system_prompt.md → llm/prompt/markdown/repo_summarizer.md} +0 -0
- {zrb-1.21.29.dist-info → zrb-2.0.0a4.dist-info}/WHEEL +0 -0
- {zrb-1.21.29.dist-info → zrb-2.0.0a4.dist-info}/entry_points.txt +0 -0
|
@@ -1,288 +0,0 @@
|
|
|
1
|
-
import os
|
|
2
|
-
import subprocess
|
|
3
|
-
|
|
4
|
-
from zrb.context.any_context import AnyContext
|
|
5
|
-
from zrb.task.llm.workflow import get_available_workflows
|
|
6
|
-
from zrb.util.cli.markdown import render_markdown
|
|
7
|
-
from zrb.util.cli.style import (
|
|
8
|
-
stylize_blue,
|
|
9
|
-
stylize_bold_yellow,
|
|
10
|
-
stylize_error,
|
|
11
|
-
stylize_faint,
|
|
12
|
-
)
|
|
13
|
-
from zrb.util.file import write_file
|
|
14
|
-
from zrb.util.markdown import make_markdown_section
|
|
15
|
-
from zrb.util.string.conversion import FALSE_STRS, TRUE_STRS, to_boolean
|
|
16
|
-
|
|
17
|
-
MULTILINE_START_CMD = ["/multi", "/multiline"]
|
|
18
|
-
MULTILINE_END_CMD = ["/end"]
|
|
19
|
-
QUIT_CMD = ["/bye", "/quit", "/q", "/exit"]
|
|
20
|
-
WORKFLOW_CMD = ["/workflow", "/workflows", "/skill", "/skills", "/w"]
|
|
21
|
-
SAVE_CMD = ["/save", "/s"]
|
|
22
|
-
ATTACHMENT_CMD = ["/attachment", "/attachments", "/attach"]
|
|
23
|
-
YOLO_CMD = ["/yolo"]
|
|
24
|
-
HELP_CMD = ["/help", "/info"]
|
|
25
|
-
ADD_SUB_CMD = ["add"]
|
|
26
|
-
SET_SUB_CMD = ["set"]
|
|
27
|
-
CLEAR_SUB_CMD = ["clear"]
|
|
28
|
-
RUN_CLI_CMD = ["/run", "/exec", "/execute", "/cmd", "/cli", "!"]
|
|
29
|
-
|
|
30
|
-
# Command display constants
|
|
31
|
-
MULTILINE_START_CMD_DESC = "Start multiline input"
|
|
32
|
-
MULTILINE_END_CMD_DESC = "End multiline input"
|
|
33
|
-
QUIT_CMD_DESC = "Quit from chat session"
|
|
34
|
-
WORKFLOW_CMD_DESC = "Show active workflows"
|
|
35
|
-
WORKFLOW_ADD_SUB_CMD_DESC = (
|
|
36
|
-
"Add active workflow "
|
|
37
|
-
f"(e.g., `{WORKFLOW_CMD[0]} {ADD_SUB_CMD[0]} coding,researching`)"
|
|
38
|
-
)
|
|
39
|
-
WORKFLOW_SET_SUB_CMD_DESC = (
|
|
40
|
-
"Set active workflows " f"(e.g., `{WORKFLOW_CMD[0]} {SET_SUB_CMD[0]} coding,`)"
|
|
41
|
-
)
|
|
42
|
-
WORKFLOW_CLEAR_SUB_CMD_DESC = "Deactivate all workflows"
|
|
43
|
-
SAVE_CMD_DESC = f"Save last response to a file (e.g., `{SAVE_CMD[0]} conclusion.md`)"
|
|
44
|
-
ATTACHMENT_CMD_DESC = "Show current attachment"
|
|
45
|
-
ATTACHMENT_ADD_SUB_CMD_DESC = (
|
|
46
|
-
"Attach a file " f"(e.g., `{ATTACHMENT_CMD[0]} {ADD_SUB_CMD[0]} ./logo.png`)"
|
|
47
|
-
)
|
|
48
|
-
ATTACHMENT_SET_SUB_CMD_DESC = (
|
|
49
|
-
"Set attachments "
|
|
50
|
-
f"(e.g., `{ATTACHMENT_CMD[0]} {SET_SUB_CMD[0]} ./logo.png,./diagram.png`)"
|
|
51
|
-
)
|
|
52
|
-
ATTACHMENT_CLEAR_SUB_CMD_DESC = "Clear attachment"
|
|
53
|
-
YOLO_CMD_DESC = "Show/manipulate current YOLO mode"
|
|
54
|
-
YOLO_SET_CMD_DESC = (
|
|
55
|
-
"Assign YOLO tools "
|
|
56
|
-
f"(e.g., `{YOLO_CMD[0]} {SET_SUB_CMD[0]} read_from_file,analyze_file`)"
|
|
57
|
-
)
|
|
58
|
-
YOLO_SET_TRUE_CMD_DESC = "Activate YOLO mode for all tools"
|
|
59
|
-
YOLO_SET_FALSE_CMD_DESC = "Deactivate YOLO mode for all tools"
|
|
60
|
-
RUN_CLI_CMD_DESC = "Run a non-interactive CLI command"
|
|
61
|
-
HELP_CMD_DESC = "Show info/help"
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
def print_current_yolo_mode(
|
|
65
|
-
ctx: AnyContext, current_yolo_mode_value: str | bool
|
|
66
|
-
) -> None:
|
|
67
|
-
yolo_mode_str = (
|
|
68
|
-
current_yolo_mode_value if current_yolo_mode_value != "" else "*Not Set*"
|
|
69
|
-
)
|
|
70
|
-
ctx.print(render_markdown(f"🎲 Current YOLO mode: {yolo_mode_str}"), plain=True)
|
|
71
|
-
ctx.print("", plain=True)
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
def print_current_attachments(ctx: AnyContext, current_attachments_value: str) -> None:
|
|
75
|
-
attachments_str = (
|
|
76
|
-
current_attachments_value if current_attachments_value != "" else "*Not Set*"
|
|
77
|
-
)
|
|
78
|
-
ctx.print(render_markdown(f"📎 Current attachments: {attachments_str}"), plain=True)
|
|
79
|
-
ctx.print("", plain=True)
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
def print_current_workflows(ctx: AnyContext, current_workflows_value: str) -> None:
|
|
83
|
-
available_workflows = get_available_workflows()
|
|
84
|
-
available_workflows_str = (
|
|
85
|
-
", ".join(sorted([workflow_name for workflow_name in available_workflows]))
|
|
86
|
-
if len(available_workflows) > 0
|
|
87
|
-
else "*No Available Workflow*"
|
|
88
|
-
)
|
|
89
|
-
current_workflows_str = (
|
|
90
|
-
current_workflows_value
|
|
91
|
-
if current_workflows_value != ""
|
|
92
|
-
else "*No Active Workflow*"
|
|
93
|
-
)
|
|
94
|
-
ctx.print(
|
|
95
|
-
render_markdown(
|
|
96
|
-
"\n".join(
|
|
97
|
-
[
|
|
98
|
-
f"- 🔄 Current workflows : {current_workflows_str}",
|
|
99
|
-
f"- 📚 Available workflows : {available_workflows_str}",
|
|
100
|
-
]
|
|
101
|
-
)
|
|
102
|
-
),
|
|
103
|
-
plain=True,
|
|
104
|
-
)
|
|
105
|
-
ctx.print("", plain=True)
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
def save_final_result(ctx: AnyContext, user_input: str, final_result: str) -> None:
|
|
109
|
-
save_path = get_command_param(user_input, SAVE_CMD)
|
|
110
|
-
save_path = os.path.expanduser(save_path)
|
|
111
|
-
if os.path.exists(save_path):
|
|
112
|
-
ctx.print(
|
|
113
|
-
stylize_error(f"Cannot save to existing file: {save_path}"),
|
|
114
|
-
plain=True,
|
|
115
|
-
)
|
|
116
|
-
return
|
|
117
|
-
write_file(save_path, final_result)
|
|
118
|
-
ctx.print(f"Response saved to {save_path}", plain=True)
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
def run_cli_command(ctx: AnyContext, user_input: str) -> None:
|
|
122
|
-
command = get_command_param(user_input, RUN_CLI_CMD)
|
|
123
|
-
result = subprocess.run(
|
|
124
|
-
command,
|
|
125
|
-
shell=True,
|
|
126
|
-
capture_output=True,
|
|
127
|
-
text=True,
|
|
128
|
-
)
|
|
129
|
-
ctx.print(
|
|
130
|
-
render_markdown(
|
|
131
|
-
make_markdown_section(
|
|
132
|
-
f"`{command}`",
|
|
133
|
-
"\n".join(
|
|
134
|
-
[
|
|
135
|
-
make_markdown_section("📤 Stdout", result.stdout, as_code=True),
|
|
136
|
-
make_markdown_section("🚫 Stderr", result.stderr, as_code=True),
|
|
137
|
-
make_markdown_section(
|
|
138
|
-
"🎯 Return code", f"Return Code: {result.returncode}"
|
|
139
|
-
),
|
|
140
|
-
]
|
|
141
|
-
),
|
|
142
|
-
)
|
|
143
|
-
),
|
|
144
|
-
plain=True,
|
|
145
|
-
)
|
|
146
|
-
ctx.print("", plain=True)
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
def get_new_yolo_mode(old_yolo_mode: str | bool, user_input: str) -> str | bool:
|
|
150
|
-
new_yolo_mode = get_command_param(user_input, YOLO_CMD)
|
|
151
|
-
if new_yolo_mode != "":
|
|
152
|
-
if new_yolo_mode in TRUE_STRS or new_yolo_mode in FALSE_STRS:
|
|
153
|
-
return to_boolean(new_yolo_mode)
|
|
154
|
-
return new_yolo_mode
|
|
155
|
-
if isinstance(old_yolo_mode, bool):
|
|
156
|
-
return old_yolo_mode
|
|
157
|
-
return _normalize_comma_separated_str(old_yolo_mode)
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
def get_new_attachments(old_attachment: str, user_input: str) -> str:
|
|
161
|
-
if not is_command_match(user_input, ATTACHMENT_CMD):
|
|
162
|
-
return _normalize_comma_separated_str(old_attachment)
|
|
163
|
-
if is_command_match(user_input, ATTACHMENT_CMD, SET_SUB_CMD):
|
|
164
|
-
return _normalize_comma_separated_str(
|
|
165
|
-
get_command_param(user_input, ATTACHMENT_CMD, SET_SUB_CMD)
|
|
166
|
-
)
|
|
167
|
-
if is_command_match(user_input, ATTACHMENT_CMD, CLEAR_SUB_CMD):
|
|
168
|
-
return ""
|
|
169
|
-
if is_command_match(user_input, ATTACHMENT_CMD, ADD_SUB_CMD):
|
|
170
|
-
new_attachment = get_command_param(user_input, ATTACHMENT_CMD, ADD_SUB_CMD)
|
|
171
|
-
return _normalize_comma_separated_str(
|
|
172
|
-
",".join([old_attachment, new_attachment])
|
|
173
|
-
)
|
|
174
|
-
return old_attachment
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
def get_new_workflows(old_workflow: str, user_input: str) -> str:
|
|
178
|
-
if not is_command_match(user_input, WORKFLOW_CMD):
|
|
179
|
-
return _normalize_comma_separated_str(old_workflow)
|
|
180
|
-
if is_command_match(user_input, WORKFLOW_CMD, SET_SUB_CMD):
|
|
181
|
-
return _normalize_comma_separated_str(
|
|
182
|
-
get_command_param(user_input, WORKFLOW_CMD, SET_SUB_CMD)
|
|
183
|
-
)
|
|
184
|
-
if is_command_match(user_input, WORKFLOW_CMD, CLEAR_SUB_CMD):
|
|
185
|
-
return ""
|
|
186
|
-
if is_command_match(user_input, WORKFLOW_CMD, ADD_SUB_CMD):
|
|
187
|
-
new_workflow = get_command_param(user_input, WORKFLOW_CMD, ADD_SUB_CMD)
|
|
188
|
-
return _normalize_comma_separated_str(",".join([old_workflow, new_workflow]))
|
|
189
|
-
return _normalize_comma_separated_str(old_workflow)
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
def _normalize_comma_separated_str(comma_separated_str: str) -> str:
|
|
193
|
-
return ",".join(
|
|
194
|
-
[
|
|
195
|
-
workflow_name.strip()
|
|
196
|
-
for workflow_name in comma_separated_str.split(",")
|
|
197
|
-
if workflow_name.strip() != ""
|
|
198
|
-
]
|
|
199
|
-
)
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
def get_command_param(user_input: str, *cmd_patterns: list[str]) -> str:
|
|
203
|
-
if not is_command_match(user_input, *cmd_patterns):
|
|
204
|
-
return ""
|
|
205
|
-
parts = [part for part in user_input.split(" ") if part.strip() != ""]
|
|
206
|
-
if len(parts) <= len(cmd_patterns):
|
|
207
|
-
return ""
|
|
208
|
-
params = parts[len(cmd_patterns) :]
|
|
209
|
-
return " ".join(params)
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
def is_command_match(user_input: str, *cmd_patterns: list[str]) -> bool:
|
|
213
|
-
parts = [part for part in user_input.split(" ") if part.strip() != ""]
|
|
214
|
-
if len(cmd_patterns) > len(parts):
|
|
215
|
-
return False
|
|
216
|
-
for index, cmd_pattern in enumerate(cmd_patterns):
|
|
217
|
-
part = parts[index]
|
|
218
|
-
if part.lower() not in cmd_pattern:
|
|
219
|
-
return False
|
|
220
|
-
return True
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
def print_commands(ctx: AnyContext):
|
|
224
|
-
"""
|
|
225
|
-
Displays the available chat session commands to the user.
|
|
226
|
-
Args:
|
|
227
|
-
ctx: The context object for the task.
|
|
228
|
-
"""
|
|
229
|
-
ctx.print(
|
|
230
|
-
"\n".join(
|
|
231
|
-
[
|
|
232
|
-
_show_command(QUIT_CMD[0], QUIT_CMD_DESC),
|
|
233
|
-
_show_command(MULTILINE_START_CMD[0], MULTILINE_START_CMD_DESC),
|
|
234
|
-
_show_command(MULTILINE_END_CMD[0], MULTILINE_END_CMD_DESC),
|
|
235
|
-
_show_command(ATTACHMENT_CMD[0], ATTACHMENT_CMD_DESC),
|
|
236
|
-
_show_subcommand(
|
|
237
|
-
ADD_SUB_CMD[0], "<file-path>", ATTACHMENT_ADD_SUB_CMD_DESC
|
|
238
|
-
),
|
|
239
|
-
_show_subcommand(
|
|
240
|
-
SET_SUB_CMD[0],
|
|
241
|
-
"<file1-path,file2-path,...>",
|
|
242
|
-
ATTACHMENT_SET_SUB_CMD_DESC,
|
|
243
|
-
),
|
|
244
|
-
_show_subcommand(CLEAR_SUB_CMD[0], "", ATTACHMENT_CLEAR_SUB_CMD_DESC),
|
|
245
|
-
_show_command(WORKFLOW_CMD[0], WORKFLOW_CMD_DESC),
|
|
246
|
-
_show_subcommand(
|
|
247
|
-
ADD_SUB_CMD[0], "<workflow>", WORKFLOW_ADD_SUB_CMD_DESC
|
|
248
|
-
),
|
|
249
|
-
_show_subcommand(
|
|
250
|
-
SET_SUB_CMD[0],
|
|
251
|
-
"<workflow1,workflow2,..>",
|
|
252
|
-
WORKFLOW_SET_SUB_CMD_DESC,
|
|
253
|
-
),
|
|
254
|
-
_show_subcommand(CLEAR_SUB_CMD[0], "", WORKFLOW_CLEAR_SUB_CMD_DESC),
|
|
255
|
-
_show_command(f"{SAVE_CMD[0]}", SAVE_CMD_DESC),
|
|
256
|
-
_show_command(YOLO_CMD[0], YOLO_CMD_DESC),
|
|
257
|
-
_show_subcommand(SET_SUB_CMD[0], "true", YOLO_SET_TRUE_CMD_DESC),
|
|
258
|
-
_show_subcommand(SET_SUB_CMD[0], "false", YOLO_SET_FALSE_CMD_DESC),
|
|
259
|
-
_show_subcommand(
|
|
260
|
-
SET_SUB_CMD[0], "<tool1,tool2,tool2>", YOLO_SET_CMD_DESC
|
|
261
|
-
),
|
|
262
|
-
_show_command(RUN_CLI_CMD[0], ""),
|
|
263
|
-
_show_command_param("<cli-command>", RUN_CLI_CMD_DESC),
|
|
264
|
-
_show_command(HELP_CMD[0], HELP_CMD_DESC),
|
|
265
|
-
]
|
|
266
|
-
),
|
|
267
|
-
plain=True,
|
|
268
|
-
)
|
|
269
|
-
ctx.print("", plain=True)
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
def _show_command(command: str, description: str) -> str:
|
|
273
|
-
styled_command = stylize_bold_yellow(command.ljust(37))
|
|
274
|
-
styled_description = stylize_faint(description)
|
|
275
|
-
return f" {styled_command} {styled_description}"
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
def _show_subcommand(subcommand: str, param: str, description: str) -> str:
|
|
279
|
-
styled_subcommand = stylize_bold_yellow(f" {subcommand}")
|
|
280
|
-
styled_param = stylize_blue(param.ljust(32 - len(subcommand)))
|
|
281
|
-
styled_description = stylize_faint(description)
|
|
282
|
-
return f" {styled_subcommand} {styled_param} {styled_description}"
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
def _show_command_param(param: str, description: str) -> str:
|
|
286
|
-
styled_param = stylize_blue(f" {param}".ljust(37))
|
|
287
|
-
styled_description = stylize_faint(description)
|
|
288
|
-
return f" {styled_param} {styled_description}"
|
zrb/builtin/llm/chat_trigger.py
DELETED
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
import asyncio
|
|
2
|
-
import os
|
|
3
|
-
from asyncio import StreamReader
|
|
4
|
-
from typing import TYPE_CHECKING, Any, Callable, Coroutine
|
|
5
|
-
|
|
6
|
-
from zrb.context.any_context import AnyContext
|
|
7
|
-
from zrb.util.run import run_async
|
|
8
|
-
|
|
9
|
-
if TYPE_CHECKING:
|
|
10
|
-
from prompt_toolkit import PromptSession
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
ChatTrigger = Callable[[AnyContext], Coroutine[Any, Any, str] | str]
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
class LLMChatTrigger:
|
|
17
|
-
|
|
18
|
-
def __init__(self):
|
|
19
|
-
self._triggers: list[ChatTrigger] = []
|
|
20
|
-
|
|
21
|
-
def add_trigger(self, *trigger: ChatTrigger):
|
|
22
|
-
self.append_trigger(*trigger)
|
|
23
|
-
|
|
24
|
-
def append_trigger(self, *trigger: ChatTrigger):
|
|
25
|
-
for single_trigger in trigger:
|
|
26
|
-
self._triggers.append(single_trigger)
|
|
27
|
-
|
|
28
|
-
async def wait(
|
|
29
|
-
self, reader: "PromptSession[Any] | StreamReader", ctx: AnyContext
|
|
30
|
-
) -> str:
|
|
31
|
-
trigger_tasks = [
|
|
32
|
-
asyncio.create_task(run_async(self._read_next_line(reader, ctx)))
|
|
33
|
-
] + [asyncio.create_task(run_async(trigger(ctx))) for trigger in self._triggers]
|
|
34
|
-
final_result: str = ""
|
|
35
|
-
try:
|
|
36
|
-
done, pending = await asyncio.wait(
|
|
37
|
-
trigger_tasks, return_when=asyncio.FIRST_COMPLETED
|
|
38
|
-
)
|
|
39
|
-
for task in done:
|
|
40
|
-
final_result = await task
|
|
41
|
-
if pending:
|
|
42
|
-
for task in pending:
|
|
43
|
-
task.cancel()
|
|
44
|
-
for task in done:
|
|
45
|
-
break
|
|
46
|
-
except asyncio.CancelledError:
|
|
47
|
-
ctx.print("Task cancelled.", plain=True)
|
|
48
|
-
final_result = "/bye"
|
|
49
|
-
except KeyboardInterrupt:
|
|
50
|
-
ctx.print("KeyboardInterrupt detected. Exiting...", plain=True)
|
|
51
|
-
final_result = "/bye"
|
|
52
|
-
return final_result
|
|
53
|
-
|
|
54
|
-
async def _read_next_line(
|
|
55
|
-
self, reader: "PromptSession[Any] | StreamReader", ctx: AnyContext
|
|
56
|
-
) -> str:
|
|
57
|
-
"""Reads one line of input using the provided reader."""
|
|
58
|
-
from prompt_toolkit import PromptSession
|
|
59
|
-
|
|
60
|
-
from zrb.builtin.llm.chat_completion import ChatCompleter
|
|
61
|
-
|
|
62
|
-
try:
|
|
63
|
-
if isinstance(reader, PromptSession):
|
|
64
|
-
bottom_toolbar = f"📁 Current directory: {os.getcwd()}"
|
|
65
|
-
return await reader.prompt_async(
|
|
66
|
-
completer=ChatCompleter(), bottom_toolbar=bottom_toolbar
|
|
67
|
-
)
|
|
68
|
-
line_bytes = await reader.readline()
|
|
69
|
-
if not line_bytes:
|
|
70
|
-
return "/bye" # Signal to exit
|
|
71
|
-
user_input = line_bytes.decode().strip()
|
|
72
|
-
ctx.print(user_input, plain=True)
|
|
73
|
-
return user_input
|
|
74
|
-
except KeyboardInterrupt:
|
|
75
|
-
ctx.print("KeyboardInterrupt detected. Exiting...", plain=True)
|
|
76
|
-
return "/bye"
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
llm_chat_trigger = LLMChatTrigger()
|
zrb/builtin/llm/history.py
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import json
|
|
2
|
-
import os
|
|
3
|
-
from typing import Any
|
|
4
|
-
|
|
5
|
-
from zrb.config.config import CFG
|
|
6
|
-
from zrb.context.any_context import AnyContext
|
|
7
|
-
from zrb.task.llm.conversation_history_model import ConversationHistory
|
|
8
|
-
from zrb.util.file import read_file, write_file
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
def read_chat_conversation(ctx: AnyContext) -> dict[str, Any] | list | None:
|
|
12
|
-
"""Reads conversation history from the session file.
|
|
13
|
-
Returns the raw dictionary or list loaded from JSON, or None if not found/empty.
|
|
14
|
-
The LLMTask will handle parsing this into ConversationHistory.
|
|
15
|
-
"""
|
|
16
|
-
if ctx.input.start_new:
|
|
17
|
-
return None # Indicate no history to load
|
|
18
|
-
previous_session_name = ctx.input.previous_session
|
|
19
|
-
if not previous_session_name: # Check for empty string or None
|
|
20
|
-
last_session_file_path = os.path.join(CFG.LLM_HISTORY_DIR, "last-session")
|
|
21
|
-
if os.path.isfile(last_session_file_path):
|
|
22
|
-
previous_session_name = read_file(last_session_file_path).strip()
|
|
23
|
-
if not previous_session_name: # Handle empty last-session file
|
|
24
|
-
return None
|
|
25
|
-
else:
|
|
26
|
-
return None # No previous session specified and no last session found
|
|
27
|
-
conversation_file_path = os.path.join(
|
|
28
|
-
CFG.LLM_HISTORY_DIR, f"{previous_session_name}.json"
|
|
29
|
-
)
|
|
30
|
-
if not os.path.isfile(conversation_file_path):
|
|
31
|
-
ctx.log_warning(f"History file not found: {conversation_file_path}")
|
|
32
|
-
return None
|
|
33
|
-
try:
|
|
34
|
-
content = read_file(conversation_file_path)
|
|
35
|
-
if not content.strip():
|
|
36
|
-
ctx.log_warning(f"History file is empty: {conversation_file_path}")
|
|
37
|
-
return None
|
|
38
|
-
# Return the raw loaded data (dict or list)
|
|
39
|
-
return json.loads(content)
|
|
40
|
-
except json.JSONDecodeError:
|
|
41
|
-
ctx.log_warning(
|
|
42
|
-
f"Could not decode JSON from history file '{conversation_file_path}'. "
|
|
43
|
-
"Treating as empty history."
|
|
44
|
-
)
|
|
45
|
-
return None
|
|
46
|
-
except Exception as e:
|
|
47
|
-
ctx.log_warning(
|
|
48
|
-
f"Error reading history file '{conversation_file_path}': {e}. "
|
|
49
|
-
"Treating as empty history."
|
|
50
|
-
)
|
|
51
|
-
return None
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
def write_chat_conversation(ctx: AnyContext, history_data: ConversationHistory):
|
|
55
|
-
"""Writes the conversation history data (including context) to a session file."""
|
|
56
|
-
os.makedirs(CFG.LLM_HISTORY_DIR, exist_ok=True)
|
|
57
|
-
current_session_name = ctx.session.name if ctx.session is not None else None
|
|
58
|
-
if not current_session_name:
|
|
59
|
-
ctx.log_warning("Cannot write history: Session name is empty.")
|
|
60
|
-
return
|
|
61
|
-
conversation_file_path = os.path.join(
|
|
62
|
-
CFG.LLM_HISTORY_DIR, f"{current_session_name}.json"
|
|
63
|
-
)
|
|
64
|
-
try:
|
|
65
|
-
# Use model_dump_json to serialize the Pydantic model
|
|
66
|
-
write_file(conversation_file_path, history_data.model_dump_json(indent=2))
|
|
67
|
-
# Update the last-session pointer
|
|
68
|
-
last_session_file_path = os.path.join(CFG.LLM_HISTORY_DIR, "last-session")
|
|
69
|
-
write_file(last_session_file_path, current_session_name)
|
|
70
|
-
except Exception as e:
|
|
71
|
-
ctx.log_error(f"Error writing history file '{conversation_file_path}': {e}")
|
zrb/builtin/llm/input.py
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import os
|
|
2
|
-
|
|
3
|
-
from zrb.context.any_shared_context import AnySharedContext
|
|
4
|
-
from zrb.input.str_input import StrInput
|
|
5
|
-
from zrb.util.file import read_file
|
|
6
|
-
from zrb.util.string.conversion import to_pascal_case
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
class PreviousSessionInput(StrInput):
|
|
10
|
-
|
|
11
|
-
def to_html(self, ctx: AnySharedContext) -> str:
|
|
12
|
-
name = self.name
|
|
13
|
-
description = self.description
|
|
14
|
-
default = self.get_default_str(ctx)
|
|
15
|
-
script = read_file(
|
|
16
|
-
file_path=os.path.join(os.path.dirname(__file__), "previous-session.js"),
|
|
17
|
-
replace_map={
|
|
18
|
-
"CURRENT_INPUT_NAME": name,
|
|
19
|
-
"CurrentPascalInputName": to_pascal_case(name),
|
|
20
|
-
},
|
|
21
|
-
)
|
|
22
|
-
return "\n".join(
|
|
23
|
-
[
|
|
24
|
-
f'<input name="{name}" placeholder="{description}" value="{default}" />',
|
|
25
|
-
f"<script>{script}</script>",
|
|
26
|
-
]
|
|
27
|
-
)
|