zrb 1.13.1__py3-none-any.whl → 1.21.17__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 -6
- zrb/attr/type.py +8 -8
- zrb/builtin/__init__.py +2 -0
- zrb/builtin/group.py +31 -15
- zrb/builtin/http.py +7 -8
- zrb/builtin/llm/attachment.py +40 -0
- zrb/builtin/llm/chat_session.py +130 -144
- zrb/builtin/llm/chat_session_cmd.py +226 -0
- zrb/builtin/llm/chat_trigger.py +73 -0
- zrb/builtin/llm/history.py +4 -4
- zrb/builtin/llm/llm_ask.py +218 -110
- zrb/builtin/llm/tool/api.py +74 -62
- zrb/builtin/llm/tool/cli.py +35 -16
- zrb/builtin/llm/tool/code.py +49 -47
- zrb/builtin/llm/tool/file.py +262 -251
- zrb/builtin/llm/tool/note.py +84 -0
- zrb/builtin/llm/tool/rag.py +25 -18
- zrb/builtin/llm/tool/sub_agent.py +29 -22
- zrb/builtin/llm/tool/web.py +135 -143
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/add_entity_util.py +7 -7
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/add_module_util.py +5 -5
- zrb/builtin/project/add/fastapp/fastapp_util.py +1 -1
- zrb/builtin/searxng/config/settings.yml +5671 -0
- zrb/builtin/searxng/start.py +21 -0
- zrb/builtin/setup/latex/ubuntu.py +1 -0
- zrb/builtin/setup/ubuntu.py +1 -1
- zrb/builtin/shell/autocomplete/bash.py +4 -3
- zrb/builtin/shell/autocomplete/zsh.py +4 -3
- zrb/config/config.py +255 -78
- zrb/config/default_prompt/file_extractor_system_prompt.md +109 -9
- zrb/config/default_prompt/interactive_system_prompt.md +24 -30
- zrb/config/default_prompt/persona.md +1 -1
- zrb/config/default_prompt/repo_extractor_system_prompt.md +31 -31
- zrb/config/default_prompt/repo_summarizer_system_prompt.md +27 -8
- zrb/config/default_prompt/summarization_prompt.md +8 -13
- zrb/config/default_prompt/system_prompt.md +36 -30
- zrb/config/llm_config.py +129 -24
- zrb/config/llm_context/config.py +127 -90
- zrb/config/llm_context/config_parser.py +1 -7
- zrb/config/llm_context/workflow.py +81 -0
- zrb/config/llm_rate_limitter.py +89 -45
- zrb/context/any_shared_context.py +7 -1
- zrb/context/context.py +8 -2
- zrb/context/shared_context.py +6 -8
- zrb/group/any_group.py +12 -5
- zrb/group/group.py +67 -3
- zrb/input/any_input.py +5 -1
- zrb/input/base_input.py +18 -6
- zrb/input/text_input.py +7 -24
- zrb/runner/cli.py +21 -20
- zrb/runner/common_util.py +24 -19
- zrb/runner/web_route/task_input_api_route.py +5 -5
- zrb/runner/web_route/task_session_api_route.py +1 -4
- zrb/runner/web_util/user.py +7 -3
- zrb/session/any_session.py +12 -6
- zrb/session/session.py +39 -18
- zrb/task/any_task.py +24 -3
- zrb/task/base/context.py +17 -9
- zrb/task/base/execution.py +15 -8
- zrb/task/base/lifecycle.py +8 -4
- zrb/task/base/monitoring.py +12 -7
- zrb/task/base_task.py +69 -5
- zrb/task/base_trigger.py +12 -5
- zrb/task/llm/agent.py +138 -52
- zrb/task/llm/config.py +45 -13
- zrb/task/llm/conversation_history.py +76 -6
- zrb/task/llm/conversation_history_model.py +0 -168
- zrb/task/llm/default_workflow/coding/workflow.md +41 -0
- zrb/task/llm/default_workflow/copywriting/workflow.md +68 -0
- zrb/task/llm/default_workflow/git/workflow.md +118 -0
- zrb/task/llm/default_workflow/golang/workflow.md +128 -0
- zrb/task/llm/default_workflow/html-css/workflow.md +135 -0
- zrb/task/llm/default_workflow/java/workflow.md +146 -0
- zrb/task/llm/default_workflow/javascript/workflow.md +158 -0
- zrb/task/llm/default_workflow/python/workflow.md +160 -0
- zrb/task/llm/default_workflow/researching/workflow.md +153 -0
- zrb/task/llm/default_workflow/rust/workflow.md +162 -0
- zrb/task/llm/default_workflow/shell/workflow.md +299 -0
- zrb/task/llm/file_replacement.py +206 -0
- zrb/task/llm/file_tool_model.py +57 -0
- zrb/task/llm/history_summarization.py +22 -35
- zrb/task/llm/history_summarization_tool.py +24 -0
- zrb/task/llm/print_node.py +182 -63
- zrb/task/llm/prompt.py +213 -153
- zrb/task/llm/tool_wrapper.py +210 -53
- zrb/task/llm/workflow.py +76 -0
- zrb/task/llm_task.py +98 -47
- zrb/task/make_task.py +2 -3
- zrb/task/rsync_task.py +25 -10
- zrb/task/scheduler.py +4 -4
- zrb/util/attr.py +50 -40
- zrb/util/cli/markdown.py +12 -0
- zrb/util/cli/text.py +30 -0
- zrb/util/file.py +27 -11
- zrb/util/{llm/prompt.py → markdown.py} +2 -3
- zrb/util/string/conversion.py +1 -1
- zrb/util/truncate.py +23 -0
- zrb/util/yaml.py +204 -0
- {zrb-1.13.1.dist-info → zrb-1.21.17.dist-info}/METADATA +40 -20
- {zrb-1.13.1.dist-info → zrb-1.21.17.dist-info}/RECORD +102 -79
- {zrb-1.13.1.dist-info → zrb-1.21.17.dist-info}/WHEEL +1 -1
- zrb/task/llm/default_workflow/coding.md +0 -24
- zrb/task/llm/default_workflow/copywriting.md +0 -17
- zrb/task/llm/default_workflow/researching.md +0 -18
- {zrb-1.13.1.dist-info → zrb-1.21.17.dist-info}/entry_points.txt +0 -0
zrb/task/llm_task.py
CHANGED
|
@@ -5,7 +5,6 @@ from typing import TYPE_CHECKING, Any
|
|
|
5
5
|
from zrb.attr.type import BoolAttr, IntAttr, StrAttr, StrListAttr, fstring
|
|
6
6
|
from zrb.config.llm_rate_limitter import LLMRateLimiter
|
|
7
7
|
from zrb.context.any_context import AnyContext
|
|
8
|
-
from zrb.context.any_shared_context import AnySharedContext
|
|
9
8
|
from zrb.env.any_env import AnyEnv
|
|
10
9
|
from zrb.input.any_input import AnyInput
|
|
11
10
|
from zrb.task.any_task import AnyTask
|
|
@@ -14,30 +13,31 @@ from zrb.task.llm.agent import get_agent, run_agent_iteration
|
|
|
14
13
|
from zrb.task.llm.config import (
|
|
15
14
|
get_model,
|
|
16
15
|
get_model_settings,
|
|
16
|
+
get_yolo_mode,
|
|
17
17
|
)
|
|
18
18
|
from zrb.task.llm.conversation_history import (
|
|
19
|
+
inject_conversation_history_notes,
|
|
19
20
|
read_conversation_history,
|
|
20
21
|
write_conversation_history,
|
|
21
22
|
)
|
|
22
23
|
from zrb.task.llm.conversation_history_model import ConversationHistory
|
|
23
24
|
from zrb.task.llm.history_summarization import maybe_summarize_history
|
|
24
25
|
from zrb.task.llm.prompt import (
|
|
26
|
+
get_attachments,
|
|
25
27
|
get_summarization_system_prompt,
|
|
26
28
|
get_system_and_user_prompt,
|
|
27
29
|
get_user_message,
|
|
28
30
|
)
|
|
31
|
+
from zrb.task.llm.workflow import load_workflow
|
|
29
32
|
from zrb.util.cli.style import stylize_faint
|
|
30
33
|
from zrb.xcom.xcom import Xcom
|
|
31
34
|
|
|
32
35
|
if TYPE_CHECKING:
|
|
33
|
-
from pydantic_ai import Agent, Tool
|
|
36
|
+
from pydantic_ai import AbstractToolset, Agent, Tool, UserContent
|
|
34
37
|
from pydantic_ai.models import Model
|
|
35
38
|
from pydantic_ai.settings import ModelSettings
|
|
36
|
-
from pydantic_ai.toolsets import AbstractToolset
|
|
37
39
|
|
|
38
40
|
ToolOrCallable = Tool | Callable
|
|
39
|
-
else:
|
|
40
|
-
ToolOrCallable = Any
|
|
41
41
|
|
|
42
42
|
|
|
43
43
|
class LLMTask(BaseTask):
|
|
@@ -50,47 +50,55 @@ class LLMTask(BaseTask):
|
|
|
50
50
|
cli_only: bool = False,
|
|
51
51
|
input: list[AnyInput | None] | AnyInput | None = None,
|
|
52
52
|
env: list[AnyEnv | None] | AnyEnv | None = None,
|
|
53
|
-
model:
|
|
54
|
-
"Callable[[AnySharedContext], Model | str | fstring] | Model | None"
|
|
55
|
-
) = None,
|
|
53
|
+
model: "Callable[[AnyContext], Model | str | fstring | None] | Model | None" = None,
|
|
56
54
|
render_model: bool = True,
|
|
57
|
-
model_base_url:
|
|
55
|
+
model_base_url: "Callable[[AnyContext], str | None] | str | None" = None,
|
|
58
56
|
render_model_base_url: bool = True,
|
|
59
|
-
model_api_key:
|
|
57
|
+
model_api_key: "Callable[[AnyContext], str | None] | str | None" = None,
|
|
60
58
|
render_model_api_key: bool = True,
|
|
61
59
|
model_settings: (
|
|
62
|
-
"ModelSettings | Callable[[
|
|
60
|
+
"ModelSettings | Callable[[AnyContext], ModelSettings] | None"
|
|
61
|
+
) = None,
|
|
62
|
+
small_model: (
|
|
63
|
+
"Callable[[AnyContext], Model | str | fstring] | Model | None"
|
|
63
64
|
) = None,
|
|
64
|
-
|
|
65
|
-
|
|
65
|
+
render_small_model: bool = True,
|
|
66
|
+
small_model_base_url: StrAttr | None = None,
|
|
67
|
+
render_small_model_base_url: bool = True,
|
|
68
|
+
small_model_api_key: StrAttr | None = None,
|
|
69
|
+
render_small_model_api_key: bool = True,
|
|
70
|
+
small_model_settings: (
|
|
71
|
+
"ModelSettings | Callable[[AnyContext], ModelSettings] | None"
|
|
72
|
+
) = None,
|
|
73
|
+
persona: "Callable[[AnyContext], str | None] | str | None" = None,
|
|
66
74
|
render_persona: bool = False,
|
|
67
|
-
system_prompt:
|
|
75
|
+
system_prompt: "Callable[[AnyContext], str | None] | str | None" = None,
|
|
68
76
|
render_system_prompt: bool = False,
|
|
69
|
-
special_instruction_prompt:
|
|
77
|
+
special_instruction_prompt: "Callable[[AnyContext], str | None] | str | None" = None,
|
|
70
78
|
render_special_instruction_prompt: bool = False,
|
|
71
|
-
|
|
72
|
-
|
|
79
|
+
workflows: StrListAttr | None = None,
|
|
80
|
+
render_workflows: bool = True,
|
|
73
81
|
message: StrAttr | None = None,
|
|
82
|
+
attachment: "UserContent | list[UserContent] | Callable[[AnyContext], UserContent | list[UserContent]] | None" = None, # noqa
|
|
74
83
|
render_message: bool = True,
|
|
75
84
|
tools: (
|
|
76
|
-
list["ToolOrCallable"]
|
|
77
|
-
| Callable[[AnySharedContext], list["ToolOrCallable"]]
|
|
85
|
+
list["ToolOrCallable"] | Callable[[AnyContext], list["ToolOrCallable"]]
|
|
78
86
|
) = [],
|
|
79
87
|
toolsets: (
|
|
80
|
-
list["AbstractToolset[
|
|
88
|
+
list["AbstractToolset[None] | str"]
|
|
89
|
+
| Callable[[AnyContext], list["AbstractToolset[None] | str"]]
|
|
81
90
|
) = [],
|
|
82
91
|
conversation_history: (
|
|
83
92
|
ConversationHistory
|
|
84
|
-
| Callable[[
|
|
93
|
+
| Callable[[AnyContext], ConversationHistory | dict | list]
|
|
85
94
|
| dict
|
|
86
95
|
| list
|
|
87
96
|
) = ConversationHistory(),
|
|
88
97
|
conversation_history_reader: (
|
|
89
|
-
Callable[[
|
|
90
|
-
| None
|
|
98
|
+
Callable[[AnyContext], ConversationHistory | dict | list | None] | None
|
|
91
99
|
) = None,
|
|
92
100
|
conversation_history_writer: (
|
|
93
|
-
Callable[[
|
|
101
|
+
Callable[[AnyContext, ConversationHistory], None] | None
|
|
94
102
|
) = None,
|
|
95
103
|
conversation_history_file: StrAttr | None = None,
|
|
96
104
|
render_history_file: bool = True,
|
|
@@ -101,9 +109,16 @@ class LLMTask(BaseTask):
|
|
|
101
109
|
history_summarization_token_threshold: IntAttr | None = None,
|
|
102
110
|
render_history_summarization_token_threshold: bool = True,
|
|
103
111
|
rate_limitter: LLMRateLimiter | None = None,
|
|
104
|
-
execute_condition: bool | str | Callable[[
|
|
112
|
+
execute_condition: bool | str | Callable[[AnyContext], bool] = True,
|
|
105
113
|
retries: int = 2,
|
|
106
114
|
retry_period: float = 0,
|
|
115
|
+
yolo_mode: (
|
|
116
|
+
Callable[[AnyContext], list[str] | bool | None]
|
|
117
|
+
| StrListAttr
|
|
118
|
+
| BoolAttr
|
|
119
|
+
| None
|
|
120
|
+
) = None,
|
|
121
|
+
render_yolo_mode: bool = True,
|
|
107
122
|
readiness_check: list[AnyTask] | AnyTask | None = None,
|
|
108
123
|
readiness_check_delay: float = 0.5,
|
|
109
124
|
readiness_check_period: float = 5,
|
|
@@ -115,7 +130,7 @@ class LLMTask(BaseTask):
|
|
|
115
130
|
fallback: list[AnyTask] | AnyTask | None = None,
|
|
116
131
|
successor: list[AnyTask] | AnyTask | None = None,
|
|
117
132
|
conversation_context: (
|
|
118
|
-
dict[str, Any] | Callable[[
|
|
133
|
+
dict[str, Any] | Callable[[AnyContext], dict[str, Any]] | None
|
|
119
134
|
) = None,
|
|
120
135
|
):
|
|
121
136
|
super().__init__(
|
|
@@ -146,24 +161,30 @@ class LLMTask(BaseTask):
|
|
|
146
161
|
self._model_api_key = model_api_key
|
|
147
162
|
self._render_model_api_key = render_model_api_key
|
|
148
163
|
self._model_settings = model_settings
|
|
149
|
-
self.
|
|
164
|
+
self._small_model = small_model
|
|
165
|
+
self._render_small_model = render_small_model
|
|
166
|
+
self._small_model_base_url = small_model_base_url
|
|
167
|
+
self._render_small_model_base_url = render_small_model_base_url
|
|
168
|
+
self._small_model_api_key = small_model_api_key
|
|
169
|
+
self._render_small_model_api_key = render_small_model_api_key
|
|
170
|
+
self._small_model_settings = small_model_settings
|
|
150
171
|
self._persona = persona
|
|
151
172
|
self._render_persona = render_persona
|
|
152
173
|
self._system_prompt = system_prompt
|
|
153
174
|
self._render_system_prompt = render_system_prompt
|
|
154
175
|
self._special_instruction_prompt = special_instruction_prompt
|
|
155
176
|
self._render_special_instruction_prompt = render_special_instruction_prompt
|
|
156
|
-
self.
|
|
157
|
-
self.
|
|
177
|
+
self._workflows = workflows
|
|
178
|
+
self._render_workflows = render_workflows
|
|
158
179
|
self._message = message
|
|
159
180
|
self._render_message = render_message
|
|
160
181
|
self._summarization_prompt = summarization_prompt
|
|
161
182
|
self._render_summarization_prompt = render_summarization_prompt
|
|
162
183
|
self._tools = tools
|
|
163
184
|
self._rate_limitter = rate_limitter
|
|
164
|
-
self._additional_tools: list["ToolOrCallable"] = []
|
|
185
|
+
self._additional_tools: list["ToolOrCallable"] = [load_workflow]
|
|
165
186
|
self._toolsets = toolsets
|
|
166
|
-
self._additional_toolsets: list["AbstractToolset[
|
|
187
|
+
self._additional_toolsets: list["AbstractToolset[None] | str"] = []
|
|
167
188
|
self._conversation_history = conversation_history
|
|
168
189
|
self._conversation_history_reader = conversation_history_reader
|
|
169
190
|
self._conversation_history_writer = conversation_history_writer
|
|
@@ -179,18 +200,21 @@ class LLMTask(BaseTask):
|
|
|
179
200
|
)
|
|
180
201
|
self._max_call_iteration = max_call_iteration
|
|
181
202
|
self._conversation_context = conversation_context
|
|
203
|
+
self._yolo_mode = yolo_mode
|
|
204
|
+
self._render_yolo_mode = render_yolo_mode
|
|
205
|
+
self._attachment = attachment
|
|
182
206
|
|
|
183
|
-
def add_tool(self, *tool: ToolOrCallable):
|
|
207
|
+
def add_tool(self, *tool: "ToolOrCallable"):
|
|
184
208
|
self.append_tool(*tool)
|
|
185
209
|
|
|
186
|
-
def append_tool(self, *tool: ToolOrCallable):
|
|
210
|
+
def append_tool(self, *tool: "ToolOrCallable"):
|
|
187
211
|
for single_tool in tool:
|
|
188
212
|
self._additional_tools.append(single_tool)
|
|
189
213
|
|
|
190
|
-
def add_toolset(self, *toolset: "AbstractToolset[
|
|
214
|
+
def add_toolset(self, *toolset: "AbstractToolset[None] | str"):
|
|
191
215
|
self.append_toolset(*toolset)
|
|
192
216
|
|
|
193
|
-
def append_toolset(self, *toolset: "AbstractToolset[
|
|
217
|
+
def append_toolset(self, *toolset: "AbstractToolset[None] | str"):
|
|
194
218
|
for single_toolset in toolset:
|
|
195
219
|
self._additional_toolsets.append(single_toolset)
|
|
196
220
|
|
|
@@ -202,6 +226,12 @@ class LLMTask(BaseTask):
|
|
|
202
226
|
):
|
|
203
227
|
self._history_summarization_token_threshold = summarization_token_threshold
|
|
204
228
|
|
|
229
|
+
def set_workflows(self, workflows: StrListAttr):
|
|
230
|
+
self._workflows = workflows
|
|
231
|
+
|
|
232
|
+
def set_yolo_mode(self, yolo_mode: StrListAttr | BoolAttr):
|
|
233
|
+
self._yolo_mode = yolo_mode
|
|
234
|
+
|
|
205
235
|
async def _exec_action(self, ctx: AnyContext) -> Any:
|
|
206
236
|
# Get dependent configurations first
|
|
207
237
|
model_settings = get_model_settings(ctx, self._model_settings)
|
|
@@ -214,12 +244,18 @@ class LLMTask(BaseTask):
|
|
|
214
244
|
model_api_key_attr=self._model_api_key,
|
|
215
245
|
render_model_api_key=self._render_model_api_key,
|
|
216
246
|
)
|
|
247
|
+
yolo_mode = get_yolo_mode(
|
|
248
|
+
ctx=ctx,
|
|
249
|
+
yolo_mode_attr=self._yolo_mode,
|
|
250
|
+
render_yolo_mode=self._render_yolo_mode,
|
|
251
|
+
)
|
|
217
252
|
summarization_prompt = get_summarization_system_prompt(
|
|
218
253
|
ctx=ctx,
|
|
219
254
|
summarization_prompt_attr=self._summarization_prompt,
|
|
220
255
|
render_summarization_prompt=self._render_summarization_prompt,
|
|
221
256
|
)
|
|
222
257
|
user_message = get_user_message(ctx, self._message, self._render_message)
|
|
258
|
+
attachments = get_attachments(ctx, self._attachment)
|
|
223
259
|
# 1. Prepare initial state (read history from previous session)
|
|
224
260
|
conversation_history = await read_conversation_history(
|
|
225
261
|
ctx=ctx,
|
|
@@ -228,9 +264,9 @@ class LLMTask(BaseTask):
|
|
|
228
264
|
render_history_file=self._render_history_file,
|
|
229
265
|
conversation_history_attr=self._conversation_history,
|
|
230
266
|
)
|
|
231
|
-
conversation_history
|
|
267
|
+
inject_conversation_history_notes(conversation_history)
|
|
232
268
|
# 2. Get system prompt and user prompt
|
|
233
|
-
system_prompt,
|
|
269
|
+
system_prompt, user_prompt = get_system_and_user_prompt(
|
|
234
270
|
ctx=ctx,
|
|
235
271
|
user_message=user_message,
|
|
236
272
|
persona_attr=self._persona,
|
|
@@ -239,14 +275,15 @@ class LLMTask(BaseTask):
|
|
|
239
275
|
render_system_prompt=self._render_system_prompt,
|
|
240
276
|
special_instruction_prompt_attr=self._special_instruction_prompt,
|
|
241
277
|
render_special_instruction_prompt=self._render_special_instruction_prompt,
|
|
242
|
-
|
|
243
|
-
|
|
278
|
+
workflows_attr=self._workflows,
|
|
279
|
+
render_workflows=self._render_workflows,
|
|
244
280
|
conversation_history=conversation_history,
|
|
245
281
|
)
|
|
282
|
+
ctx.log_debug(f"SYSTEM PROMPT:\n{system_prompt}")
|
|
283
|
+
ctx.log_debug(f"USER PROMPT:\n{user_prompt}")
|
|
246
284
|
# 3. Get the agent instance
|
|
247
285
|
agent = get_agent(
|
|
248
286
|
ctx=ctx,
|
|
249
|
-
agent_attr=self._agent,
|
|
250
287
|
model=model,
|
|
251
288
|
system_prompt=system_prompt,
|
|
252
289
|
model_settings=model_settings,
|
|
@@ -254,15 +291,27 @@ class LLMTask(BaseTask):
|
|
|
254
291
|
additional_tools=self._additional_tools,
|
|
255
292
|
toolsets_attr=self._toolsets,
|
|
256
293
|
additional_toolsets=self._additional_toolsets,
|
|
294
|
+
yolo_mode=yolo_mode,
|
|
257
295
|
)
|
|
258
296
|
# 4. Run the agent iteration and save the results/history
|
|
259
297
|
result = await self._execute_agent(
|
|
260
|
-
ctx,
|
|
261
|
-
agent,
|
|
262
|
-
|
|
263
|
-
|
|
298
|
+
ctx=ctx,
|
|
299
|
+
agent=agent,
|
|
300
|
+
user_prompt=user_prompt,
|
|
301
|
+
attachments=attachments,
|
|
302
|
+
conversation_history=conversation_history,
|
|
264
303
|
)
|
|
265
304
|
# 5. Summarize
|
|
305
|
+
small_model = get_model(
|
|
306
|
+
ctx=ctx,
|
|
307
|
+
model_attr=self._small_model,
|
|
308
|
+
render_model=self._render_small_model,
|
|
309
|
+
model_base_url_attr=self._small_model_base_url,
|
|
310
|
+
render_model_base_url=self._render_small_model_base_url,
|
|
311
|
+
model_api_key_attr=self._small_model_api_key,
|
|
312
|
+
render_model_api_key=self._render_small_model_api_key,
|
|
313
|
+
)
|
|
314
|
+
small_model_settings = get_model_settings(ctx, self._small_model_settings)
|
|
266
315
|
conversation_history = await maybe_summarize_history(
|
|
267
316
|
ctx=ctx,
|
|
268
317
|
conversation_history=conversation_history,
|
|
@@ -274,8 +323,8 @@ class LLMTask(BaseTask):
|
|
|
274
323
|
render_history_summarization_token_threshold=(
|
|
275
324
|
self._render_history_summarization_token_threshold
|
|
276
325
|
),
|
|
277
|
-
model=
|
|
278
|
-
model_settings=
|
|
326
|
+
model=small_model,
|
|
327
|
+
model_settings=small_model_settings,
|
|
279
328
|
summarization_prompt=summarization_prompt,
|
|
280
329
|
rate_limitter=self._rate_limitter,
|
|
281
330
|
)
|
|
@@ -294,6 +343,7 @@ class LLMTask(BaseTask):
|
|
|
294
343
|
ctx: AnyContext,
|
|
295
344
|
agent: "Agent",
|
|
296
345
|
user_prompt: str,
|
|
346
|
+
attachments: "list[UserContent]",
|
|
297
347
|
conversation_history: ConversationHistory,
|
|
298
348
|
) -> Any:
|
|
299
349
|
"""Executes the agent, processes results, and saves history."""
|
|
@@ -302,6 +352,7 @@ class LLMTask(BaseTask):
|
|
|
302
352
|
ctx=ctx,
|
|
303
353
|
agent=agent,
|
|
304
354
|
user_prompt=user_prompt,
|
|
355
|
+
attachments=attachments,
|
|
305
356
|
history_list=conversation_history.history,
|
|
306
357
|
rate_limitter=self._rate_limitter,
|
|
307
358
|
)
|
|
@@ -313,7 +364,7 @@ class LLMTask(BaseTask):
|
|
|
313
364
|
ctx.xcom[xcom_usage_key] = Xcom([])
|
|
314
365
|
usage = agent_run.result.usage()
|
|
315
366
|
ctx.xcom[xcom_usage_key].push(usage)
|
|
316
|
-
ctx.print(stylize_faint(f"💸 Token: {usage}"), plain=True)
|
|
367
|
+
ctx.print(stylize_faint(f" 💸 Token: {usage}"), plain=True)
|
|
317
368
|
return agent_run.result.output
|
|
318
369
|
else:
|
|
319
370
|
ctx.log_warning("Agent run did not produce a result.")
|
zrb/task/make_task.py
CHANGED
|
@@ -2,7 +2,6 @@ from collections.abc import Callable
|
|
|
2
2
|
from typing import Any
|
|
3
3
|
|
|
4
4
|
from zrb.context.any_context import AnyContext
|
|
5
|
-
from zrb.context.any_shared_context import AnySharedContext
|
|
6
5
|
from zrb.env.any_env import AnyEnv
|
|
7
6
|
from zrb.group.any_group import AnyGroup
|
|
8
7
|
from zrb.input.any_input import AnyInput
|
|
@@ -18,7 +17,7 @@ def make_task(
|
|
|
18
17
|
cli_only: bool = False,
|
|
19
18
|
input: list[AnyInput | None] | AnyInput | None = None,
|
|
20
19
|
env: list[AnyEnv | None] | AnyEnv | None = None,
|
|
21
|
-
execute_condition: bool | str | Callable[[
|
|
20
|
+
execute_condition: bool | str | Callable[[AnyContext], bool] = True,
|
|
22
21
|
retries: int = 2,
|
|
23
22
|
retry_period: float = 0,
|
|
24
23
|
readiness_check: list[AnyTask] | AnyTask | None = None,
|
|
@@ -33,7 +32,7 @@ def make_task(
|
|
|
33
32
|
group: AnyGroup | None = None,
|
|
34
33
|
alias: str | None = None,
|
|
35
34
|
) -> Callable[[Callable[[AnyContext], Any]], AnyTask]:
|
|
36
|
-
def _make_task(fn: Callable[[AnyContext], Any]) ->
|
|
35
|
+
def _make_task(fn: Callable[[AnyContext], Any]) -> AnyTask:
|
|
37
36
|
task = BaseTask(
|
|
38
37
|
name=name,
|
|
39
38
|
color=color,
|
zrb/task/rsync_task.py
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
from
|
|
2
|
-
|
|
3
|
-
from zrb.attr.type import IntAttr, StrAttr
|
|
1
|
+
from zrb.attr.type import BoolAttr, IntAttr, StrAttr
|
|
4
2
|
from zrb.context.any_context import AnyContext
|
|
5
3
|
from zrb.env.any_env import AnyEnv
|
|
6
4
|
from zrb.input.any_input import AnyInput
|
|
@@ -17,8 +15,8 @@ class RsyncTask(CmdTask):
|
|
|
17
15
|
icon: str | None = None,
|
|
18
16
|
description: str | None = None,
|
|
19
17
|
cli_only: bool = False,
|
|
20
|
-
input: list[AnyInput] | AnyInput | None = None,
|
|
21
|
-
env: list[AnyEnv] | AnyEnv | None = None,
|
|
18
|
+
input: list[AnyInput | None] | AnyInput | None = None,
|
|
19
|
+
env: list[AnyEnv | None] | AnyEnv | None = None,
|
|
22
20
|
shell: StrAttr | None = None,
|
|
23
21
|
auto_render_shell: bool = True,
|
|
24
22
|
remote_host: StrAttr | None = None,
|
|
@@ -39,12 +37,14 @@ class RsyncTask(CmdTask):
|
|
|
39
37
|
render_local_source_path: bool = True,
|
|
40
38
|
local_destination_path: StrAttr | None = None,
|
|
41
39
|
render_local_destination_path: bool = True,
|
|
40
|
+
exclude_from: StrAttr | None = None,
|
|
41
|
+
render_exclude_from: bool = True,
|
|
42
42
|
cwd: str | None = None,
|
|
43
43
|
render_cwd: bool = True,
|
|
44
44
|
plain_print: bool = False,
|
|
45
45
|
max_output_line: int = 1000,
|
|
46
46
|
max_error_line: int = 1000,
|
|
47
|
-
execute_condition:
|
|
47
|
+
execute_condition: BoolAttr = True,
|
|
48
48
|
retries: int = 2,
|
|
49
49
|
retry_period: float = 0,
|
|
50
50
|
readiness_check: list[AnyTask] | AnyTask | None = None,
|
|
@@ -93,6 +93,8 @@ class RsyncTask(CmdTask):
|
|
|
93
93
|
self._render_local_source_path = render_local_source_path
|
|
94
94
|
self._local_destination_path = local_destination_path
|
|
95
95
|
self._render_local_destination_path = render_local_destination_path
|
|
96
|
+
self._exclude_from = exclude_from
|
|
97
|
+
self._render_exclude_from = render_exclude_from
|
|
96
98
|
|
|
97
99
|
def _get_source_path(self, ctx: AnyContext) -> str:
|
|
98
100
|
local_source_path = self._get_local_source_path(ctx)
|
|
@@ -144,16 +146,29 @@ class RsyncTask(CmdTask):
|
|
|
144
146
|
auto_render=self._render_local_destination_path,
|
|
145
147
|
)
|
|
146
148
|
|
|
149
|
+
def _get_exclude_from_param(self, ctx: AnyContext) -> str:
|
|
150
|
+
exclude_from = get_str_attr(
|
|
151
|
+
ctx,
|
|
152
|
+
self._exclude_from,
|
|
153
|
+
"",
|
|
154
|
+
auto_render=self._render_exclude_from,
|
|
155
|
+
).strip()
|
|
156
|
+
if exclude_from == "":
|
|
157
|
+
return ""
|
|
158
|
+
return f"--exclude-from='{exclude_from}'"
|
|
159
|
+
|
|
147
160
|
def _get_cmd_script(self, ctx: AnyContext) -> str:
|
|
148
161
|
port = self._get_remote_port(ctx)
|
|
149
162
|
password = self._get_remote_password(ctx)
|
|
150
163
|
key = self._get_remote_ssh_key(ctx)
|
|
151
164
|
src = self._get_source_path(ctx)
|
|
152
165
|
dst = self._get_destination_path(ctx)
|
|
166
|
+
exclude_from = self._get_exclude_from_param(ctx)
|
|
167
|
+
exclude_from_with_space = f"{exclude_from} " if exclude_from != "" else ""
|
|
153
168
|
if key != "" and password != "":
|
|
154
|
-
return f'sshpass -p "$_ZRB_SSH_PASSWORD" rsync --mkpath -avz -e "ssh -i {key} -p {port}" {src} {dst}' # noqa
|
|
169
|
+
return f'sshpass -p "$_ZRB_SSH_PASSWORD" rsync --mkpath -avz -e "ssh -i {key} -p {port}" {exclude_from_with_space}{src} {dst}' # noqa
|
|
155
170
|
if key != "":
|
|
156
|
-
return f'rsync --mkpath -avz -e "ssh -i {key} -p {port}" {src} {dst}'
|
|
171
|
+
return f'rsync --mkpath -avz -e "ssh -i {key} -p {port}" {exclude_from_with_space}{src} {dst}' # noqa
|
|
157
172
|
if password != "":
|
|
158
|
-
return f'sshpass -p "$_ZRB_SSH_PASSWORD" rsync --mkpath -avz -e "ssh -p {port}" {src} {dst}' # noqa
|
|
159
|
-
return f'rsync --mkpath -avz -e "ssh -p {port}" {src} {dst}'
|
|
173
|
+
return f'sshpass -p "$_ZRB_SSH_PASSWORD" rsync --mkpath -avz -e "ssh -p {port}" {exclude_from_with_space}{src} {dst}' # noqa
|
|
174
|
+
return f'rsync --mkpath -avz -e "ssh -p {port}" {exclude_from_with_space}{src} {dst}'
|
zrb/task/scheduler.py
CHANGED
|
@@ -24,8 +24,8 @@ class Scheduler(BaseTrigger):
|
|
|
24
24
|
cli_only: bool = False,
|
|
25
25
|
input: list[AnyInput | None] | AnyInput | None = None,
|
|
26
26
|
env: list[AnyEnv | None] | AnyEnv | None = None,
|
|
27
|
-
schedule: StrAttr = None,
|
|
28
|
-
execute_condition: bool | str | Callable[[
|
|
27
|
+
schedule: StrAttr | None = None,
|
|
28
|
+
execute_condition: bool | str | Callable[[AnyContext], bool] = True,
|
|
29
29
|
queue_name: fstring | None = None,
|
|
30
30
|
callback: list[AnyCallback] | AnyCallback = [],
|
|
31
31
|
retries: int = 2,
|
|
@@ -76,6 +76,6 @@ class Scheduler(BaseTrigger):
|
|
|
76
76
|
ctx.print(f"Current time: {now}")
|
|
77
77
|
if match_cron(cron_pattern, now):
|
|
78
78
|
ctx.print(f"Matching {now} with pattern: {cron_pattern}")
|
|
79
|
-
|
|
80
|
-
|
|
79
|
+
if ctx.session is not None:
|
|
80
|
+
self.push_exchange_xcom(ctx.session, now)
|
|
81
81
|
await asyncio.sleep(60)
|
zrb/util/attr.py
CHANGED
|
@@ -9,52 +9,54 @@ from zrb.attr.type import (
|
|
|
9
9
|
StrDictAttr,
|
|
10
10
|
StrListAttr,
|
|
11
11
|
)
|
|
12
|
-
from zrb.context.
|
|
12
|
+
from zrb.context.any_context import AnyContext
|
|
13
13
|
from zrb.util.string.conversion import to_boolean
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
def get_str_list_attr(
|
|
17
|
-
|
|
17
|
+
ctx: AnyContext, attr: StrListAttr | None, auto_render: bool = True
|
|
18
18
|
) -> list[str]:
|
|
19
19
|
"""
|
|
20
20
|
Retrieve a list of strings from shared context attributes.
|
|
21
21
|
|
|
22
22
|
Args:
|
|
23
|
-
|
|
23
|
+
ctx (AnyContext): The shared context object.
|
|
24
24
|
attr (StrListAttr | None): The string list attribute to retrieve.
|
|
25
25
|
auto_render (bool): Whether to auto-render the attribute values.
|
|
26
26
|
|
|
27
27
|
Returns:
|
|
28
28
|
list[str]: A list of string attributes.
|
|
29
29
|
"""
|
|
30
|
+
if attr is None:
|
|
31
|
+
return []
|
|
30
32
|
if callable(attr):
|
|
31
|
-
return attr(
|
|
32
|
-
return
|
|
33
|
+
return attr(ctx)
|
|
34
|
+
return [get_str_attr(ctx, val, "", auto_render) for val in attr]
|
|
33
35
|
|
|
34
36
|
|
|
35
37
|
def get_str_dict_attr(
|
|
36
|
-
|
|
38
|
+
ctx: AnyContext, attr: StrDictAttr | None, auto_render: bool = True
|
|
37
39
|
) -> dict[str, Any]:
|
|
38
40
|
"""
|
|
39
41
|
Retrieve a dictionary of strings from shared context attributes.
|
|
40
42
|
|
|
41
43
|
Args:
|
|
42
|
-
|
|
44
|
+
ctx (AnyContext): The shared context object.
|
|
43
45
|
attr (StrDictAttr | None): The string dictionary attribute to retrieve.
|
|
44
46
|
auto_render (bool): Whether to auto-render the attribute values.
|
|
45
47
|
|
|
46
48
|
Returns:
|
|
47
49
|
dict[str, Any]: A dictionary of string attributes.
|
|
48
50
|
"""
|
|
51
|
+
if attr is None:
|
|
52
|
+
return {}
|
|
49
53
|
if callable(attr):
|
|
50
|
-
return attr(
|
|
51
|
-
return {
|
|
52
|
-
key: get_str_attr(shared_ctx, val, "", auto_render) for key, val in attr.items()
|
|
53
|
-
}
|
|
54
|
+
return attr(ctx)
|
|
55
|
+
return {key: get_str_attr(ctx, val, "", auto_render) for key, val in attr.items()}
|
|
54
56
|
|
|
55
57
|
|
|
56
58
|
def get_str_attr(
|
|
57
|
-
|
|
59
|
+
ctx: AnyContext,
|
|
58
60
|
attr: StrAttr | None,
|
|
59
61
|
default: StrAttr = "",
|
|
60
62
|
auto_render: bool = True,
|
|
@@ -63,7 +65,7 @@ def get_str_attr(
|
|
|
63
65
|
Retrieve a string from shared context attributes.
|
|
64
66
|
|
|
65
67
|
Args:
|
|
66
|
-
|
|
68
|
+
ctx (AnyContext): The shared context object.
|
|
67
69
|
attr (StrAttr | None): The string attribute to retrieve.
|
|
68
70
|
default (StrAttr): The default value if the attribute is None.
|
|
69
71
|
auto_render (bool): Whether to auto-render the attribute value.
|
|
@@ -71,14 +73,16 @@ def get_str_attr(
|
|
|
71
73
|
Returns:
|
|
72
74
|
str: The string attribute value.
|
|
73
75
|
"""
|
|
74
|
-
val = get_attr(
|
|
75
|
-
if
|
|
76
|
-
return
|
|
77
|
-
|
|
76
|
+
val = get_attr(ctx, attr, default, auto_render)
|
|
77
|
+
if isinstance(val, str):
|
|
78
|
+
return val
|
|
79
|
+
if val is None:
|
|
80
|
+
return ""
|
|
81
|
+
return str(val)
|
|
78
82
|
|
|
79
83
|
|
|
80
84
|
def get_bool_attr(
|
|
81
|
-
|
|
85
|
+
ctx: AnyContext,
|
|
82
86
|
attr: BoolAttr | None,
|
|
83
87
|
default: BoolAttr = False,
|
|
84
88
|
auto_render: bool = True,
|
|
@@ -87,7 +91,7 @@ def get_bool_attr(
|
|
|
87
91
|
Retrieve a boolean from shared context attributes.
|
|
88
92
|
|
|
89
93
|
Args:
|
|
90
|
-
|
|
94
|
+
ctx (AnyContext): The shared context object.
|
|
91
95
|
attr (BoolAttr | None): The boolean attribute to retrieve.
|
|
92
96
|
default (BoolAttr): The default value if the attribute is None.
|
|
93
97
|
auto_render (bool): Whether to auto-render the attribute value if it's a string.
|
|
@@ -95,14 +99,16 @@ def get_bool_attr(
|
|
|
95
99
|
Returns:
|
|
96
100
|
bool: The boolean attribute value.
|
|
97
101
|
"""
|
|
98
|
-
val = get_attr(
|
|
99
|
-
if isinstance(val,
|
|
100
|
-
return
|
|
101
|
-
|
|
102
|
+
val = get_attr(ctx, attr, default, auto_render)
|
|
103
|
+
if isinstance(val, bool):
|
|
104
|
+
return val
|
|
105
|
+
if val is None:
|
|
106
|
+
return False
|
|
107
|
+
return to_boolean(val)
|
|
102
108
|
|
|
103
109
|
|
|
104
110
|
def get_int_attr(
|
|
105
|
-
|
|
111
|
+
ctx: AnyContext,
|
|
106
112
|
attr: IntAttr | None,
|
|
107
113
|
default: IntAttr = 0,
|
|
108
114
|
auto_render: bool = True,
|
|
@@ -111,7 +117,7 @@ def get_int_attr(
|
|
|
111
117
|
Retrieve an integer from shared context attributes.
|
|
112
118
|
|
|
113
119
|
Args:
|
|
114
|
-
|
|
120
|
+
ctx (AnyContext): The shared context object.
|
|
115
121
|
attr (IntAttr | None): The integer attribute to retrieve.
|
|
116
122
|
default (IntAttr): The default value if the attribute is None.
|
|
117
123
|
auto_render (bool): Whether to auto-render the attribute value if it's a string.
|
|
@@ -119,14 +125,16 @@ def get_int_attr(
|
|
|
119
125
|
Returns:
|
|
120
126
|
int: The integer attribute value.
|
|
121
127
|
"""
|
|
122
|
-
val = get_attr(
|
|
123
|
-
if isinstance(val,
|
|
124
|
-
return
|
|
125
|
-
|
|
128
|
+
val = get_attr(ctx, attr, default, auto_render)
|
|
129
|
+
if isinstance(val, int):
|
|
130
|
+
return val
|
|
131
|
+
if val is None:
|
|
132
|
+
return 0
|
|
133
|
+
return int(val)
|
|
126
134
|
|
|
127
135
|
|
|
128
136
|
def get_float_attr(
|
|
129
|
-
|
|
137
|
+
ctx: AnyContext,
|
|
130
138
|
attr: FloatAttr | None,
|
|
131
139
|
default: FloatAttr = 0.0,
|
|
132
140
|
auto_render: bool = True,
|
|
@@ -135,7 +143,7 @@ def get_float_attr(
|
|
|
135
143
|
Retrieve a float from shared context attributes.
|
|
136
144
|
|
|
137
145
|
Args:
|
|
138
|
-
|
|
146
|
+
ctx (AnyContext): The shared context object.
|
|
139
147
|
attr (FloatAttr | None): The float attribute to retrieve.
|
|
140
148
|
default (FloatAttr): The default value if the attribute is None.
|
|
141
149
|
auto_render (bool): Whether to auto-render the attribute value if it's a string.
|
|
@@ -143,14 +151,16 @@ def get_float_attr(
|
|
|
143
151
|
Returns:
|
|
144
152
|
float | None: The float attribute value.
|
|
145
153
|
"""
|
|
146
|
-
val = get_attr(
|
|
147
|
-
if isinstance(val,
|
|
148
|
-
return
|
|
149
|
-
|
|
154
|
+
val = get_attr(ctx, attr, default, auto_render)
|
|
155
|
+
if isinstance(val, (int, float)):
|
|
156
|
+
return val
|
|
157
|
+
if val is None:
|
|
158
|
+
return 0.0
|
|
159
|
+
return float(val)
|
|
150
160
|
|
|
151
161
|
|
|
152
162
|
def get_attr(
|
|
153
|
-
|
|
163
|
+
ctx: AnyContext,
|
|
154
164
|
attr: AnyAttr,
|
|
155
165
|
default: AnyAttr,
|
|
156
166
|
auto_render: bool = True,
|
|
@@ -159,7 +169,7 @@ def get_attr(
|
|
|
159
169
|
Retrieve an attribute value from shared context, handling callables and rendering.
|
|
160
170
|
|
|
161
171
|
Args:
|
|
162
|
-
|
|
172
|
+
ctx (AnyContext): The shared context object.
|
|
163
173
|
attr (AnyAttr): The attribute to retrieve. Can be a value, a callable,
|
|
164
174
|
or a string to render.
|
|
165
175
|
default (AnyAttr): The default value if the attribute is None.
|
|
@@ -170,10 +180,10 @@ def get_attr(
|
|
|
170
180
|
"""
|
|
171
181
|
if attr is None:
|
|
172
182
|
if callable(default):
|
|
173
|
-
return default(
|
|
183
|
+
return default(ctx)
|
|
174
184
|
return default
|
|
175
185
|
if callable(attr):
|
|
176
|
-
return attr(
|
|
186
|
+
return attr(ctx)
|
|
177
187
|
if isinstance(attr, str) and auto_render:
|
|
178
|
-
return
|
|
188
|
+
return ctx.render(attr)
|
|
179
189
|
return attr
|