zrb 1.16.2__py3-none-any.whl → 1.16.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/__init__.py +1 -0
- zrb/builtin/llm/chat_session.py +13 -20
- zrb/builtin/llm/chat_trigger.py +73 -0
- zrb/builtin/llm/llm_ask.py +1 -1
- zrb/builtin/llm/tool/code.py +7 -3
- zrb/builtin/llm/tool/sub_agent.py +1 -2
- {zrb-1.16.2.dist-info → zrb-1.16.3.dist-info}/METADATA +1 -1
- {zrb-1.16.2.dist-info → zrb-1.16.3.dist-info}/RECORD +10 -9
- {zrb-1.16.2.dist-info → zrb-1.16.3.dist-info}/WHEEL +0 -0
- {zrb-1.16.2.dist-info → zrb-1.16.3.dist-info}/entry_points.txt +0 -0
zrb/builtin/__init__.py
CHANGED
@@ -9,6 +9,7 @@ from zrb.builtin.git import (
|
|
9
9
|
from zrb.builtin.git_subtree import git_add_subtree, git_pull_subtree, git_push_subtree
|
10
10
|
from zrb.builtin.http import generate_curl, http_request
|
11
11
|
from zrb.builtin.jwt import decode_jwt, encode_jwt, validate_jwt
|
12
|
+
from zrb.builtin.llm.chat_trigger import llm_chat_trigger
|
12
13
|
from zrb.builtin.llm.llm_ask import llm_ask
|
13
14
|
from zrb.builtin.md5 import hash_md5, sum_md5, validate_md5
|
14
15
|
from zrb.builtin.project.add.fastapp.fastapp_task import add_fastapp_to_project
|
zrb/builtin/llm/chat_session.py
CHANGED
@@ -7,13 +7,20 @@ conversation flow via XCom.
|
|
7
7
|
|
8
8
|
import asyncio
|
9
9
|
import sys
|
10
|
+
from typing import TYPE_CHECKING, Any
|
10
11
|
|
12
|
+
from zrb.builtin.llm.chat_trigger import llm_chat_trigger
|
11
13
|
from zrb.config.llm_config import llm_config
|
12
14
|
from zrb.context.any_context import AnyContext
|
13
15
|
from zrb.util.cli.markdown import render_markdown
|
14
16
|
from zrb.util.cli.style import stylize_blue, stylize_bold_yellow, stylize_faint
|
15
17
|
from zrb.util.string.conversion import to_boolean
|
16
18
|
|
19
|
+
if TYPE_CHECKING:
|
20
|
+
from asyncio import StreamReader
|
21
|
+
|
22
|
+
from prompt_toolkit import PromptSession
|
23
|
+
|
17
24
|
|
18
25
|
async def read_user_prompt(ctx: AnyContext) -> str:
|
19
26
|
"""
|
@@ -22,7 +29,7 @@ async def read_user_prompt(ctx: AnyContext) -> str:
|
|
22
29
|
"""
|
23
30
|
_show_info(ctx)
|
24
31
|
is_tty: bool = ctx.is_tty
|
25
|
-
reader = await _setup_input_reader(is_tty)
|
32
|
+
reader: PromptSession[Any] | StreamReader = await _setup_input_reader(is_tty)
|
26
33
|
multiline_mode = False
|
27
34
|
is_first_time = True
|
28
35
|
current_modes: str = ctx.input.modes
|
@@ -32,7 +39,7 @@ async def read_user_prompt(ctx: AnyContext) -> str:
|
|
32
39
|
while True:
|
33
40
|
await asyncio.sleep(0.01)
|
34
41
|
previous_session_name: str | None = (
|
35
|
-
ctx.input.previous_session if is_first_time else
|
42
|
+
ctx.input.previous_session if is_first_time else ""
|
36
43
|
)
|
37
44
|
start_new: bool = ctx.input.start_new if is_first_time else False
|
38
45
|
if is_first_time and ctx.input.message.strip() != "":
|
@@ -41,7 +48,7 @@ async def read_user_prompt(ctx: AnyContext) -> str:
|
|
41
48
|
# Get user input based on mode
|
42
49
|
if not multiline_mode:
|
43
50
|
ctx.print("💬 >>", plain=True)
|
44
|
-
user_input = await
|
51
|
+
user_input = await llm_chat_trigger.wait(reader, ctx)
|
45
52
|
if not multiline_mode:
|
46
53
|
ctx.print("", plain=True)
|
47
54
|
is_first_time = False
|
@@ -153,7 +160,9 @@ def _show_subcommand(command: str, description: str) -> str:
|
|
153
160
|
return f" {styled_command} {styled_description}"
|
154
161
|
|
155
162
|
|
156
|
-
async def _setup_input_reader(
|
163
|
+
async def _setup_input_reader(
|
164
|
+
is_interactive: bool,
|
165
|
+
) -> "PromptSession[Any] | StreamReader":
|
157
166
|
"""Sets up and returns the appropriate asynchronous input reader."""
|
158
167
|
if is_interactive:
|
159
168
|
from prompt_toolkit import PromptSession
|
@@ -167,22 +176,6 @@ async def _setup_input_reader(is_interactive: bool):
|
|
167
176
|
return reader
|
168
177
|
|
169
178
|
|
170
|
-
async def _read_next_line(reader, ctx: AnyContext) -> str:
|
171
|
-
"""Reads one line of input using the provided reader."""
|
172
|
-
from prompt_toolkit import PromptSession
|
173
|
-
|
174
|
-
if isinstance(reader, PromptSession):
|
175
|
-
return await reader.prompt_async()
|
176
|
-
|
177
|
-
line_bytes = await reader.readline()
|
178
|
-
if not line_bytes:
|
179
|
-
return "/bye" # Signal to exit
|
180
|
-
|
181
|
-
user_input = line_bytes.decode().strip()
|
182
|
-
ctx.print(user_input, plain=True)
|
183
|
-
return user_input
|
184
|
-
|
185
|
-
|
186
179
|
async def _trigger_ask_and_wait_for_result(
|
187
180
|
ctx: AnyContext,
|
188
181
|
user_prompt: str,
|
@@ -0,0 +1,73 @@
|
|
1
|
+
import asyncio
|
2
|
+
from asyncio import StreamReader
|
3
|
+
from typing import TYPE_CHECKING, Any, Callable, Coroutine
|
4
|
+
|
5
|
+
from zrb.context.any_context import AnyContext
|
6
|
+
from zrb.util.run import run_async
|
7
|
+
|
8
|
+
if TYPE_CHECKING:
|
9
|
+
from prompt_toolkit import PromptSession
|
10
|
+
|
11
|
+
|
12
|
+
ChatTrigger = Callable[[AnyContext], Coroutine[Any, Any, str] | str]
|
13
|
+
|
14
|
+
|
15
|
+
class LLMChatTrigger:
|
16
|
+
|
17
|
+
def __init__(self):
|
18
|
+
self._triggers: list[ChatTrigger] = []
|
19
|
+
|
20
|
+
def add_trigger(self, *trigger: ChatTrigger):
|
21
|
+
self.append_trigger(*trigger)
|
22
|
+
|
23
|
+
def append_trigger(self, *trigger: ChatTrigger):
|
24
|
+
for single_trigger in trigger:
|
25
|
+
self._triggers.append(single_trigger)
|
26
|
+
|
27
|
+
async def wait(
|
28
|
+
self, reader: "PromptSession[Any] | StreamReader", ctx: AnyContext
|
29
|
+
) -> str:
|
30
|
+
trigger_tasks = [
|
31
|
+
asyncio.create_task(run_async(self._read_next_line(reader, ctx)))
|
32
|
+
] + [asyncio.create_task(run_async(trigger(ctx))) for trigger in self._triggers]
|
33
|
+
final_result: str = ""
|
34
|
+
try:
|
35
|
+
done, pending = await asyncio.wait(
|
36
|
+
trigger_tasks, return_when=asyncio.FIRST_COMPLETED
|
37
|
+
)
|
38
|
+
for task in done:
|
39
|
+
final_result = await task
|
40
|
+
if pending:
|
41
|
+
for task in pending:
|
42
|
+
task.cancel()
|
43
|
+
for task in done:
|
44
|
+
break
|
45
|
+
except asyncio.CancelledError:
|
46
|
+
ctx.print("Task cancelled.", plain=True)
|
47
|
+
final_result = "/bye"
|
48
|
+
except KeyboardInterrupt:
|
49
|
+
ctx.print("KeyboardInterrupt detected. Exiting...", plain=True)
|
50
|
+
final_result = "/bye"
|
51
|
+
return final_result
|
52
|
+
|
53
|
+
async def _read_next_line(
|
54
|
+
self, reader: "PromptSession[Any] | StreamReader", ctx: AnyContext
|
55
|
+
) -> str:
|
56
|
+
"""Reads one line of input using the provided reader."""
|
57
|
+
from prompt_toolkit import PromptSession
|
58
|
+
|
59
|
+
try:
|
60
|
+
if isinstance(reader, PromptSession):
|
61
|
+
return await reader.prompt_async()
|
62
|
+
line_bytes = await reader.readline()
|
63
|
+
if not line_bytes:
|
64
|
+
return "/bye" # Signal to exit
|
65
|
+
user_input = line_bytes.decode().strip()
|
66
|
+
ctx.print(user_input, plain=True)
|
67
|
+
return user_input
|
68
|
+
except KeyboardInterrupt:
|
69
|
+
ctx.print("KeyboardInterrupt detected. Exiting...", plain=True)
|
70
|
+
return "/bye"
|
71
|
+
|
72
|
+
|
73
|
+
llm_chat_trigger = LLMChatTrigger()
|
zrb/builtin/llm/llm_ask.py
CHANGED
@@ -106,7 +106,7 @@ def _render_yolo_mode_input(ctx: AnyContext) -> list[str] | bool | None:
|
|
106
106
|
return elements
|
107
107
|
|
108
108
|
|
109
|
-
def _get_inputs(require_message: bool = True) -> list[AnyInput]:
|
109
|
+
def _get_inputs(require_message: bool = True) -> list[AnyInput | None]:
|
110
110
|
return [
|
111
111
|
StrInput(
|
112
112
|
"model",
|
zrb/builtin/llm/tool/code.py
CHANGED
@@ -120,6 +120,10 @@ async def analyze_repo(
|
|
120
120
|
goal=goal,
|
121
121
|
token_limit=extraction_token_threshold,
|
122
122
|
)
|
123
|
+
if len(extracted_infos) == 0:
|
124
|
+
raise RuntimeError(
|
125
|
+
"No info can be extracted, adjust extensions or exclude_patterns."
|
126
|
+
)
|
123
127
|
if len(extracted_infos) == 1:
|
124
128
|
return extracted_infos[0]
|
125
129
|
summarized_infos = extracted_infos
|
@@ -146,11 +150,11 @@ def _get_file_metadatas(
|
|
146
150
|
if not any(file.endswith(f".{ext}") for ext in extensions):
|
147
151
|
continue
|
148
152
|
file_path = os.path.join(root, file)
|
149
|
-
if is_excluded(file_path, exclude_patterns):
|
150
|
-
continue
|
151
153
|
try:
|
154
|
+
rel_path = os.path.relpath(file_path, dir_path)
|
155
|
+
if is_excluded(rel_path, exclude_patterns):
|
156
|
+
continue
|
152
157
|
with open(file_path, "r", encoding="utf-8", errors="ignore") as f:
|
153
|
-
rel_path = os.path.relpath(file_path, dir_path)
|
154
158
|
metadata_list.append({"path": rel_path, "content": f.read()})
|
155
159
|
except Exception as e:
|
156
160
|
print(f"Error reading file {file_path}: {e}")
|
@@ -1,4 +1,3 @@
|
|
1
|
-
import json
|
2
1
|
from collections.abc import Callable
|
3
2
|
from textwrap import dedent
|
4
3
|
from typing import TYPE_CHECKING, Any, Coroutine
|
@@ -9,7 +8,7 @@ from zrb.task.llm.config import get_model, get_model_settings
|
|
9
8
|
from zrb.task.llm.prompt import get_system_and_user_prompt
|
10
9
|
|
11
10
|
if TYPE_CHECKING:
|
12
|
-
from pydantic_ai import
|
11
|
+
from pydantic_ai import Tool
|
13
12
|
from pydantic_ai.models import Model
|
14
13
|
from pydantic_ai.settings import ModelSettings
|
15
14
|
from pydantic_ai.toolsets import AbstractToolset
|
@@ -2,25 +2,26 @@ zrb/__init__.py,sha256=qkCV2EnAGIgvsawBHYvKgPAp0zzPcikYSmbQXATLzg4,5060
|
|
2
2
|
zrb/__main__.py,sha256=9SXH9MK4PVyU9lkEyHxiIUABbcsV2wseP94HmlqTR4M,2657
|
3
3
|
zrb/attr/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
4
4
|
zrb/attr/type.py,sha256=4TV5gPYMMrKh5V-yB6iRYKCbsXAH_AvGXMsjxKLHcUs,568
|
5
|
-
zrb/builtin/__init__.py,sha256=
|
5
|
+
zrb/builtin/__init__.py,sha256=qeLg_S7mRWe48AYrzNutAgAnLh2YE57-iEVK0ICd-3A,1672
|
6
6
|
zrb/builtin/base64.py,sha256=UjaFttE2oRx0T7_RpKtKfgMtWfiQXfJBAJmA16ek8Ic,1507
|
7
7
|
zrb/builtin/git.py,sha256=8_qVE_2lVQEVXQ9vhiw8Tn4Prj1VZB78ZjEJJS5Ab3M,5461
|
8
8
|
zrb/builtin/git_subtree.py,sha256=7BKwOkVTWDrR0DXXQ4iJyHqeR6sV5VYRt8y_rEB0EHg,3505
|
9
9
|
zrb/builtin/group.py,sha256=zYC5uw0VE97TXiLCr464kFJ-CJIJyeQ2RXjnVRY5ovs,2577
|
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=6q40xQdv56OtaTZCVSS16WDchn4l0sagZI2BGX_JyQM,10448
|
13
|
+
zrb/builtin/llm/chat_trigger.py,sha256=xaJmzrvBGz6LFPOpYnG9bMeT1dY6XqZPXamtr9e72-w,2427
|
13
14
|
zrb/builtin/llm/history.py,sha256=LDOrL0p7r_AHLa5L8Dp7bHNsOALugmJd7OguXRWGnm4,3087
|
14
15
|
zrb/builtin/llm/input.py,sha256=Nw-26uTWp2QhUgKJcP_IMHmtk-b542CCSQ_vCOjhvhM,877
|
15
|
-
zrb/builtin/llm/llm_ask.py,sha256=
|
16
|
+
zrb/builtin/llm/llm_ask.py,sha256=8V5YAShUPes5qnlxLaS9Ks4KOs7oCQFGrpfkj-6rLMU,7546
|
16
17
|
zrb/builtin/llm/previous-session.js,sha256=xMKZvJoAbrwiyHS0OoPrWuaKxWYLoyR5sguePIoCjTY,816
|
17
18
|
zrb/builtin/llm/tool/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
18
19
|
zrb/builtin/llm/tool/api.py,sha256=p55Fs6QTmsM2u-vVcBJb9xYxGAkiHIKX2wYKhsGlWFE,2417
|
19
20
|
zrb/builtin/llm/tool/cli.py,sha256=sm_maE1WBB051odh1xXr8QQOWln_ewAU_7OScKAneT4,1244
|
20
|
-
zrb/builtin/llm/tool/code.py,sha256
|
21
|
+
zrb/builtin/llm/tool/code.py,sha256=-MKUpXX4jkWm4rCqrUmTTzsYhjfzKle9_XsNPtq8PNM,8952
|
21
22
|
zrb/builtin/llm/tool/file.py,sha256=fDgt31CWwZtOYOk6lfBSBxX85NARLr-ZzXPvG1JP8C0,23589
|
22
23
|
zrb/builtin/llm/tool/rag.py,sha256=aN8D8ZqzGXWCP_1F1LbN0QgfyzaK9CKrjfTPorDIYjw,9824
|
23
|
-
zrb/builtin/llm/tool/sub_agent.py,sha256=
|
24
|
+
zrb/builtin/llm/tool/sub_agent.py,sha256=nYluPfc8FlSobpP_4vnBIqkPARrDHq_SwKkmlh_ATUI,5067
|
24
25
|
zrb/builtin/llm/tool/web.py,sha256=zDgxYRIQRj9A8QXb80-ZSPmGCvIOWy8bpJMGSAuTL8Y,7491
|
25
26
|
zrb/builtin/md5.py,sha256=690RV2LbW7wQeTFxY-lmmqTSVEEZv3XZbjEUW1Q3XpE,1480
|
26
27
|
zrb/builtin/project/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -410,7 +411,7 @@ zrb/util/todo_model.py,sha256=hhzAX-uFl5rsg7iVX1ULlJOfBtblwQ_ieNUxBWfc-Os,1670
|
|
410
411
|
zrb/util/truncate.py,sha256=eSzmjBpc1Qod3lM3M73snNbDOcARHukW_tq36dWdPvc,921
|
411
412
|
zrb/xcom/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
412
413
|
zrb/xcom/xcom.py,sha256=o79rxR9wphnShrcIushA0Qt71d_p3ZTxjNf7x9hJB78,1571
|
413
|
-
zrb-1.16.
|
414
|
-
zrb-1.16.
|
415
|
-
zrb-1.16.
|
416
|
-
zrb-1.16.
|
414
|
+
zrb-1.16.3.dist-info/METADATA,sha256=XONEHMCkv5j0YPf35oaP5MYliI1CYXoPXUv-8FNKFI4,9935
|
415
|
+
zrb-1.16.3.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
416
|
+
zrb-1.16.3.dist-info/entry_points.txt,sha256=-Pg3ElWPfnaSM-XvXqCxEAa-wfVI6BEgcs386s8C8v8,46
|
417
|
+
zrb-1.16.3.dist-info/RECORD,,
|
File without changes
|
File without changes
|