zrb 1.8.10__py3-none-any.whl → 1.21.29__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.

Potentially problematic release.


This version of zrb might be problematic. Click here for more details.

Files changed (147) hide show
  1. zrb/__init__.py +126 -113
  2. zrb/__main__.py +1 -1
  3. zrb/attr/type.py +10 -7
  4. zrb/builtin/__init__.py +2 -50
  5. zrb/builtin/git.py +12 -1
  6. zrb/builtin/group.py +31 -15
  7. zrb/builtin/http.py +7 -8
  8. zrb/builtin/llm/attachment.py +40 -0
  9. zrb/builtin/llm/chat_completion.py +274 -0
  10. zrb/builtin/llm/chat_session.py +152 -85
  11. zrb/builtin/llm/chat_session_cmd.py +288 -0
  12. zrb/builtin/llm/chat_trigger.py +79 -0
  13. zrb/builtin/llm/history.py +7 -9
  14. zrb/builtin/llm/llm_ask.py +221 -98
  15. zrb/builtin/llm/tool/api.py +74 -52
  16. zrb/builtin/llm/tool/cli.py +46 -17
  17. zrb/builtin/llm/tool/code.py +71 -90
  18. zrb/builtin/llm/tool/file.py +301 -241
  19. zrb/builtin/llm/tool/note.py +84 -0
  20. zrb/builtin/llm/tool/rag.py +38 -8
  21. zrb/builtin/llm/tool/sub_agent.py +67 -50
  22. zrb/builtin/llm/tool/web.py +146 -122
  23. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/add_entity_util.py +7 -7
  24. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/add_module_util.py +5 -5
  25. zrb/builtin/project/add/fastapp/fastapp_util.py +1 -1
  26. zrb/builtin/searxng/config/settings.yml +5671 -0
  27. zrb/builtin/searxng/start.py +21 -0
  28. zrb/builtin/setup/latex/ubuntu.py +1 -0
  29. zrb/builtin/setup/ubuntu.py +1 -1
  30. zrb/builtin/shell/autocomplete/bash.py +4 -3
  31. zrb/builtin/shell/autocomplete/zsh.py +4 -3
  32. zrb/builtin/todo.py +13 -2
  33. zrb/config/config.py +614 -0
  34. zrb/config/default_prompt/file_extractor_system_prompt.md +112 -0
  35. zrb/config/default_prompt/interactive_system_prompt.md +29 -0
  36. zrb/config/default_prompt/persona.md +1 -0
  37. zrb/config/default_prompt/repo_extractor_system_prompt.md +112 -0
  38. zrb/config/default_prompt/repo_summarizer_system_prompt.md +29 -0
  39. zrb/config/default_prompt/summarization_prompt.md +57 -0
  40. zrb/config/default_prompt/system_prompt.md +38 -0
  41. zrb/config/llm_config.py +339 -0
  42. zrb/config/llm_context/config.py +166 -0
  43. zrb/config/llm_context/config_parser.py +40 -0
  44. zrb/config/llm_context/workflow.py +81 -0
  45. zrb/config/llm_rate_limitter.py +190 -0
  46. zrb/{runner → config}/web_auth_config.py +17 -22
  47. zrb/context/any_shared_context.py +17 -1
  48. zrb/context/context.py +16 -2
  49. zrb/context/shared_context.py +18 -8
  50. zrb/group/any_group.py +12 -5
  51. zrb/group/group.py +67 -3
  52. zrb/input/any_input.py +5 -1
  53. zrb/input/base_input.py +18 -6
  54. zrb/input/option_input.py +13 -1
  55. zrb/input/text_input.py +8 -25
  56. zrb/runner/cli.py +25 -23
  57. zrb/runner/common_util.py +24 -19
  58. zrb/runner/web_app.py +3 -3
  59. zrb/runner/web_route/docs_route.py +1 -1
  60. zrb/runner/web_route/error_page/serve_default_404.py +1 -1
  61. zrb/runner/web_route/error_page/show_error_page.py +1 -1
  62. zrb/runner/web_route/home_page/home_page_route.py +2 -2
  63. zrb/runner/web_route/login_api_route.py +1 -1
  64. zrb/runner/web_route/login_page/login_page_route.py +2 -2
  65. zrb/runner/web_route/logout_api_route.py +1 -1
  66. zrb/runner/web_route/logout_page/logout_page_route.py +2 -2
  67. zrb/runner/web_route/node_page/group/show_group_page.py +1 -1
  68. zrb/runner/web_route/node_page/node_page_route.py +1 -1
  69. zrb/runner/web_route/node_page/task/show_task_page.py +1 -1
  70. zrb/runner/web_route/refresh_token_api_route.py +1 -1
  71. zrb/runner/web_route/static/static_route.py +1 -1
  72. zrb/runner/web_route/task_input_api_route.py +6 -6
  73. zrb/runner/web_route/task_session_api_route.py +20 -12
  74. zrb/runner/web_util/cookie.py +1 -1
  75. zrb/runner/web_util/token.py +1 -1
  76. zrb/runner/web_util/user.py +8 -4
  77. zrb/session/any_session.py +24 -17
  78. zrb/session/session.py +50 -25
  79. zrb/session_state_logger/any_session_state_logger.py +9 -4
  80. zrb/session_state_logger/file_session_state_logger.py +16 -6
  81. zrb/session_state_logger/session_state_logger_factory.py +1 -1
  82. zrb/task/any_task.py +30 -9
  83. zrb/task/base/context.py +17 -9
  84. zrb/task/base/execution.py +15 -8
  85. zrb/task/base/lifecycle.py +8 -4
  86. zrb/task/base/monitoring.py +12 -7
  87. zrb/task/base_task.py +69 -5
  88. zrb/task/base_trigger.py +12 -5
  89. zrb/task/cmd_task.py +1 -1
  90. zrb/task/llm/agent.py +154 -161
  91. zrb/task/llm/agent_runner.py +152 -0
  92. zrb/task/llm/config.py +47 -18
  93. zrb/task/llm/conversation_history.py +209 -0
  94. zrb/task/llm/conversation_history_model.py +67 -0
  95. zrb/task/llm/default_workflow/coding/workflow.md +41 -0
  96. zrb/task/llm/default_workflow/copywriting/workflow.md +68 -0
  97. zrb/task/llm/default_workflow/git/workflow.md +118 -0
  98. zrb/task/llm/default_workflow/golang/workflow.md +128 -0
  99. zrb/task/llm/default_workflow/html-css/workflow.md +135 -0
  100. zrb/task/llm/default_workflow/java/workflow.md +146 -0
  101. zrb/task/llm/default_workflow/javascript/workflow.md +158 -0
  102. zrb/task/llm/default_workflow/python/workflow.md +160 -0
  103. zrb/task/llm/default_workflow/researching/workflow.md +153 -0
  104. zrb/task/llm/default_workflow/rust/workflow.md +162 -0
  105. zrb/task/llm/default_workflow/shell/workflow.md +299 -0
  106. zrb/task/llm/error.py +24 -10
  107. zrb/task/llm/file_replacement.py +206 -0
  108. zrb/task/llm/file_tool_model.py +57 -0
  109. zrb/task/llm/history_processor.py +206 -0
  110. zrb/task/llm/history_summarization.py +11 -166
  111. zrb/task/llm/print_node.py +193 -69
  112. zrb/task/llm/prompt.py +242 -45
  113. zrb/task/llm/subagent_conversation_history.py +41 -0
  114. zrb/task/llm/tool_wrapper.py +260 -57
  115. zrb/task/llm/workflow.py +76 -0
  116. zrb/task/llm_task.py +182 -171
  117. zrb/task/make_task.py +2 -3
  118. zrb/task/rsync_task.py +26 -11
  119. zrb/task/scheduler.py +4 -4
  120. zrb/util/attr.py +54 -39
  121. zrb/util/callable.py +23 -0
  122. zrb/util/cli/markdown.py +12 -0
  123. zrb/util/cli/text.py +30 -0
  124. zrb/util/file.py +29 -11
  125. zrb/util/git.py +8 -11
  126. zrb/util/git_diff_model.py +10 -0
  127. zrb/util/git_subtree.py +9 -14
  128. zrb/util/git_subtree_model.py +32 -0
  129. zrb/util/init_path.py +1 -1
  130. zrb/util/markdown.py +62 -0
  131. zrb/util/string/conversion.py +2 -2
  132. zrb/util/todo.py +17 -50
  133. zrb/util/todo_model.py +46 -0
  134. zrb/util/truncate.py +23 -0
  135. zrb/util/yaml.py +204 -0
  136. zrb/xcom/xcom.py +10 -0
  137. zrb-1.21.29.dist-info/METADATA +270 -0
  138. {zrb-1.8.10.dist-info → zrb-1.21.29.dist-info}/RECORD +140 -98
  139. {zrb-1.8.10.dist-info → zrb-1.21.29.dist-info}/WHEEL +1 -1
  140. zrb/config.py +0 -335
  141. zrb/llm_config.py +0 -411
  142. zrb/llm_rate_limitter.py +0 -125
  143. zrb/task/llm/context.py +0 -102
  144. zrb/task/llm/context_enrichment.py +0 -199
  145. zrb/task/llm/history.py +0 -211
  146. zrb-1.8.10.dist-info/METADATA +0 -264
  147. {zrb-1.8.10.dist-info → zrb-1.21.29.dist-info}/entry_points.txt +0 -0
