zrb 1.15.1__py3-none-any.whl → 1.15.3__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/chat_session.py +6 -3
- zrb/config/llm_context/config.py +3 -3
- zrb/task/llm/print_node.py +17 -10
- zrb/task/llm/prompt.py +36 -10
- zrb/task/llm/tool_wrapper.py +4 -2
- zrb/task/llm_task.py +1 -1
- {zrb-1.15.1.dist-info → zrb-1.15.3.dist-info}/METADATA +1 -1
- {zrb-1.15.1.dist-info → zrb-1.15.3.dist-info}/RECORD +10 -10
- {zrb-1.15.1.dist-info → zrb-1.15.3.dist-info}/WHEEL +0 -0
- {zrb-1.15.1.dist-info → zrb-1.15.3.dist-info}/entry_points.txt +0 -0
zrb/builtin/llm/chat_session.py
CHANGED
@@ -34,7 +34,7 @@ async def read_user_prompt(ctx: AnyContext) -> str:
|
|
34
34
|
# Get user input based on mode
|
35
35
|
if not multiline_mode:
|
36
36
|
ctx.print("💬 >>", plain=True)
|
37
|
-
user_input = await _read_next_line(
|
37
|
+
user_input = await _read_next_line(reader, ctx)
|
38
38
|
if not multiline_mode:
|
39
39
|
ctx.print("", plain=True)
|
40
40
|
# Handle user input
|
@@ -111,6 +111,7 @@ def _show_info(ctx: AnyContext):
|
|
111
111
|
),
|
112
112
|
plain=True,
|
113
113
|
)
|
114
|
+
ctx.print("", plain=True)
|
114
115
|
|
115
116
|
|
116
117
|
def _show_command(command: str, description: str) -> str:
|
@@ -157,9 +158,11 @@ async def _setup_input_reader(is_interactive: bool):
|
|
157
158
|
return reader
|
158
159
|
|
159
160
|
|
160
|
-
async def _read_next_line(
|
161
|
+
async def _read_next_line(reader, ctx: AnyContext) -> str:
|
161
162
|
"""Reads one line of input using the provided reader."""
|
162
|
-
|
163
|
+
from prompt_toolkit import PromptSession
|
164
|
+
|
165
|
+
if isinstance(reader, PromptSession):
|
163
166
|
return await reader.prompt_async()
|
164
167
|
|
165
168
|
line_bytes = await reader.readline()
|
zrb/config/llm_context/config.py
CHANGED
@@ -44,7 +44,7 @@ class LLMContextConfig:
|
|
44
44
|
for config_dir, sections in reversed(all_sections):
|
45
45
|
for key, value in sections.items():
|
46
46
|
if key.startswith("Context:"):
|
47
|
-
context_path = key
|
47
|
+
context_path = key[len("Context:") :].strip()
|
48
48
|
if context_path == ".":
|
49
49
|
context_path = config_dir
|
50
50
|
elif not os.path.isabs(context_path):
|
@@ -64,9 +64,9 @@ class LLMContextConfig:
|
|
64
64
|
for _, sections in reversed(all_sections):
|
65
65
|
for key, value in sections.items():
|
66
66
|
if key.startswith("Workflow:"):
|
67
|
+
workflow_name = key[len("Workflow:") :].strip()
|
67
68
|
workflow_name = key.replace("Workflow:", "").lower().strip()
|
68
|
-
|
69
|
-
workflows[workflow_name] = value
|
69
|
+
workflows[workflow_name] = value
|
70
70
|
return workflows
|
71
71
|
|
72
72
|
def write_context(
|
zrb/task/llm/print_node.py
CHANGED
@@ -19,10 +19,10 @@ async def print_node(print_func: Callable, agent_run: Any, node: Any):
|
|
19
19
|
)
|
20
20
|
|
21
21
|
if Agent.is_user_prompt_node(node):
|
22
|
-
print_func(stylize_faint("🔠 Receiving input..."))
|
22
|
+
print_func(stylize_faint(" 🔠 Receiving input..."))
|
23
23
|
elif Agent.is_model_request_node(node):
|
24
24
|
# A model request node => We can stream tokens from the model's request
|
25
|
-
print_func(stylize_faint("🧠 Processing..."))
|
25
|
+
print_func(stylize_faint(" 🧠 Processing..."))
|
26
26
|
# Reference: https://ai.pydantic.dev/agents/#streaming
|
27
27
|
async with node.stream(agent_run.ctx) as request_stream:
|
28
28
|
is_streaming = False
|
@@ -30,9 +30,8 @@ async def print_node(print_func: Callable, agent_run: Any, node: Any):
|
|
30
30
|
if isinstance(event, PartStartEvent) and event.part:
|
31
31
|
if is_streaming:
|
32
32
|
print_func("")
|
33
|
-
|
34
|
-
|
35
|
-
)
|
33
|
+
content = _get_event_part_content(event)
|
34
|
+
print_func(stylize_faint(f" {content}"), end="")
|
36
35
|
is_streaming = False
|
37
36
|
elif isinstance(event, PartDeltaEvent):
|
38
37
|
if isinstance(event.delta, TextPartDelta) or isinstance(
|
@@ -52,14 +51,14 @@ async def print_node(print_func: Callable, agent_run: Any, node: Any):
|
|
52
51
|
if is_streaming:
|
53
52
|
print_func("")
|
54
53
|
print_func(
|
55
|
-
stylize_faint(f"
|
54
|
+
stylize_faint(f" Result: tool_name={event.tool_name}"),
|
56
55
|
)
|
57
56
|
is_streaming = False
|
58
57
|
if is_streaming:
|
59
58
|
print_func("")
|
60
59
|
elif Agent.is_call_tools_node(node):
|
61
60
|
# A handle-response node => The model returned some data, potentially calls a tool
|
62
|
-
print_func(stylize_faint("🧰 Calling Tool..."))
|
61
|
+
print_func(stylize_faint(" 🧰 Calling Tool..."))
|
63
62
|
async with node.stream(agent_run.ctx) as handle_stream:
|
64
63
|
async for event in handle_stream:
|
65
64
|
if isinstance(event, FunctionToolCallEvent):
|
@@ -79,16 +78,24 @@ async def print_node(print_func: Callable, agent_run: Any, node: Any):
|
|
79
78
|
del event.part.args["_dummy"]
|
80
79
|
print_func(
|
81
80
|
stylize_faint(
|
82
|
-
f"
|
81
|
+
f" {event.part.tool_call_id} | "
|
83
82
|
f"Call {event.part.tool_name} {event.part.args}"
|
84
83
|
)
|
85
84
|
)
|
86
85
|
elif isinstance(event, FunctionToolResultEvent):
|
87
86
|
print_func(
|
88
87
|
stylize_faint(
|
89
|
-
f"
|
88
|
+
f" {event.tool_call_id} | {event.result.content}"
|
90
89
|
)
|
91
90
|
)
|
92
91
|
elif Agent.is_end_node(node):
|
93
92
|
# Once an End node is reached, the agent run is complete
|
94
|
-
print_func(stylize_faint("✅ Completed..."))
|
93
|
+
print_func(stylize_faint(" ✅ Completed..."))
|
94
|
+
|
95
|
+
|
96
|
+
def _get_event_part_content(event: Any) -> str:
|
97
|
+
if not hasattr(event, "part"):
|
98
|
+
return f"{event}"
|
99
|
+
if not hasattr(event.part, "content"):
|
100
|
+
return f"{event.part}"
|
101
|
+
return getattr(event.part, "content")
|
zrb/task/llm/prompt.py
CHANGED
@@ -93,28 +93,54 @@ def get_workflow_prompt(
|
|
93
93
|
modes_attr: StrListAttr | None,
|
94
94
|
render_modes: bool,
|
95
95
|
) -> str:
|
96
|
-
|
96
|
+
builtin_workflow_dir = os.path.join(os.path.dirname(__file__), "default_workflow")
|
97
|
+
modes = set(get_modes(ctx, modes_attr, render_modes))
|
98
|
+
|
97
99
|
# Get user-defined workflows
|
98
100
|
workflows = {
|
99
101
|
workflow_name.strip().lower(): content
|
100
102
|
for workflow_name, content in llm_context_config.get_workflows().items()
|
101
103
|
if workflow_name.strip().lower() in modes
|
102
104
|
}
|
103
|
-
|
105
|
+
|
106
|
+
# Get available builtin workflow names from the file system
|
107
|
+
available_builtin_workflow_names = set()
|
108
|
+
try:
|
109
|
+
for filename in os.listdir(builtin_workflow_dir):
|
110
|
+
if filename.endswith(".md"):
|
111
|
+
available_builtin_workflow_names.add(filename[:-3].lower())
|
112
|
+
except FileNotFoundError:
|
113
|
+
# Handle case where the directory might not exist
|
114
|
+
ctx.log_error(
|
115
|
+
f"Warning: Default workflow directory not found at {builtin_workflow_dir}"
|
116
|
+
)
|
117
|
+
except Exception as e:
|
118
|
+
# Catch other potential errors during directory listing
|
119
|
+
ctx.log_error(f"Error listing default workflows: {e}")
|
120
|
+
|
121
|
+
# Determine which builtin workflows are requested and not already loaded
|
104
122
|
requested_builtin_workflow_names = [
|
105
|
-
workflow_name
|
106
|
-
for workflow_name in
|
107
|
-
if workflow_name
|
123
|
+
workflow_name
|
124
|
+
for workflow_name in available_builtin_workflow_names
|
125
|
+
if workflow_name in modes and workflow_name not in workflows
|
108
126
|
]
|
109
|
-
|
127
|
+
|
128
|
+
# Add builtin-workflows if requested
|
110
129
|
if len(requested_builtin_workflow_names) > 0:
|
111
|
-
dir_path = os.path.dirname(__file__)
|
112
130
|
for workflow_name in requested_builtin_workflow_names:
|
113
131
|
workflow_file_path = os.path.join(
|
114
|
-
|
132
|
+
builtin_workflow_dir, f"{workflow_name}.md"
|
115
133
|
)
|
116
|
-
|
117
|
-
|
134
|
+
try:
|
135
|
+
with open(workflow_file_path, "r") as f:
|
136
|
+
workflows[workflow_name] = f.read()
|
137
|
+
except FileNotFoundError:
|
138
|
+
ctx.log_error(
|
139
|
+
f"Warning: Builtin workflow file not found: {workflow_file_path}"
|
140
|
+
)
|
141
|
+
except Exception as e:
|
142
|
+
ctx.log_error(f"Error reading builtin workflow {workflow_name}: {e}")
|
143
|
+
|
118
144
|
return "\n".join(
|
119
145
|
[
|
120
146
|
make_prompt_section(header.capitalize(), content)
|
zrb/task/llm/tool_wrapper.py
CHANGED
@@ -123,7 +123,7 @@ def _create_wrapper(
|
|
123
123
|
|
124
124
|
|
125
125
|
async def _ask_for_approval(
|
126
|
-
ctx: AnyContext, func: Callable, args: list[Any], kwargs: dict[Any]
|
126
|
+
ctx: AnyContext, func: Callable, args: list[Any], kwargs: dict[str, Any]
|
127
127
|
) -> tuple[bool, str]:
|
128
128
|
func_name = get_callable_name(func)
|
129
129
|
normalized_args = [stylize_green(_truncate_arg(arg)) for arg in args]
|
@@ -139,9 +139,11 @@ async def _ask_for_approval(
|
|
139
139
|
)
|
140
140
|
while True:
|
141
141
|
ctx.print(
|
142
|
-
f"✅ >> Allow to run tool: {func_call_str} (Yes | No, <reason>)",
|
142
|
+
f"\n✅ >> Allow to run tool: {func_call_str} (Yes | No, <reason>) ",
|
143
|
+
plain=True,
|
143
144
|
)
|
144
145
|
user_input = await _read_line()
|
146
|
+
ctx.print("", plain=True)
|
145
147
|
user_responses = [val.strip() for val in user_input.split(",", maxsplit=1)]
|
146
148
|
while len(user_responses) < 2:
|
147
149
|
user_responses.append("")
|
zrb/task/llm_task.py
CHANGED
@@ -331,7 +331,7 @@ class LLMTask(BaseTask):
|
|
331
331
|
ctx.xcom[xcom_usage_key] = Xcom([])
|
332
332
|
usage = agent_run.result.usage()
|
333
333
|
ctx.xcom[xcom_usage_key].push(usage)
|
334
|
-
ctx.print(stylize_faint(f"💸 Token: {usage}"), plain=True)
|
334
|
+
ctx.print(stylize_faint(f" 💸 Token: {usage}"), plain=True)
|
335
335
|
return agent_run.result.output
|
336
336
|
else:
|
337
337
|
ctx.log_warning("Agent run did not produce a result.")
|
@@ -9,7 +9,7 @@ zrb/builtin/git_subtree.py,sha256=7BKwOkVTWDrR0DXXQ4iJyHqeR6sV5VYRt8y_rEB0EHg,35
|
|
9
9
|
zrb/builtin/group.py,sha256=t008xLM4_fgbjfZrPoi_fQAnSHIo6MOiQSCHBO4GDYU,2379
|
10
10
|
zrb/builtin/http.py,sha256=L6RE73c65wWwG5iHFN-tpOhyh56KsrgVskDd3c3YXtk,4246
|
11
11
|
zrb/builtin/jwt.py,sha256=3M5uaQhJZbKQLjTUft1OwPz_JxtmK-xtkjxWjciOQho,2859
|
12
|
-
zrb/builtin/llm/chat_session.py,sha256=
|
12
|
+
zrb/builtin/llm/chat_session.py,sha256=gAn04kxT7YmqFCqxamFhV2W3Duq5z8z6jYaOmVxa5yc,10529
|
13
13
|
zrb/builtin/llm/history.py,sha256=LDOrL0p7r_AHLa5L8Dp7bHNsOALugmJd7OguXRWGnm4,3087
|
14
14
|
zrb/builtin/llm/input.py,sha256=Nw-26uTWp2QhUgKJcP_IMHmtk-b542CCSQ_vCOjhvhM,877
|
15
15
|
zrb/builtin/llm/llm_ask.py,sha256=03d1-2jh7NS0VP3eNl9wCdrUzud98i6zFUXW5NNu3_o,5597
|
@@ -226,7 +226,7 @@ zrb/config/default_prompt/repo_summarizer_system_prompt.md,sha256=fpG5B416OK3oE4
|
|
226
226
|
zrb/config/default_prompt/summarization_prompt.md,sha256=hRXH5E78TugSze_Hgp-KTbIhCeyrMcJg-pSXvXH3C9E,1629
|
227
227
|
zrb/config/default_prompt/system_prompt.md,sha256=Jkne5n9HJcBCgfeENwxvqH-kbDO2CaiUzqR4VoWMRHY,3054
|
228
228
|
zrb/config/llm_config.py,sha256=xt-Xf8ZuNoUT_GKCSFz5yy0BhbeHzxP-jrezB06WeiY,8857
|
229
|
-
zrb/config/llm_context/config.py,sha256=
|
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
231
|
zrb/config/llm_rate_limitter.py,sha256=P4vR7qxwiGwjlKx2kHcfdIxwGbJB98vdN-UQEH-Q2WU,4894
|
232
232
|
zrb/config/web_auth_config.py,sha256=_PXatQTYh2mX9H3HSYSQKp13zm1RlLyVIoeIr6KYMQ8,6279
|
@@ -355,11 +355,11 @@ zrb/task/llm/default_workflow/copywriting.md,sha256=xSO7GeDolwGxiuz6kXsK2GKGpwp8
|
|
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
357
|
zrb/task/llm/history_summarization.py,sha256=YaK3BR7gJVi9f8G5loosNAaO4y7K3ck_4bJ9GuOChXk,8028
|
358
|
-
zrb/task/llm/print_node.py,sha256=
|
359
|
-
zrb/task/llm/prompt.py,sha256=
|
360
|
-
zrb/task/llm/tool_wrapper.py,sha256=
|
358
|
+
zrb/task/llm/print_node.py,sha256=BlIccGqMeKSLI7QGCVKtmUyi4-B64Mn4wzWj1Dbtl4o,4467
|
359
|
+
zrb/task/llm/prompt.py,sha256=FGXWYHecWtrNNkPnjg-uhnkqp7fYt8V91-AjFM_5fpA,11550
|
360
|
+
zrb/task/llm/tool_wrapper.py,sha256=AevU5cY8ztBE-HS27XBefouvP7JK44rau7z0e79vOWo,8352
|
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=aIo4pHaV2LV4E5E0aCDry7pwKKAvb78Saq5vgEc6t9Q,14449
|
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
|
@@ -406,7 +406,7 @@ zrb/util/todo.py,sha256=r9_KYF2-hLKMNjsp6AFK9zivykMrywd-kJ4bCwfdafI,19323
|
|
406
406
|
zrb/util/todo_model.py,sha256=hhzAX-uFl5rsg7iVX1ULlJOfBtblwQ_ieNUxBWfc-Os,1670
|
407
407
|
zrb/xcom/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
408
408
|
zrb/xcom/xcom.py,sha256=o79rxR9wphnShrcIushA0Qt71d_p3ZTxjNf7x9hJB78,1571
|
409
|
-
zrb-1.15.
|
410
|
-
zrb-1.15.
|
411
|
-
zrb-1.15.
|
412
|
-
zrb-1.15.
|
409
|
+
zrb-1.15.3.dist-info/METADATA,sha256=dvXTlDqIDrLqzZarWVexy1OLJ-W2ufWqptdARc1DBig,9807
|
410
|
+
zrb-1.15.3.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
411
|
+
zrb-1.15.3.dist-info/entry_points.txt,sha256=-Pg3ElWPfnaSM-XvXqCxEAa-wfVI6BEgcs386s8C8v8,46
|
412
|
+
zrb-1.15.3.dist-info/RECORD,,
|
File without changes
|
File without changes
|