zrb 1.15.5__py3-none-any.whl → 1.15.6__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/builtin/llm/tool/sub_agent.py +2 -3
- zrb/config/config.py +11 -2
- zrb/config/llm_rate_limitter.py +51 -40
- zrb/context/context.py +1 -1
- zrb/context/shared_context.py +1 -5
- zrb/input/any_input.py +5 -1
- zrb/input/base_input.py +8 -4
- zrb/runner/cli.py +19 -18
- zrb/runner/common_util.py +24 -19
- zrb/runner/web_route/task_input_api_route.py +5 -5
- zrb/task/any_task.py +10 -2
- zrb/task/base/context.py +16 -8
- zrb/task/base/lifecycle.py +8 -4
- zrb/task/base_task.py +54 -4
- zrb/task/llm/agent.py +8 -2
- zrb/task/llm/history_summarization.py +2 -1
- zrb/task/llm/tool_wrapper.py +13 -7
- zrb/task/llm_task.py +1 -0
- zrb/util/truncate.py +23 -0
- {zrb-1.15.5.dist-info → zrb-1.15.6.dist-info}/METADATA +2 -1
- {zrb-1.15.5.dist-info → zrb-1.15.6.dist-info}/RECORD +23 -22
- {zrb-1.15.5.dist-info → zrb-1.15.6.dist-info}/WHEEL +0 -0
- {zrb-1.15.5.dist-info → zrb-1.15.6.dist-info}/entry_points.txt +0 -0
@@ -118,9 +118,8 @@ def create_sub_agent_tool(
|
|
118
118
|
if sub_agent_run and sub_agent_run.result:
|
119
119
|
# Return the final message content as a string
|
120
120
|
return json.dumps({"result": sub_agent_run.result.output})
|
121
|
-
|
122
|
-
|
123
|
-
return "Sub-agent failed to produce a result."
|
121
|
+
ctx.log_warning("Sub-agent run did not produce a result.")
|
122
|
+
raise ValueError(f"{tool_name} not returning any result")
|
124
123
|
|
125
124
|
# Set the name and docstring for the callable function
|
126
125
|
run_sub_agent.__name__ = tool_name
|
zrb/config/config.py
CHANGED
@@ -102,6 +102,7 @@ class Config:
|
|
102
102
|
level = level.upper()
|
103
103
|
log_levels = {
|
104
104
|
"CRITICAL": logging.CRITICAL, # 50
|
105
|
+
"FATAL": logging.CRITICAL, # 50
|
105
106
|
"ERROR": logging.ERROR, # 40
|
106
107
|
"WARN": logging.WARNING, # 30
|
107
108
|
"WARNING": logging.WARNING, # 30
|
@@ -282,7 +283,7 @@ class Config:
|
|
282
283
|
Maximum number of LLM requests allowed per minute.
|
283
284
|
Default is conservative to accommodate free-tier LLM providers.
|
284
285
|
"""
|
285
|
-
return int(self._getenv("LLM_MAX_REQUESTS_PER_MINUTE", "
|
286
|
+
return int(self._getenv("LLM_MAX_REQUESTS_PER_MINUTE", "60"))
|
286
287
|
|
287
288
|
@property
|
288
289
|
def LLM_MAX_TOKENS_PER_MINUTE(self) -> int:
|
@@ -295,7 +296,7 @@ class Config:
|
|
295
296
|
@property
|
296
297
|
def LLM_MAX_TOKENS_PER_REQUEST(self) -> int:
|
297
298
|
"""Maximum number of tokens allowed per individual LLM request."""
|
298
|
-
return int(self._getenv("LLM_MAX_TOKENS_PER_REQUEST", "
|
299
|
+
return int(self._getenv("LLM_MAX_TOKENS_PER_REQUEST", "100000"))
|
299
300
|
|
300
301
|
@property
|
301
302
|
def LLM_THROTTLE_SLEEP(self) -> float:
|
@@ -435,5 +436,13 @@ class Config:
|
|
435
436
|
def LLM_CONTEXT_FILE(self) -> str:
|
436
437
|
return self._getenv("LLM_CONTEXT_FILE", "ZRB.md")
|
437
438
|
|
439
|
+
@property
|
440
|
+
def USE_TIKTOKEN(self) -> bool:
|
441
|
+
return to_boolean(self._getenv("USE_TIKTOKEN", "true"))
|
442
|
+
|
443
|
+
@property
|
444
|
+
def TIKTOKEN_ENCODING_NAME(self) -> str:
|
445
|
+
return self._getenv("TIKTOKEN_ENCODING_NAME", "cl100k_base")
|
446
|
+
|
438
447
|
|
439
448
|
CFG = Config()
|
zrb/config/llm_rate_limitter.py
CHANGED
@@ -3,27 +3,9 @@ import time
|
|
3
3
|
from collections import deque
|
4
4
|
from typing import Callable
|
5
5
|
|
6
|
-
import tiktoken
|
7
|
-
|
8
6
|
from zrb.config.config import CFG
|
9
7
|
|
10
8
|
|
11
|
-
def _estimate_token(text: str) -> int:
|
12
|
-
"""
|
13
|
-
Estimates the number of tokens in a given text.
|
14
|
-
Tries to use the 'gpt-4o' model's tokenizer for an accurate count.
|
15
|
-
If the tokenizer is unavailable (e.g., due to network issues),
|
16
|
-
it falls back to a heuristic of 4 characters per token.
|
17
|
-
"""
|
18
|
-
try:
|
19
|
-
# Primary method: Use tiktoken for an accurate count
|
20
|
-
enc = tiktoken.encoding_for_model("gpt-4o")
|
21
|
-
return len(enc.encode(text))
|
22
|
-
except Exception:
|
23
|
-
# Fallback method: Heuristic (4 characters per token)
|
24
|
-
return len(text) // 4
|
25
|
-
|
26
|
-
|
27
9
|
class LLMRateLimiter:
|
28
10
|
"""
|
29
11
|
Helper class to enforce LLM API rate limits and throttling.
|
@@ -36,13 +18,15 @@ class LLMRateLimiter:
|
|
36
18
|
max_tokens_per_minute: int | None = None,
|
37
19
|
max_tokens_per_request: int | None = None,
|
38
20
|
throttle_sleep: float | None = None,
|
39
|
-
|
21
|
+
use_tiktoken: bool | None = None,
|
22
|
+
tiktoken_encodeing_name: str | None = None,
|
40
23
|
):
|
41
24
|
self._max_requests_per_minute = max_requests_per_minute
|
42
25
|
self._max_tokens_per_minute = max_tokens_per_minute
|
43
26
|
self._max_tokens_per_request = max_tokens_per_request
|
44
27
|
self._throttle_sleep = throttle_sleep
|
45
|
-
self.
|
28
|
+
self._use_tiktoken = use_tiktoken
|
29
|
+
self._tiktoken_encoding_name = tiktoken_encodeing_name
|
46
30
|
self.request_times = deque()
|
47
31
|
self.token_times = deque()
|
48
32
|
|
@@ -71,10 +55,16 @@ class LLMRateLimiter:
|
|
71
55
|
return CFG.LLM_THROTTLE_SLEEP
|
72
56
|
|
73
57
|
@property
|
74
|
-
def
|
75
|
-
if self.
|
76
|
-
return self.
|
77
|
-
return
|
58
|
+
def use_tiktoken(self) -> bool:
|
59
|
+
if self._use_tiktoken is not None:
|
60
|
+
return self._use_tiktoken
|
61
|
+
return CFG.USE_TIKTOKEN
|
62
|
+
|
63
|
+
@property
|
64
|
+
def tiktoken_encoding_name(self) -> str:
|
65
|
+
if self._tiktoken_encoding_name is not None:
|
66
|
+
return self._tiktoken_encoding_name
|
67
|
+
return CFG.TIKTOKEN_ENCODING_NAME
|
78
68
|
|
79
69
|
def set_max_requests_per_minute(self, value: int):
|
80
70
|
self._max_requests_per_minute = value
|
@@ -88,24 +78,43 @@ class LLMRateLimiter:
|
|
88
78
|
def set_throttle_sleep(self, value: float):
|
89
79
|
self._throttle_sleep = value
|
90
80
|
|
91
|
-
def
|
92
|
-
self.
|
81
|
+
def count_token(self, prompt: str) -> int:
|
82
|
+
if not self.use_tiktoken:
|
83
|
+
return self._fallback_count_token(prompt)
|
84
|
+
try:
|
85
|
+
import tiktoken
|
86
|
+
|
87
|
+
enc = tiktoken.get_encoding(self.tiktoken_encoding_name)
|
88
|
+
return len(enc.encode(prompt))
|
89
|
+
except Exception:
|
90
|
+
return self._fallback_count_token(prompt)
|
91
|
+
|
92
|
+
def _fallback_count_token(self, prompt: str) -> int:
|
93
|
+
return len(prompt) // 4
|
93
94
|
|
94
95
|
def clip_prompt(self, prompt: str, limit: int) -> str:
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
96
|
+
if not self.use_tiktoken:
|
97
|
+
return self._fallback_clip_prompt(prompt, limit)
|
98
|
+
try:
|
99
|
+
import tiktoken
|
100
|
+
|
101
|
+
enc = tiktoken.get_encoding("cl100k_base")
|
102
|
+
tokens = enc.encode(prompt)
|
103
|
+
if len(tokens) <= limit:
|
104
|
+
return prompt
|
105
|
+
truncated = tokens[: limit - 3]
|
106
|
+
clipped_text = enc.decode(truncated)
|
107
|
+
return clipped_text + "..."
|
108
|
+
except Exception:
|
109
|
+
return self._fallback_clip_prompt(prompt, limit)
|
110
|
+
|
111
|
+
def _fallback_clip_prompt(self, prompt: str, limit: int) -> str:
|
112
|
+
char_limit = limit * 4 if limit * 4 <= 10 else limit * 4 - 10
|
113
|
+
return prompt[:char_limit] + "..."
|
114
|
+
|
115
|
+
async def throttle(
|
116
|
+
self, prompt: str, throttle_notif_callback: Callable | None = None
|
117
|
+
):
|
109
118
|
now = time.time()
|
110
119
|
tokens = self.count_token(prompt)
|
111
120
|
# Clean up old entries
|
@@ -123,6 +132,8 @@ class LLMRateLimiter:
|
|
123
132
|
len(self.request_times) >= self.max_requests_per_minute
|
124
133
|
or sum(t for _, t in self.token_times) + tokens > self.max_tokens_per_minute
|
125
134
|
):
|
135
|
+
if throttle_notif_callback is not None:
|
136
|
+
throttle_notif_callback()
|
126
137
|
await asyncio.sleep(self.throttle_sleep)
|
127
138
|
now = time.time()
|
128
139
|
while self.request_times and now - self.request_times[0] > 60:
|
zrb/context/context.py
CHANGED
zrb/context/shared_context.py
CHANGED
@@ -40,11 +40,7 @@ class SharedContext(AnySharedContext):
|
|
40
40
|
|
41
41
|
def __repr__(self):
|
42
42
|
class_name = self.__class__.__name__
|
43
|
-
|
44
|
-
args = self._args
|
45
|
-
env = self._env
|
46
|
-
xcom = self._xcom
|
47
|
-
return f"<{class_name} input={input} args={args} xcom={xcom} env={env}>"
|
43
|
+
return f"<{class_name}>"
|
48
44
|
|
49
45
|
@property
|
50
46
|
def is_web_mode(self) -> bool:
|
zrb/input/any_input.py
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
from abc import ABC, abstractmethod
|
2
|
+
from typing import Any
|
2
3
|
|
3
4
|
from zrb.context.any_shared_context import AnySharedContext
|
4
5
|
|
@@ -35,7 +36,10 @@ class AnyInput(ABC):
|
|
35
36
|
|
36
37
|
@abstractmethod
|
37
38
|
def update_shared_context(
|
38
|
-
self,
|
39
|
+
self,
|
40
|
+
shared_ctx: AnySharedContext,
|
41
|
+
str_value: str | None = None,
|
42
|
+
value: Any = None,
|
39
43
|
):
|
40
44
|
pass
|
41
45
|
|
zrb/input/base_input.py
CHANGED
@@ -58,11 +58,15 @@ class BaseInput(AnyInput):
|
|
58
58
|
return f'<input name="{name}" placeholder="{description}" value="{default}" />'
|
59
59
|
|
60
60
|
def update_shared_context(
|
61
|
-
self,
|
61
|
+
self,
|
62
|
+
shared_ctx: AnySharedContext,
|
63
|
+
str_value: str | None = None,
|
64
|
+
value: Any = None,
|
62
65
|
):
|
63
|
-
if
|
64
|
-
str_value
|
65
|
-
|
66
|
+
if value is None:
|
67
|
+
if str_value is None:
|
68
|
+
str_value = self.get_default_str(shared_ctx)
|
69
|
+
value = self._parse_str_value(str_value)
|
66
70
|
if self.name in shared_ctx.input:
|
67
71
|
raise ValueError(f"Input already defined in the context: {self.name}")
|
68
72
|
shared_ctx.input[self.name] = value
|
zrb/runner/cli.py
CHANGED
@@ -7,7 +7,7 @@ from zrb.context.any_context import AnyContext
|
|
7
7
|
from zrb.context.shared_context import SharedContext
|
8
8
|
from zrb.group.any_group import AnyGroup
|
9
9
|
from zrb.group.group import Group
|
10
|
-
from zrb.runner.common_util import
|
10
|
+
from zrb.runner.common_util import get_task_str_kwargs
|
11
11
|
from zrb.session.session import Session
|
12
12
|
from zrb.session_state_logger.session_state_logger_factory import session_state_logger
|
13
13
|
from zrb.task.any_task import AnyTask
|
@@ -38,23 +38,25 @@ class Cli(Group):
|
|
38
38
|
def banner(self) -> str:
|
39
39
|
return CFG.BANNER
|
40
40
|
|
41
|
-
def run(self,
|
42
|
-
|
43
|
-
node, node_path,
|
41
|
+
def run(self, str_args: list[str] = []):
|
42
|
+
str_kwargs, str_args = self._extract_kwargs_from_args(str_args)
|
43
|
+
node, node_path, str_args = extract_node_from_args(self, str_args)
|
44
44
|
if isinstance(node, AnyGroup):
|
45
45
|
self._show_group_info(node)
|
46
46
|
return
|
47
|
-
if "h" in
|
47
|
+
if "h" in str_kwargs or "help" in str_kwargs:
|
48
48
|
self._show_task_info(node)
|
49
49
|
return
|
50
|
-
|
50
|
+
task_str_kwargs = get_task_str_kwargs(
|
51
|
+
task=node, str_args=str_args, str_kwargs=str_kwargs, cli_mode=True
|
52
|
+
)
|
51
53
|
try:
|
52
|
-
result = self._run_task(node,
|
54
|
+
result = self._run_task(node, str_args, task_str_kwargs)
|
53
55
|
if result is not None:
|
54
56
|
print(result)
|
55
57
|
return result
|
56
58
|
finally:
|
57
|
-
run_command = self._get_run_command(node_path,
|
59
|
+
run_command = self._get_run_command(node_path, task_str_kwargs)
|
58
60
|
self._print_run_command(run_command)
|
59
61
|
|
60
62
|
def _print_run_command(self, run_command: str):
|
@@ -64,11 +66,14 @@ class Cli(Group):
|
|
64
66
|
file=sys.stderr,
|
65
67
|
)
|
66
68
|
|
67
|
-
def _get_run_command(
|
69
|
+
def _get_run_command(
|
70
|
+
self, node_path: list[str], task_str_kwargs: dict[str, str]
|
71
|
+
) -> str:
|
68
72
|
parts = [self.name] + node_path
|
69
|
-
if len(
|
73
|
+
if len(task_str_kwargs) > 0:
|
70
74
|
parts += [
|
71
|
-
self._get_run_command_param(key, val)
|
75
|
+
self._get_run_command_param(key, val)
|
76
|
+
for key, val in task_str_kwargs.items()
|
72
77
|
]
|
73
78
|
return " ".join(parts)
|
74
79
|
|
@@ -81,13 +86,9 @@ class Cli(Group):
|
|
81
86
|
self, task: AnyTask, args: list[str], run_kwargs: dict[str, str]
|
82
87
|
) -> tuple[Any]:
|
83
88
|
shared_ctx = SharedContext(args=args)
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
shared_ctx, run_kwargs[task_input.name]
|
88
|
-
)
|
89
|
-
continue
|
90
|
-
return task.run(Session(shared_ctx=shared_ctx, root_group=self))
|
89
|
+
return task.run(
|
90
|
+
Session(shared_ctx=shared_ctx, root_group=self), str_kwargs=run_kwargs
|
91
|
+
)
|
91
92
|
|
92
93
|
def _show_task_info(self, task: AnyTask):
|
93
94
|
description = task.description
|
zrb/runner/common_util.py
CHANGED
@@ -1,31 +1,36 @@
|
|
1
|
-
from typing import Any
|
2
|
-
|
3
1
|
from zrb.context.shared_context import SharedContext
|
4
2
|
from zrb.task.any_task import AnyTask
|
5
3
|
|
6
4
|
|
7
|
-
def
|
8
|
-
task: AnyTask,
|
5
|
+
def get_task_str_kwargs(
|
6
|
+
task: AnyTask, str_args: list[str], str_kwargs: dict[str, str], cli_mode: bool
|
9
7
|
) -> dict[str, str]:
|
10
8
|
arg_index = 0
|
11
|
-
|
12
|
-
|
13
|
-
shared_ctx = SharedContext(args=args)
|
9
|
+
dummmy_shared_ctx = SharedContext()
|
10
|
+
task_str_kwargs = {}
|
14
11
|
for task_input in task.inputs:
|
12
|
+
task_name = task_input.name
|
15
13
|
if task_input.name in str_kwargs:
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
14
|
+
task_str_kwargs[task_input.name] = str_kwargs[task_name]
|
15
|
+
# Update dummy shared context for next input default value
|
16
|
+
task_input.update_shared_context(
|
17
|
+
dummmy_shared_ctx, str_value=str_kwargs[task_name]
|
18
|
+
)
|
19
|
+
elif arg_index < len(str_args) and task_input.allow_positional_parsing:
|
20
|
+
task_str_kwargs[task_name] = str_args[arg_index]
|
21
|
+
# Update dummy shared context for next input default value
|
22
|
+
task_input.update_shared_context(
|
23
|
+
dummmy_shared_ctx, str_value=task_str_kwargs[task_name]
|
24
|
+
)
|
22
25
|
arg_index += 1
|
23
26
|
else:
|
24
27
|
if cli_mode and task_input.always_prompt:
|
25
|
-
str_value = task_input.prompt_cli_str(
|
28
|
+
str_value = task_input.prompt_cli_str(dummmy_shared_ctx)
|
26
29
|
else:
|
27
|
-
str_value = task_input.get_default_str(
|
28
|
-
|
29
|
-
# Update shared context for next input default value
|
30
|
-
task_input.update_shared_context(
|
31
|
-
|
30
|
+
str_value = task_input.get_default_str(dummmy_shared_ctx)
|
31
|
+
task_str_kwargs[task_name] = str_value
|
32
|
+
# Update dummy shared context for next input default value
|
33
|
+
task_input.update_shared_context(
|
34
|
+
dummmy_shared_ctx, str_value=task_str_kwargs[task_name]
|
35
|
+
)
|
36
|
+
return task_str_kwargs
|
@@ -3,7 +3,7 @@ from typing import TYPE_CHECKING
|
|
3
3
|
|
4
4
|
from zrb.config.web_auth_config import WebAuthConfig
|
5
5
|
from zrb.group.any_group import AnyGroup
|
6
|
-
from zrb.runner.common_util import
|
6
|
+
from zrb.runner.common_util import get_task_str_kwargs
|
7
7
|
from zrb.runner.web_util.user import get_user_from_request
|
8
8
|
from zrb.task.any_task import AnyTask
|
9
9
|
from zrb.util.group import NodeNotFoundError, extract_node_from_args
|
@@ -39,9 +39,9 @@ def serve_task_input_api(
|
|
39
39
|
if isinstance(task, AnyTask):
|
40
40
|
if not user.can_access_task(task):
|
41
41
|
return JSONResponse(content={"detail": "Forbidden"}, status_code=403)
|
42
|
-
|
43
|
-
|
44
|
-
task=task,
|
42
|
+
str_kwargs = json.loads(query)
|
43
|
+
task_str_kwargs = get_task_str_kwargs(
|
44
|
+
task=task, str_args=[], str_kwargs=str_kwargs, cli_mode=False
|
45
45
|
)
|
46
|
-
return
|
46
|
+
return task_str_kwargs
|
47
47
|
return JSONResponse(content={"detail": "Not found"}, status_code=404)
|
zrb/task/any_task.py
CHANGED
@@ -148,13 +148,17 @@ class AnyTask(ABC):
|
|
148
148
|
|
149
149
|
@abstractmethod
|
150
150
|
def run(
|
151
|
-
self,
|
151
|
+
self,
|
152
|
+
session: "AnySession | None" = None,
|
153
|
+
str_kwargs: dict[str, str] | None = None,
|
154
|
+
kwargs: dict[str, Any] | None = None,
|
152
155
|
) -> Any:
|
153
156
|
"""Runs the task synchronously.
|
154
157
|
|
155
158
|
Args:
|
156
159
|
session (AnySession): The shared session.
|
157
160
|
str_kwargs(dict[str, str]): The input string values.
|
161
|
+
kwargs(dict[str, Any]): The input values.
|
158
162
|
|
159
163
|
Returns:
|
160
164
|
Any: The result of the task execution.
|
@@ -163,13 +167,17 @@ class AnyTask(ABC):
|
|
163
167
|
|
164
168
|
@abstractmethod
|
165
169
|
async def async_run(
|
166
|
-
self,
|
170
|
+
self,
|
171
|
+
session: "AnySession | None" = None,
|
172
|
+
str_kwargs: dict[str, str] | None = None,
|
173
|
+
kwargs: dict[str, Any] | None = None,
|
167
174
|
) -> Any:
|
168
175
|
"""Runs the task asynchronously.
|
169
176
|
|
170
177
|
Args:
|
171
178
|
session (AnySession): The shared session.
|
172
179
|
str_kwargs(dict[str, str]): The input string values.
|
180
|
+
kwargs(dict[str, Any]): The input values.
|
173
181
|
|
174
182
|
Returns:
|
175
183
|
Any: The result of the task execution.
|
zrb/task/base/context.py
CHANGED
@@ -26,25 +26,33 @@ def build_task_context(task: AnyTask, session: AnySession) -> AnyContext:
|
|
26
26
|
|
27
27
|
|
28
28
|
def fill_shared_context_inputs(
|
29
|
-
|
29
|
+
shared_ctx: AnySharedContext,
|
30
|
+
task: AnyTask,
|
31
|
+
str_kwargs: dict[str, str] | None = None,
|
32
|
+
kwargs: dict[str, str] | None = None,
|
30
33
|
):
|
31
34
|
"""
|
32
|
-
Populates the shared context with input values provided via
|
35
|
+
Populates the shared context with input values provided via str_kwargs.
|
33
36
|
"""
|
37
|
+
str_kwarg_dict = str_kwargs if str_kwargs is not None else {}
|
38
|
+
kwarg_dict = kwargs if kwargs is not None else {}
|
34
39
|
for task_input in task.inputs:
|
35
|
-
if task_input.name not in
|
36
|
-
|
37
|
-
|
40
|
+
if task_input.name not in shared_ctx.input:
|
41
|
+
task_input.update_shared_context(
|
42
|
+
shared_ctx,
|
43
|
+
value=kwarg_dict.get(task_input.name, None),
|
44
|
+
str_value=str_kwarg_dict.get(task_input.name, None),
|
45
|
+
)
|
38
46
|
|
39
47
|
|
40
|
-
def fill_shared_context_envs(
|
48
|
+
def fill_shared_context_envs(shared_ctx: AnySharedContext):
|
41
49
|
"""
|
42
50
|
Injects OS environment variables into the shared context if they don't already exist.
|
43
51
|
"""
|
44
52
|
os_env_map = {
|
45
|
-
key: val for key, val in os.environ.items() if key not in
|
53
|
+
key: val for key, val in os.environ.items() if key not in shared_ctx.env
|
46
54
|
}
|
47
|
-
|
55
|
+
shared_ctx.env.update(os_env_map)
|
48
56
|
|
49
57
|
|
50
58
|
def combine_inputs(
|
zrb/task/base/lifecycle.py
CHANGED
@@ -12,7 +12,8 @@ from zrb.util.run import run_async
|
|
12
12
|
async def run_and_cleanup(
|
13
13
|
task: AnyTask,
|
14
14
|
session: AnySession | None = None,
|
15
|
-
str_kwargs: dict[str, str] =
|
15
|
+
str_kwargs: dict[str, str] | None = None,
|
16
|
+
kwargs: dict[str, Any] | None = None,
|
16
17
|
) -> Any:
|
17
18
|
"""
|
18
19
|
Wrapper for async_run that ensures session termination and cleanup of
|
@@ -23,7 +24,9 @@ async def run_and_cleanup(
|
|
23
24
|
session = Session(shared_ctx=SharedContext())
|
24
25
|
|
25
26
|
# Create the main task execution coroutine
|
26
|
-
main_task_coro = asyncio.create_task(
|
27
|
+
main_task_coro = asyncio.create_task(
|
28
|
+
run_task_async(task, session, str_kwargs, kwargs)
|
29
|
+
)
|
27
30
|
|
28
31
|
try:
|
29
32
|
result = await main_task_coro
|
@@ -67,7 +70,8 @@ async def run_and_cleanup(
|
|
67
70
|
async def run_task_async(
|
68
71
|
task: AnyTask,
|
69
72
|
session: AnySession | None = None,
|
70
|
-
str_kwargs: dict[str, str] =
|
73
|
+
str_kwargs: dict[str, str] | None = None,
|
74
|
+
kwargs: dict[str, Any] | None = None,
|
71
75
|
) -> Any:
|
72
76
|
"""
|
73
77
|
Asynchronous entry point for running a task (`task.async_run()`).
|
@@ -77,7 +81,7 @@ async def run_task_async(
|
|
77
81
|
session = Session(shared_ctx=SharedContext())
|
78
82
|
|
79
83
|
# Populate shared context with inputs and environment variables
|
80
|
-
fill_shared_context_inputs(
|
84
|
+
fill_shared_context_inputs(session.shared_ctx, task, str_kwargs, kwargs)
|
81
85
|
fill_shared_context_envs(session.shared_ctx) # Inject OS env vars
|
82
86
|
|
83
87
|
# Start the execution chain from the root tasks
|
zrb/task/base_task.py
CHANGED
@@ -216,7 +216,10 @@ class BaseTask(AnyTask):
|
|
216
216
|
return build_task_context(self, session)
|
217
217
|
|
218
218
|
def run(
|
219
|
-
self,
|
219
|
+
self,
|
220
|
+
session: AnySession | None = None,
|
221
|
+
str_kwargs: dict[str, str] | None = None,
|
222
|
+
kwargs: dict[str, str] | None = None,
|
220
223
|
) -> Any:
|
221
224
|
"""
|
222
225
|
Synchronously runs the task and its dependencies, handling async setup and cleanup.
|
@@ -235,12 +238,19 @@ class BaseTask(AnyTask):
|
|
235
238
|
Any: The final result of the main task execution.
|
236
239
|
"""
|
237
240
|
# Use asyncio.run() to execute the async cleanup wrapper
|
238
|
-
return asyncio.run(
|
241
|
+
return asyncio.run(
|
242
|
+
run_and_cleanup(self, session=session, str_kwargs=str_kwargs, kwargs=kwargs)
|
243
|
+
)
|
239
244
|
|
240
245
|
async def async_run(
|
241
|
-
self,
|
246
|
+
self,
|
247
|
+
session: AnySession | None = None,
|
248
|
+
str_kwargs: dict[str, str] | None = None,
|
249
|
+
kwargs: dict[str, Any] | None = None,
|
242
250
|
) -> Any:
|
243
|
-
return await run_task_async(
|
251
|
+
return await run_task_async(
|
252
|
+
self, session=session, str_kwargs=str_kwargs, kwargs=kwargs
|
253
|
+
)
|
244
254
|
|
245
255
|
async def exec_root_tasks(self, session: AnySession):
|
246
256
|
return await execute_root_tasks(self, session)
|
@@ -280,3 +290,43 @@ class BaseTask(AnyTask):
|
|
280
290
|
# fallback: use the __notes__ attribute directly
|
281
291
|
e.__notes__ = getattr(e, "__notes__", []) + [additional_error_note]
|
282
292
|
raise e
|
293
|
+
|
294
|
+
def to_fn(self):
|
295
|
+
# NOTE: Non documented feature, untested
|
296
|
+
from inspect import Parameter, Signature
|
297
|
+
|
298
|
+
from zrb.context.shared_context import SharedContext
|
299
|
+
from zrb.session.session import Session
|
300
|
+
|
301
|
+
def task_runner_fn(**kwargs):
|
302
|
+
str_kwargs = {k: str(v) for k, v in kwargs.items()}
|
303
|
+
shared_ctx = SharedContext()
|
304
|
+
session = Session(shared_ctx=shared_ctx)
|
305
|
+
return self.run(session=session, str_kwargs=str_kwargs)
|
306
|
+
|
307
|
+
# Create docstring
|
308
|
+
doc = f"{self.description}\n\n"
|
309
|
+
if len(self.inputs) > 0:
|
310
|
+
doc += "Args:\n"
|
311
|
+
for inp in self.inputs:
|
312
|
+
doc += f" {inp.name}: {inp.description}"
|
313
|
+
if inp.default is not None:
|
314
|
+
doc += f" (default: {inp.default})"
|
315
|
+
doc += "\n"
|
316
|
+
task_runner_fn.__doc__ = doc
|
317
|
+
|
318
|
+
# Create signature
|
319
|
+
params = []
|
320
|
+
for inp in self.inputs:
|
321
|
+
params.append(
|
322
|
+
Parameter(
|
323
|
+
name=inp.name,
|
324
|
+
kind=Parameter.POSITIONAL_OR_KEYWORD,
|
325
|
+
default=inp.default if inp.default is not None else Parameter.empty,
|
326
|
+
)
|
327
|
+
)
|
328
|
+
sig = Signature(params)
|
329
|
+
task_runner_fn.__signature__ = sig
|
330
|
+
task_runner_fn.__name__ = self.name
|
331
|
+
|
332
|
+
return task_runner_fn
|
zrb/task/llm/agent.py
CHANGED
@@ -9,6 +9,7 @@ from zrb.task.llm.error import extract_api_error_details
|
|
9
9
|
from zrb.task.llm.print_node import print_node
|
10
10
|
from zrb.task.llm.tool_wrapper import wrap_func, wrap_tool
|
11
11
|
from zrb.task.llm.typing import ListOfDict
|
12
|
+
from zrb.util.cli.style import stylize_faint
|
12
13
|
|
13
14
|
if TYPE_CHECKING:
|
14
15
|
from pydantic_ai import Agent, Tool
|
@@ -184,10 +185,11 @@ async def _run_single_agent_iteration(
|
|
184
185
|
agent_payload = _estimate_request_payload(
|
185
186
|
agent, user_prompt, attachments, history_list
|
186
187
|
)
|
188
|
+
callback = lambda: _print_throttle_notif(ctx)
|
187
189
|
if rate_limitter:
|
188
|
-
await rate_limitter.throttle(agent_payload)
|
190
|
+
await rate_limitter.throttle(agent_payload, callback)
|
189
191
|
else:
|
190
|
-
await llm_rate_limitter.throttle(agent_payload)
|
192
|
+
await llm_rate_limitter.throttle(agent_payload, callback)
|
191
193
|
|
192
194
|
user_prompt_with_attachments = [user_prompt] + attachments
|
193
195
|
async with agent:
|
@@ -214,6 +216,10 @@ async def _run_single_agent_iteration(
|
|
214
216
|
return agent_run
|
215
217
|
|
216
218
|
|
219
|
+
def _print_throttle_notif(ctx: AnyContext):
|
220
|
+
ctx.print(stylize_faint(" ⌛>> Request Throttled"), plain=True)
|
221
|
+
|
222
|
+
|
217
223
|
def _estimate_request_payload(
|
218
224
|
agent: "Agent",
|
219
225
|
user_prompt: str,
|
@@ -16,6 +16,7 @@ from zrb.task.llm.typing import ListOfDict
|
|
16
16
|
from zrb.util.attr import get_bool_attr, get_int_attr
|
17
17
|
from zrb.util.cli.style import stylize_faint
|
18
18
|
from zrb.util.llm.prompt import make_prompt_section
|
19
|
+
from zrb.util.truncate import truncate_str
|
19
20
|
|
20
21
|
if TYPE_CHECKING:
|
21
22
|
from pydantic_ai.models import Model
|
@@ -115,7 +116,7 @@ async def summarize_history(
|
|
115
116
|
),
|
116
117
|
make_prompt_section(
|
117
118
|
"Recent Conversation (JSON)",
|
118
|
-
json.dumps(conversation_history.history),
|
119
|
+
json.dumps(truncate_str(conversation_history.history, 1000)),
|
119
120
|
as_code=True,
|
120
121
|
),
|
121
122
|
make_prompt_section(
|
zrb/task/llm/tool_wrapper.py
CHANGED
@@ -128,14 +128,13 @@ def _create_wrapper(
|
|
128
128
|
async def _ask_for_approval(
|
129
129
|
ctx: AnyContext, func: Callable, args: list[Any], kwargs: dict[str, Any]
|
130
130
|
) -> tuple[bool, str]:
|
131
|
-
func_name = get_callable_name(func)
|
132
131
|
func_call_str = _get_func_call_str(func, args, kwargs)
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
132
|
+
complete_confirmation_message = "\n".join(
|
133
|
+
[
|
134
|
+
f"\n🎰 >> {func_call_str}",
|
135
|
+
_get_detail_func_param(args, kwargs),
|
136
|
+
f"✅ >> {_get_run_func_confirmation(func)}",
|
137
|
+
]
|
139
138
|
)
|
140
139
|
while True:
|
141
140
|
ctx.print(complete_confirmation_message, plain=True)
|
@@ -166,6 +165,13 @@ async def _ask_for_approval(
|
|
166
165
|
continue
|
167
166
|
|
168
167
|
|
168
|
+
def _get_run_func_confirmation(func: Callable) -> str:
|
169
|
+
func_name = get_callable_name(func)
|
170
|
+
return render_markdown(
|
171
|
+
f"Allow to run `{func_name}`? (`Yes` | `No, <reason>`)"
|
172
|
+
).strip()
|
173
|
+
|
174
|
+
|
169
175
|
def _get_detail_func_param(args: list[Any], kwargs: dict[str, Any]) -> str:
|
170
176
|
markdown = "\n".join(
|
171
177
|
[_get_func_param_item(key, val) for key, val in kwargs.items()]
|
zrb/task/llm_task.py
CHANGED
@@ -323,6 +323,7 @@ class LLMTask(BaseTask):
|
|
323
323
|
history_list=conversation_history.history,
|
324
324
|
rate_limitter=self._rate_limitter,
|
325
325
|
)
|
326
|
+
|
326
327
|
if agent_run and agent_run.result:
|
327
328
|
new_history_list = json.loads(agent_run.result.all_messages_json())
|
328
329
|
conversation_history.history = new_history_list
|
zrb/util/truncate.py
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
from collections.abc import Mapping, Sequence
|
2
|
+
from typing import Any
|
3
|
+
|
4
|
+
|
5
|
+
def truncate_str(value: Any, limit: int):
|
6
|
+
# If value is a string, truncate
|
7
|
+
if isinstance(value, str):
|
8
|
+
if len(value) > limit:
|
9
|
+
if limit < 4:
|
10
|
+
return value[:limit]
|
11
|
+
return value[: limit - 4] + " ..."
|
12
|
+
# If value is a dict, process recursively
|
13
|
+
elif isinstance(value, Mapping):
|
14
|
+
return {k: truncate_str(v, limit) for k, v in value.items()}
|
15
|
+
# If value is a list or tuple, process recursively preserving type
|
16
|
+
elif isinstance(value, Sequence) and not isinstance(value, (str, bytes, bytearray)):
|
17
|
+
t = type(value)
|
18
|
+
return t(truncate_str(v, limit) for v in value)
|
19
|
+
# If value is a set, process recursively preserving type
|
20
|
+
elif isinstance(value, set):
|
21
|
+
return {truncate_str(v, limit) for v in value}
|
22
|
+
# Other types are returned unchanged
|
23
|
+
return value
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: zrb
|
3
|
-
Version: 1.15.
|
3
|
+
Version: 1.15.6
|
4
4
|
Summary: Your Automation Powerhouse
|
5
5
|
License: AGPL-3.0-or-later
|
6
6
|
Keywords: Automation,Task Runner,Code Generator,Monorepo,Low Code
|
@@ -27,6 +27,7 @@ Requires-Dist: pdfplumber (>=0.11.7,<0.12.0)
|
|
27
27
|
Requires-Dist: playwright (>=1.54.0,<2.0.0) ; extra == "playwright" or extra == "all"
|
28
28
|
Requires-Dist: psutil (>=7.0.0,<8.0.0)
|
29
29
|
Requires-Dist: pydantic-ai-slim[anthropic,bedrock,cli,cohere,google,groq,huggingface,mcp,mistral,openai,vertexai] (>=0.7.4,<0.8.0)
|
30
|
+
Requires-Dist: pyjwt (>=2.10.1,<3.0.0)
|
30
31
|
Requires-Dist: python-dotenv (>=1.1.1,<2.0.0)
|
31
32
|
Requires-Dist: python-jose[cryptography] (>=3.5.0,<4.0.0)
|
32
33
|
Requires-Dist: requests (>=2.32.4,<3.0.0)
|
@@ -20,7 +20,7 @@ zrb/builtin/llm/tool/cli.py,sha256=8rugrKaNPEatHjr7nN4OIRLRT2TcF-oylEZGbLI9Brs,1
|
|
20
20
|
zrb/builtin/llm/tool/code.py,sha256=BACeH0tGhTdDo0rZ7sTAP6oRaLi9cS7gdEigXiTd0Jg,8842
|
21
21
|
zrb/builtin/llm/tool/file.py,sha256=eXFGGFxxpdpWGVw0svyQNQc03I5M7wotSsA_HjkXw7c,23670
|
22
22
|
zrb/builtin/llm/tool/rag.py,sha256=Ab8_ZljnG_zfkwxPezImvorshuz3Fi4CmSzNOtU1a-g,9770
|
23
|
-
zrb/builtin/llm/tool/sub_agent.py,sha256=
|
23
|
+
zrb/builtin/llm/tool/sub_agent.py,sha256=dPqdFCXxJ-3hZnPjheZr-bPeKNbfSBSDKcZZR5vkWFM,5075
|
24
24
|
zrb/builtin/llm/tool/web.py,sha256=zNQWDNOz_MyyzhncBeV5E_9XijQxTFVp6BSzz_e5tBI,7261
|
25
25
|
zrb/builtin/md5.py,sha256=690RV2LbW7wQeTFxY-lmmqTSVEEZv3XZbjEUW1Q3XpE,1480
|
26
26
|
zrb/builtin/project/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -217,7 +217,7 @@ zrb/callback/callback.py,sha256=PFhCqzfxdk6IAthmXcZ13DokT62xtBzJr_ciLw6I8Zg,4030
|
|
217
217
|
zrb/cmd/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
218
218
|
zrb/cmd/cmd_result.py,sha256=L8bQJzWCpcYexIxHBNsXj2pT3BtLmWex0iJSMkvimOA,597
|
219
219
|
zrb/cmd/cmd_val.py,sha256=7Doowyg6BK3ISSGBLt-PmlhzaEkBjWWm51cED6fAUOQ,1014
|
220
|
-
zrb/config/config.py,sha256=
|
220
|
+
zrb/config/config.py,sha256=AtJ61i_ZTi95vRV5h4EKtMWhPdU2YVEdv08mU1DePEk,14161
|
221
221
|
zrb/config/default_prompt/file_extractor_system_prompt.md,sha256=tmeZMPzF9MGExsZZw7M2PZN6V0oFVRp1nIjiqUPvQ9M,1013
|
222
222
|
zrb/config/default_prompt/interactive_system_prompt.md,sha256=sRFrwqnqudnXATkTwHnnQAhLKC0ep6lad8vKXaRAPzc,3505
|
223
223
|
zrb/config/default_prompt/persona.md,sha256=WU4JKp-p7qJePDA6NZ_CYdBggo2B3PEq8IEnNVblIHU,41
|
@@ -228,7 +228,7 @@ zrb/config/default_prompt/system_prompt.md,sha256=Jkne5n9HJcBCgfeENwxvqH-kbDO2Ca
|
|
228
228
|
zrb/config/llm_config.py,sha256=xt-Xf8ZuNoUT_GKCSFz5yy0BhbeHzxP-jrezB06WeiY,8857
|
229
229
|
zrb/config/llm_context/config.py,sha256=PDsrKAduQfsEUMYt4jirG0F7KDkY7jqhrbsptxdMOEg,4962
|
230
230
|
zrb/config/llm_context/config_parser.py,sha256=h95FbOjvVobhrsfGtG_BY3hxS-OLzQj-9F5vGZuehkY,1473
|
231
|
-
zrb/config/llm_rate_limitter.py,sha256=
|
231
|
+
zrb/config/llm_rate_limitter.py,sha256=_iQRv3d6kUPeRvmUYZX_iwCE7iDSEK1oKa4bQ9GROho,5261
|
232
232
|
zrb/config/web_auth_config.py,sha256=_PXatQTYh2mX9H3HSYSQKp13zm1RlLyVIoeIr6KYMQ8,6279
|
233
233
|
zrb/content_transformer/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
234
234
|
zrb/content_transformer/any_content_transformer.py,sha256=v8ZUbcix1GGeDQwB6OKX_1TjpY__ksxWVeqibwa_iZA,850
|
@@ -236,8 +236,8 @@ zrb/content_transformer/content_transformer.py,sha256=STl77wW-I69QaGzCXjvkppngYF
|
|
236
236
|
zrb/context/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
237
237
|
zrb/context/any_context.py,sha256=2hgVKbbDwmwrEl1h1L1FaTUjuUYaDd_b7YRGkaorW6Q,6362
|
238
238
|
zrb/context/any_shared_context.py,sha256=wJawL1jGgApcKPRcpw3js7W4-MhJRA3GMbR5zTsJmt0,1929
|
239
|
-
zrb/context/context.py,sha256=
|
240
|
-
zrb/context/shared_context.py,sha256=
|
239
|
+
zrb/context/context.py,sha256=pnFV7KjVMKWAkYidhZTVFpPZvvGbqGuj_TERpWOvCIw,6883
|
240
|
+
zrb/context/shared_context.py,sha256=mBbTDPfde5ZBj4EKfMEC2636bSE7GZWx7MtaQnETqgg,2972
|
241
241
|
zrb/dot_dict/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
242
242
|
zrb/dot_dict/dot_dict.py,sha256=ubw_x8I7AOJ59xxtFVJ00VGmq_IYdZP3mUhNlO4nEK0,556
|
243
243
|
zrb/env/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -249,8 +249,8 @@ zrb/group/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
249
249
|
zrb/group/any_group.py,sha256=sdUk82YRuJBMwDhD_b-vJ3v-Yxz8K7LFW52TM19k3HI,1242
|
250
250
|
zrb/group/group.py,sha256=t5JnXlrLfthFfqmkVdRLKCIyms4JqsthcTODVncSmPk,4312
|
251
251
|
zrb/input/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
252
|
-
zrb/input/any_input.py,sha256=
|
253
|
-
zrb/input/base_input.py,sha256=
|
252
|
+
zrb/input/any_input.py,sha256=3EQgg2Qk_2t2Ege_4pHV2G95tV3XAIThLLuFZ6uV6oM,1051
|
253
|
+
zrb/input/base_input.py,sha256=Rb2m9xLJgGDph2D8L9HnLFPtQZqmPAPKrSP2K4pK97A,3848
|
254
254
|
zrb/input/bool_input.py,sha256=9ir8aTm8zaufrJ84_EerC5vOjyn4hHZ3BiLzFqPgPFM,1839
|
255
255
|
zrb/input/float_input.py,sha256=8G9lJKLlb_Upk9m5pBF9JwqlAAiYJLrbIItLnyzPxpg,1475
|
256
256
|
zrb/input/int_input.py,sha256=UhxCFYlZdJcgUSGGEkz301zOgRVpK0KDG_IxxWpQfMU,1457
|
@@ -259,8 +259,8 @@ zrb/input/password_input.py,sha256=szBojWxSP9QJecgsgA87OIYwQrY2AQ3USIKdDZY6snU,1
|
|
259
259
|
zrb/input/str_input.py,sha256=NevZHX9rf1g8eMatPyy-kUX3DglrVAQpzvVpKAzf7bA,81
|
260
260
|
zrb/input/text_input.py,sha256=UCkC497V6L12cPjupOgIZ5XW2eBbBDydQi5IIYtknek,3702
|
261
261
|
zrb/runner/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
262
|
-
zrb/runner/cli.py,sha256=
|
263
|
-
zrb/runner/common_util.py,sha256=
|
262
|
+
zrb/runner/cli.py,sha256=CNZoti_cNcHEkD6TO4gQie2_t6KTinjdc7oEc-wszQg,6947
|
263
|
+
zrb/runner/common_util.py,sha256=yIJm9ivM7hvJ4Kb4Nt5RRE7oqAlt9EN89w6JDGyLkFE,1570
|
264
264
|
zrb/runner/web_app.py,sha256=n8iXtQ5DGIfRcFsHdBafm9VJisVSDD159XFPpEXQTN0,2796
|
265
265
|
zrb/runner/web_route/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
266
266
|
zrb/runner/web_route/docs_route.py,sha256=Y8zTROzIOfmJuU_E9KZljdjgkd65DcvLeX3k0xO-o_k,550
|
@@ -315,7 +315,7 @@ zrb/runner/web_route/static/resources/session/current-session.js,sha256=tzUdK7qJ
|
|
315
315
|
zrb/runner/web_route/static/resources/session/event.js,sha256=X5OlSHefK0SDB9VkFCRyBKE_Pb7mqM319mW9jRGoDOk,4716
|
316
316
|
zrb/runner/web_route/static/resources/session/past-session.js,sha256=RwGJYKSp75K8NZ-iZP58XppWgdzkiKFaiC5wgcMLxDo,5470
|
317
317
|
zrb/runner/web_route/static/static_route.py,sha256=QPs5XW4O_8CuzG0Wy4sHh5wRcLbU63CLDI4YNqkUxHA,1555
|
318
|
-
zrb/runner/web_route/task_input_api_route.py,sha256=
|
318
|
+
zrb/runner/web_route/task_input_api_route.py,sha256=1uTI9efQNXJ_S9jGWSudQFIyGSkINSLLYzSWCMcOtkc,1795
|
319
319
|
zrb/runner/web_route/task_session_api_route.py,sha256=U9fPOh_nmAzsmRnS5xe713KFUU15n0IkbbzU_Eg8YGI,6181
|
320
320
|
zrb/runner/web_schema/session.py,sha256=NwbuS2Sv-CXO52nU-EZv8OMlD4vgCQWNeLC_dT0FK7I,92
|
321
321
|
zrb/runner/web_schema/token.py,sha256=Y7XCPS4WzrxslTDtHeLcPTTUpmWhPOkRcl4b99zrC7c,185
|
@@ -334,19 +334,19 @@ zrb/session_state_logger/any_session_state_logger.py,sha256=T_-aJv63HwoTeiDOmXKH
|
|
334
334
|
zrb/session_state_logger/file_session_state_logger.py,sha256=NMyj_g2ImQc6ZRM9f35EpA-CM1UO-ZgoDnPkN1DSi9U,3915
|
335
335
|
zrb/session_state_logger/session_state_logger_factory.py,sha256=_oT1UIqm25nMwKhsUvXehnCdDvNqxCyuN8GLdv2D_U4,188
|
336
336
|
zrb/task/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
337
|
-
zrb/task/any_task.py,sha256=
|
337
|
+
zrb/task/any_task.py,sha256=SAPX1uuq4c0mxgGEQ6lyioR4eRmFovhH-Wr2xCtrHnA,6078
|
338
338
|
zrb/task/base/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
339
|
-
zrb/task/base/context.py,sha256=
|
339
|
+
zrb/task/base/context.py,sha256=uj0fHPtbjiRWE4gRB8DKNJhLmEN1ZWH6FCjItlE45q4,3918
|
340
340
|
zrb/task/base/execution.py,sha256=scDLfNYBe8Bc8Ct1LCIKmFtjpPxm7FjqZ2bJXIQAzv8,11042
|
341
|
-
zrb/task/base/lifecycle.py,sha256=
|
341
|
+
zrb/task/base/lifecycle.py,sha256=c2v977pUm7S4EqrTMcUJKhnYOWugACVwU3qORDKiLXQ,7639
|
342
342
|
zrb/task/base/monitoring.py,sha256=UAOEcPiYNtZR4FFxzWCosuOEFE_P3c4GT5vAhQmohqI,5663
|
343
343
|
zrb/task/base/operators.py,sha256=uAMFqpZJsPnCrojgOl1FUDXTS15mtOa_IqiAXltyYRU,1576
|
344
|
-
zrb/task/base_task.py,sha256=
|
344
|
+
zrb/task/base_task.py,sha256=qPtEIP3TEX7YbDadQtsUXLJ4_7Khzk_JxXDh_mRrluU,12602
|
345
345
|
zrb/task/base_trigger.py,sha256=WSGcmBcGAZw8EzUXfmCjqJQkz8GEmi1RzogpF6A1V4s,6902
|
346
346
|
zrb/task/cmd_task.py,sha256=myM8WZm6NrUD-Wv0Vb5sTOrutrAVZLt5LVsSBKwX6SM,10860
|
347
347
|
zrb/task/http_check.py,sha256=Gf5rOB2Se2EdizuN9rp65HpGmfZkGc-clIAlHmPVehs,2565
|
348
348
|
zrb/task/llm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
349
|
-
zrb/task/llm/agent.py,sha256=
|
349
|
+
zrb/task/llm/agent.py,sha256=jfC90N8oER2z-fTmPEuWH3ASPgw5t8cZm8rk98HBBlw,8876
|
350
350
|
zrb/task/llm/config.py,sha256=n1SPmwab09K2i1sL_OCwrEOWHI0Owx_hvWelg3Dreus,3781
|
351
351
|
zrb/task/llm/conversation_history.py,sha256=B_PDWYL_q66s0xwWBzMSomqPN6u3gkXlIeXBD5A0Apg,4416
|
352
352
|
zrb/task/llm/conversation_history_model.py,sha256=DJ0KDBB0BriQuE5ugC_q0aSHhjNIBcfjUk1f0S_3I9U,9245
|
@@ -354,12 +354,12 @@ zrb/task/llm/default_workflow/coding.md,sha256=2uythvPsnBpYfIhiIH1cCinQXX0i0yUqs
|
|
354
354
|
zrb/task/llm/default_workflow/copywriting.md,sha256=xSO7GeDolwGxiuz6kXsK2GKGpwp8UgtG0yRqTmill_s,1999
|
355
355
|
zrb/task/llm/default_workflow/researching.md,sha256=KD-aYHFHir6Ti-4FsBBtGwiI0seSVgleYbKJZi_POXA,2139
|
356
356
|
zrb/task/llm/error.py,sha256=QR-nIohS6pBpC_16cWR-fw7Mevo1sNYAiXMBsh_CJDE,4157
|
357
|
-
zrb/task/llm/history_summarization.py,sha256=
|
357
|
+
zrb/task/llm/history_summarization.py,sha256=_eWFP4cAn3tTfyt7YPjnPwm_PgMhMChPg9g2q2Gsf0c,8172
|
358
358
|
zrb/task/llm/print_node.py,sha256=Sd8ovTO6KKI9hllZf5TxRXog7QGCne1A1E83jnrH_kg,6526
|
359
359
|
zrb/task/llm/prompt.py,sha256=FGXWYHecWtrNNkPnjg-uhnkqp7fYt8V91-AjFM_5fpA,11550
|
360
|
-
zrb/task/llm/tool_wrapper.py,sha256=
|
360
|
+
zrb/task/llm/tool_wrapper.py,sha256=2cbaSNvOMlIb3l5RXEFbH7cnox01TAr4b4Vtg0wzuYs,9609
|
361
361
|
zrb/task/llm/typing.py,sha256=c8VAuPBw_4A3DxfYdydkgedaP-LU61W9_wj3m3CAX1E,58
|
362
|
-
zrb/task/llm_task.py,sha256=
|
362
|
+
zrb/task/llm_task.py,sha256=0c9F_AjeMLxQX8VlAJHfZAkC52PhRaWbcKoqVOggcMg,14451
|
363
363
|
zrb/task/make_task.py,sha256=PD3b_aYazthS8LHeJsLAhwKDEgdurQZpymJDKeN60u0,2265
|
364
364
|
zrb/task/rsync_task.py,sha256=WfqNSaicJgYWpunNU34eYxXDqHDHOftuDHyWJKjqwg0,6365
|
365
365
|
zrb/task/scaffolder.py,sha256=rME18w1HJUHXgi9eTYXx_T2G4JdqDYzBoNOkdOOo5-o,6806
|
@@ -405,9 +405,10 @@ zrb/util/string/format.py,sha256=MwWGAwSdtOgR_2uz-JCXlg_q-uRYUUI-G8CGkfdgqik,119
|
|
405
405
|
zrb/util/string/name.py,sha256=SXEfxJ1-tDOzHqmSV8kvepRVyMqs2XdV_vyoh_9XUu0,1584
|
406
406
|
zrb/util/todo.py,sha256=r9_KYF2-hLKMNjsp6AFK9zivykMrywd-kJ4bCwfdafI,19323
|
407
407
|
zrb/util/todo_model.py,sha256=hhzAX-uFl5rsg7iVX1ULlJOfBtblwQ_ieNUxBWfc-Os,1670
|
408
|
+
zrb/util/truncate.py,sha256=eSzmjBpc1Qod3lM3M73snNbDOcARHukW_tq36dWdPvc,921
|
408
409
|
zrb/xcom/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
409
410
|
zrb/xcom/xcom.py,sha256=o79rxR9wphnShrcIushA0Qt71d_p3ZTxjNf7x9hJB78,1571
|
410
|
-
zrb-1.15.
|
411
|
-
zrb-1.15.
|
412
|
-
zrb-1.15.
|
413
|
-
zrb-1.15.
|
411
|
+
zrb-1.15.6.dist-info/METADATA,sha256=octlKaqi1aMWs5qYYb5d02at13BGvqvMdOEjYrKbp4E,9774
|
412
|
+
zrb-1.15.6.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
413
|
+
zrb-1.15.6.dist-info/entry_points.txt,sha256=-Pg3ElWPfnaSM-XvXqCxEAa-wfVI6BEgcs386s8C8v8,46
|
414
|
+
zrb-1.15.6.dist-info/RECORD,,
|
File without changes
|
File without changes
|