@@ -3,39 +3,10 @@ import os
3
3
 
4
4
  from zrb.builtin.llm.tool.file import DEFAULT_EXCLUDED_PATTERNS, is_excluded
5
5
  from zrb.builtin.llm.tool.sub_agent import create_sub_agent_tool
6
+ from zrb.config.config import CFG
7
+ from zrb.config.llm_rate_limitter import llm_rate_limitter
6
8
  from zrb.context.any_context import AnyContext
7
- from zrb.llm_rate_limitter import llm_rate_limitter
8
-
9
- _EXTRACT_INFO_FROM_REPO_SYSTEM_PROMPT = """
10
- You are an extraction info agent.
11
- Your goal is to help to extract relevant information to help the main assistant.
12
- You write your output is in markdown format containing path and relevant information.
13
- Extract only information that relevant to main assistant's goal.
14
-
15
- Extracted Information format (Use this as reference, extract relevant information only):
16
- # <file-name>
17
- ## imports
18
- - <imported-package>
19
- - ...
20
- ## variables
21
- - <variable-type> <variable-name>: <the-purpose-of-the-variable>
22
- - ...
23
- ## functions
24
- - <function-name>:
25
- - parameters: <parameters>
26
- - logic/description: <what-the-function-do-and-how-it-works>
27
- ...
28
- # <other-file-name>
29
- ...
30
- """.strip()
31
-
32
-
33
- _SUMMARIZE_INFO_SYSTEM_PROMPT = """
34
- You are an information summarization agent.
35
- Your goal is to summarize information to help the main assistant.
36
- The summarization result should contains all necessary details
37
- to help main assistant achieve the goal.
38
- """
9
+ from zrb.util.cli.style import stylize_faint
39
10
 
