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/builtin/llm/tool/code.py
CHANGED
|
@@ -6,6 +6,7 @@ from zrb.builtin.llm.tool.sub_agent import create_sub_agent_tool
|
|
|
6
6
|
from zrb.config.config import CFG
|
|
7
7
|
from zrb.config.llm_rate_limitter import llm_rate_limitter
|
|
8
8
|
from zrb.context.any_context import AnyContext
|
|
9
|
+
from zrb.util.cli.style import stylize_faint
|
|
9
10
|
|
|
10
11
|
_DEFAULT_EXTENSIONS = [
|
|
11
12
|
"py",
|
|
@@ -49,36 +50,37 @@ _DEFAULT_EXTENSIONS = [
|
|
|
49
50
|
async def analyze_repo(
|
|
50
51
|
ctx: AnyContext,
|
|
51
52
|
path: str,
|
|
52
|
-
|
|
53
|
+
query: str,
|
|
53
54
|
extensions: list[str] = _DEFAULT_EXTENSIONS,
|
|
54
55
|
exclude_patterns: list[str] = DEFAULT_EXCLUDED_PATTERNS,
|
|
55
56
|
extraction_token_threshold: int | None = None,
|
|
56
57
|
summarization_token_threshold: int | None = None,
|
|
57
58
|
) -> str:
|
|
58
59
|
"""
|
|
59
|
-
|
|
60
|
+
Analyzes a code repository or directory to answer a specific query.
|
|
60
61
|
|
|
61
|
-
|
|
62
|
+
CRITICAL: The quality of analysis depends entirely on the query. Vague queries yield poor
|
|
63
|
+
results.
|
|
64
|
+
IMPORTANT: This tool can be slow and expensive on large repositories. Use judiciously.
|
|
62
65
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
66
|
+
Example:
|
|
67
|
+
analyze_repo(
|
|
68
|
+
path='src/my_project',
|
|
69
|
+
query='Summarize the main functionalities by analyzing Python files.',
|
|
70
|
+
extensions=['py']
|
|
71
|
+
)
|
|
69
72
|
|
|
70
73
|
Args:
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
74
|
+
ctx (AnyContext): The execution context.
|
|
75
|
+
path (str): Path to the directory or repository.
|
|
76
|
+
query (str): Clear and specific analysis question or goal.
|
|
77
|
+
extensions (list[str], optional): File extensions to include.
|
|
78
|
+
exclude_patterns (list[str], optional): Glob patterns to exclude.
|
|
79
|
+
extraction_token_threshold (int, optional): Token limit for extraction sub-agent.
|
|
80
|
+
summarization_token_threshold (int, optional): Token limit for summarization sub-agent.
|
|
77
81
|
|
|
78
82
|
Returns:
|
|
79
|
-
str:
|
|
80
|
-
Raises:
|
|
81
|
-
Exception: If an error occurs during the analysis.
|
|
83
|
+
str: Detailed, markdown-formatted analysis and summary.
|
|
82
84
|
"""
|
|
83
85
|
if extraction_token_threshold is None:
|
|
84
86
|
extraction_token_threshold = CFG.LLM_REPO_ANALYSIS_EXTRACTION_TOKEN_THRESHOLD
|
|
@@ -88,23 +90,26 @@ async def analyze_repo(
|
|
|
88
90
|
)
|
|
89
91
|
abs_path = os.path.abspath(os.path.expanduser(path))
|
|
90
92
|
file_metadatas = _get_file_metadatas(abs_path, extensions, exclude_patterns)
|
|
91
|
-
ctx.print("Extraction")
|
|
93
|
+
ctx.print(stylize_faint(" 📝 Extraction"), plain=True)
|
|
92
94
|
extracted_infos = await _extract_info(
|
|
93
95
|
ctx,
|
|
94
96
|
file_metadatas=file_metadatas,
|
|
95
|
-
|
|
97
|
+
query=query,
|
|
96
98
|
token_limit=extraction_token_threshold,
|
|
97
99
|
)
|
|
100
|
+
if len(extracted_infos) == 0:
|
|
101
|
+
raise RuntimeError(
|
|
102
|
+
"No info can be extracted, adjust extensions or exclude_patterns."
|
|
103
|
+
)
|
|
98
104
|
if len(extracted_infos) == 1:
|
|
99
105
|
return extracted_infos[0]
|
|
100
|
-
ctx.print("Summarization")
|
|
101
106
|
summarized_infos = extracted_infos
|
|
102
107
|
while len(summarized_infos) > 1:
|
|
103
|
-
ctx.print("Summarization")
|
|
108
|
+
ctx.print(stylize_faint(" 📝 Summarization"), plain=True)
|
|
104
109
|
summarized_infos = await _summarize_info(
|
|
105
110
|
ctx,
|
|
106
111
|
extracted_infos=summarized_infos,
|
|
107
|
-
|
|
112
|
+
query=query,
|
|
108
113
|
token_limit=summarization_token_threshold,
|
|
109
114
|
)
|
|
110
115
|
return summarized_infos[0]
|
|
@@ -122,11 +127,11 @@ def _get_file_metadatas(
|
|
|
122
127
|
if not any(file.endswith(f".{ext}") for ext in extensions):
|
|
123
128
|
continue
|
|
124
129
|
file_path = os.path.join(root, file)
|
|
125
|
-
if is_excluded(file_path, exclude_patterns):
|
|
126
|
-
continue
|
|
127
130
|
try:
|
|
131
|
+
rel_path = os.path.relpath(file_path, dir_path)
|
|
132
|
+
if is_excluded(rel_path, exclude_patterns):
|
|
133
|
+
continue
|
|
128
134
|
with open(file_path, "r", encoding="utf-8", errors="ignore") as f:
|
|
129
|
-
rel_path = os.path.relpath(file_path, dir_path)
|
|
130
135
|
metadata_list.append({"path": rel_path, "content": f.read()})
|
|
131
136
|
except Exception as e:
|
|
132
137
|
print(f"Error reading file {file_path}: {e}")
|
|
@@ -137,7 +142,7 @@ def _get_file_metadatas(
|
|
|
137
142
|
async def _extract_info(
|
|
138
143
|
ctx: AnyContext,
|
|
139
144
|
file_metadatas: list[dict[str, str]],
|
|
140
|
-
|
|
145
|
+
query: str,
|
|
141
146
|
token_limit: int,
|
|
142
147
|
) -> list[str]:
|
|
143
148
|
extract = create_sub_agent_tool(
|
|
@@ -155,7 +160,7 @@ async def _extract_info(
|
|
|
155
160
|
file_str = json.dumps(file_obj)
|
|
156
161
|
if current_token_count + llm_rate_limitter.count_token(file_str) > token_limit:
|
|
157
162
|
if content_buffer:
|
|
158
|
-
prompt = _create_extract_info_prompt(
|
|
163
|
+
prompt = json.dumps(_create_extract_info_prompt(query, content_buffer))
|
|
159
164
|
extracted_info = await extract(
|
|
160
165
|
ctx, llm_rate_limitter.clip_prompt(prompt, token_limit)
|
|
161
166
|
)
|
|
@@ -165,10 +170,9 @@ async def _extract_info(
|
|
|
165
170
|
else:
|
|
166
171
|
content_buffer.append(file_obj)
|
|
167
172
|
current_token_count += llm_rate_limitter.count_token(file_str)
|
|
168
|
-
|
|
169
173
|
# Process any remaining content in the buffer
|
|
170
174
|
if content_buffer:
|
|
171
|
-
prompt = _create_extract_info_prompt(
|
|
175
|
+
prompt = json.dumps(_create_extract_info_prompt(query, content_buffer))
|
|
172
176
|
extracted_info = await extract(
|
|
173
177
|
ctx, llm_rate_limitter.clip_prompt(prompt, token_limit)
|
|
174
178
|
)
|
|
@@ -176,19 +180,17 @@ async def _extract_info(
|
|
|
176
180
|
return extracted_infos
|
|
177
181
|
|
|
178
182
|
|
|
179
|
-
def _create_extract_info_prompt(
|
|
180
|
-
return
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
}
|
|
185
|
-
)
|
|
183
|
+
def _create_extract_info_prompt(query: str, content_buffer: list[dict]) -> dict:
|
|
184
|
+
return {
|
|
185
|
+
"main_assistant_query": query,
|
|
186
|
+
"files": content_buffer,
|
|
187
|
+
}
|
|
186
188
|
|
|
187
189
|
|
|
188
190
|
async def _summarize_info(
|
|
189
191
|
ctx: AnyContext,
|
|
190
192
|
extracted_infos: list[str],
|
|
191
|
-
|
|
193
|
+
query: str,
|
|
192
194
|
token_limit: int,
|
|
193
195
|
) -> list[str]:
|
|
194
196
|
summarize = create_sub_agent_tool(
|
|
@@ -202,7 +204,9 @@ async def _summarize_info(
|
|
|
202
204
|
new_prompt = content_buffer + extracted_info
|
|
203
205
|
if llm_rate_limitter.count_token(new_prompt) > token_limit:
|
|
204
206
|
if content_buffer:
|
|
205
|
-
prompt =
|
|
207
|
+
prompt = json.dumps(
|
|
208
|
+
_create_summarize_info_prompt(query, content_buffer)
|
|
209
|
+
)
|
|
206
210
|
summarized_info = await summarize(
|
|
207
211
|
ctx, llm_rate_limitter.clip_prompt(prompt, token_limit)
|
|
208
212
|
)
|
|
@@ -213,7 +217,7 @@ async def _summarize_info(
|
|
|
213
217
|
|
|
214
218
|
# Process any remaining content in the buffer
|
|
215
219
|
if content_buffer:
|
|
216
|
-
prompt = _create_summarize_info_prompt(
|
|
220
|
+
prompt = json.dumps(_create_summarize_info_prompt(query, content_buffer))
|
|
217
221
|
summarized_info = await summarize(
|
|
218
222
|
ctx, llm_rate_limitter.clip_prompt(prompt, token_limit)
|
|
219
223
|
)
|
|
@@ -221,10 +225,8 @@ async def _summarize_info(
|
|
|
221
225
|
return summarized_infos
|
|
222
226
|
|
|
223
227
|
|
|
224
|
-
def _create_summarize_info_prompt(
|
|
225
|
-
return
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
}
|
|
230
|
-
)
|
|
228
|
+
def _create_summarize_info_prompt(query: str, content_buffer: str) -> dict:
|
|
229
|
+
return {
|
|
230
|
+
"main_assistant_query": query,
|
|
231
|
+
"extracted_info": content_buffer,
|
|
232
|
+
}
|