40
11
  _DEFAULT_EXTENSIONS = [
41
12
  "py",
@@ -79,58 +50,67 @@ _DEFAULT_EXTENSIONS = [
79
50
  async def analyze_repo(
80
51
  ctx: AnyContext,
81
52
  path: str,
82
- goal: str,
53
+ query: str,
83
54
  extensions: list[str] = _DEFAULT_EXTENSIONS,
84
55
  exclude_patterns: list[str] = DEFAULT_EXCLUDED_PATTERNS,
85
- extraction_token_limit: int = 30000,
86
- summarization_token_limit: int = 30000,
56
+ extraction_token_threshold: int | None = None,
57
+ summarization_token_threshold: int | None = None,
87
58
  ) -> str:
88
59
  """
89
- Extract and summarize information from a directory that probably
90
- contains a large resources.
91
- You should state the goal specifically so that the tool can return relevant informations.
92
- Use this tool for:
93
- - summarization
94
- - outline/structure extraction
95
- - code review
96
- - create diagram as code
97
- - other tasks
60
+ Analyzes a code repository or directory to answer a specific query.
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.
65
+
66
+ Example:
67
+ analyze_repo(
68
+ path='src/my_project',
69
+ query='Summarize the main functionalities by analyzing Python files.',
70
+ extensions=['py']
71
+ )
72
+
98
73
  Args:
99
- path (str): File path to be analyze. Pass exactly as provided, including '~'.
100
- goal(str): Goal of extracting information (for example creating C4 diagram)
101
- extensions(Optional[list[str]]): List of extension to be included
102
- while reading resources. Defaults to common programming languages and config files.
103
- exclude_patterns(Optional[list[str]]): List of patterns to exclude from analysis.
104
- Common patterns like '.venv', 'node_modules' should be excluded by default.
105
- extraction_token_limit(Optional[int]): Max resource content char length
106
- the extraction assistant able to handle. Defaults to 150000
107
- summarization_token_limit(Optional[int]): Max resource content char length
108
- the summarization assistant able to handle. Defaults to 150000
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.
81
+
109
82
  Returns:
110
- str: The analysis result
111
- Raises:
112
- Exception: If an error occurs.
83
+ str: Detailed, markdown-formatted analysis and summary.
113
84
  """
85
+ if extraction_token_threshold is None:
86
+ extraction_token_threshold = CFG.LLM_REPO_ANALYSIS_EXTRACTION_TOKEN_THRESHOLD
87
+ if summarization_token_threshold is None:
88
+ summarization_token_threshold = (
89
+ CFG.LLM_REPO_ANALYSIS_SUMMARIZATION_TOKEN_THRESHOLD
90
+ )
114
91
  abs_path = os.path.abspath(os.path.expanduser(path))
115
92
  file_metadatas = _get_file_metadatas(abs_path, extensions, exclude_patterns)
116
- ctx.print("Extraction")
93
+ ctx.print(stylize_faint(" 📝 Extraction"), plain=True)
117
94
  extracted_infos = await _extract_info(
118
95
  ctx,
119
96
  file_metadatas=file_metadatas,
120
- goal=goal,
121
- token_limit=extraction_token_limit,
97
+ query=query,
98
+ token_limit=extraction_token_threshold,
122
99
  )
100
+ if len(extracted_infos) == 0:
101
+ raise RuntimeError(
102
+ "No info can be extracted, adjust extensions or exclude_patterns."
103
+ )
123
104
  if len(extracted_infos) == 1:
124
105
  return extracted_infos[0]
125
- ctx.print("Summarization")
126
106
  summarized_infos = extracted_infos
127
107
  while len(summarized_infos) > 1:
128
- ctx.print("Summarization")
108
+ ctx.print(stylize_faint(" 📝 Summarization"), plain=True)
129
109
  summarized_infos = await _summarize_info(
130
110
  ctx,
131
111
  extracted_infos=summarized_infos,
132
- goal=goal,
133
- token_limit=summarization_token_limit,
112
+ query=query,
113
+ token_limit=summarization_token_threshold,
134
114
  )
135
115
  return summarized_infos[0]
136
116
 
@@ -147,11 +127,11 @@ def _get_file_metadatas(
147
127
  if not any(file.endswith(f".{ext}") for ext in extensions):
148
128
  continue
149
129
  file_path = os.path.join(root, file)
150
- if is_excluded(file_path, exclude_patterns):
151
- continue
152
130
  try:
131
+ rel_path = os.path.relpath(file_path, dir_path)
132
+ if is_excluded(rel_path, exclude_patterns):
133
+ continue
153
134
  with open(file_path, "r", encoding="utf-8", errors="ignore") as f:
154
- rel_path = os.path.relpath(file_path, dir_path)
155
135
  metadata_list.append({"path": rel_path, "content": f.read()})
156
136
  except Exception as e:
157
137
  print(f"Error reading file {file_path}: {e}")
@@ -162,13 +142,15 @@ def _get_file_metadatas(
162
142
  async def _extract_info(
163
143
  ctx: AnyContext,
164
144
  file_metadatas: list[dict[str, str]],
165
- goal: str,
145
+ query: str,
166
146
  token_limit: int,
167
147
  ) -> list[str]:
168
148
  extract = create_sub_agent_tool(
169
149
  tool_name="extract",
170
150
  tool_description="extract",
171
- system_prompt=_EXTRACT_INFO_FROM_REPO_SYSTEM_PROMPT,
151
+ system_prompt=CFG.LLM_REPO_EXTRACTOR_SYSTEM_PROMPT,
152
+ auto_summarize=False,
153
+ remember_history=False,
172
154
  )
173
155
  extracted_infos = []
174
156
  content_buffer = []
@@ -180,7 +162,7 @@ async def _extract_info(
180
162
  file_str = json.dumps(file_obj)
181
163
  if current_token_count + llm_rate_limitter.count_token(file_str) > token_limit:
182
164
  if content_buffer:
183
- prompt = _create_extract_info_prompt(goal, content_buffer)
165
+ prompt = json.dumps(_create_extract_info_prompt(query, content_buffer))
184
166
  extracted_info = await extract(
185
167
  ctx, llm_rate_limitter.clip_prompt(prompt, token_limit)
186
168
  )
@@ -190,10 +172,9 @@ async def _extract_info(
190
172
  else:
191
173
  content_buffer.append(file_obj)
192
174
  current_token_count += llm_rate_limitter.count_token(file_str)
193
-
194
175
  # Process any remaining content in the buffer
195
176
  if content_buffer:
196
- prompt = _create_extract_info_prompt(goal, content_buffer)
177
+ prompt = json.dumps(_create_extract_info_prompt(query, content_buffer))
197
178
  extracted_info = await extract(
198
179
  ctx, llm_rate_limitter.clip_prompt(prompt, token_limit)
199
180
  )
@@ -201,25 +182,25 @@ async def _extract_info(
201
182
  return extracted_infos
202
183
 
203
184
 
204
- def _create_extract_info_prompt(goal: str, content_buffer: list[dict]) -> str:
205
- return json.dumps(
206
- {
207
- "main_assistant_goal": goal,
208
- "files": content_buffer,
209
- }
210
- )
185
+ def _create_extract_info_prompt(query: str, content_buffer: list[dict]) -> dict:
186
+ return {
187
+ "main_assistant_query": query,
188
+ "files": content_buffer,
189
+ }
211
190
 
212
191
 
213
192
  async def _summarize_info(
214
193
  ctx: AnyContext,
215
194
  extracted_infos: list[str],
216
- goal: str,
195
+ query: str,
217
196
  token_limit: int,
218
197
  ) -> list[str]:
219
198
  summarize = create_sub_agent_tool(
220
199
  tool_name="extract",
221
200
  tool_description="extract",
222
- system_prompt=_SUMMARIZE_INFO_SYSTEM_PROMPT,
201
+ system_prompt=CFG.LLM_REPO_SUMMARIZER_SYSTEM_PROMPT,
202
+ auto_summarize=False,
203
+ remember_history=False,
223
204
  )
224
205
  summarized_infos = []
225
206
  content_buffer = ""
@@ -227,7 +208,9 @@ async def _summarize_info(
227
208
  new_prompt = content_buffer + extracted_info
228
209
  if llm_rate_limitter.count_token(new_prompt) > token_limit:
229
210
  if content_buffer:
230
- prompt = _create_summarize_info_prompt(goal, content_buffer)
211
+ prompt = json.dumps(
212
+ _create_summarize_info_prompt(query, content_buffer)
213
+ )
231
214
  summarized_info = await summarize(
232
215
  ctx, llm_rate_limitter.clip_prompt(prompt, token_limit)
233
216
  )
@@ -238,7 +221,7 @@ async def _summarize_info(
238
221
 
239
222
  # Process any remaining content in the buffer
240
223
  if content_buffer:
241
- prompt = _create_summarize_info_prompt(goal, content_buffer)
224
+ prompt = json.dumps(_create_summarize_info_prompt(query, content_buffer))
242
225
  summarized_info = await summarize(
243
226
  ctx, llm_rate_limitter.clip_prompt(prompt, token_limit)
244
227
  )
@@ -246,10 +229,8 @@ async def _summarize_info(
246
229
  return summarized_infos
247
230
 
248
231
 
249
- def _create_summarize_info_prompt(goal: str, content_buffer: str) -> str:
250
- return json.dumps(
251
- {
252
- "main_assistant_goal": goal,
253
- "extracted_info": content_buffer,
254
- }
255
- )
232
+ def _create_summarize_info_prompt(query: str, content_buffer: str) -> dict:
233
+ return {
234
+ "main_assistant_query": query,
235
+ "extracted_info": content_buffer,
236
+ }