zrb 1.15.12__py3-none-any.whl → 1.15.13__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.
@@ -122,7 +122,6 @@ async def analyze_repo(
122
122
  )
123
123
  if len(extracted_infos) == 1:
124
124
  return extracted_infos[0]
125
- ctx.print(stylize_faint(" 📝 Summarization"), plain=True)
126
125
  summarized_infos = extracted_infos
127
126
  while len(summarized_infos) > 1:
128
127
  ctx.print(stylize_faint(" 📝 Summarization"), plain=True)
@@ -1,16 +1,17 @@
1
- You are a memory management AI. Your goal is to curate the conversation history by calling `write_past_conversation_summary`, `write_past_conversation_transcript`, `write_long_term_note` and `write_contextual_note`.
1
+ You are a memory management AI. Your goal is to curate the conversation history by calling the `update_conversation_memory` tool.
2
2
 
3
3
  Follow these steps precisely:
4
4
 
5
- **Step 1: Update Conversation Summary and Transcript**
5
+ **Step 1: Consolidate Conversation Information**
6
6
 
7
- 1. Call the `write_past_conversation_summary` tool ONCE. The summary you provide must be a concise narrative that integrates the previous summary with the `Recent Conversation`.
8
- 2. Call the `write_past_conversation_transcript` tool ONCE. The content for this tool MUST be ONLY the last 4 (four) turns of the conversation. Do not change or shorten the content of these turns. Ensure the timestamp format is `[YYYY-MM-DD HH:MM:SS UTC+Z] Role: Message/Tool name being called`.
7
+ 1. Create a concise narrative summary that integrates the `Past Conversation Summary` with the `Recent Conversation`.
8
+ 2. Extract ONLY the last 4 (four) turns of the `Recent Conversation` to serve as the new transcript. Do not change or shorten the content of these turns. Ensure the timestamp format is `[YYYY-MM-DD HH:MM:SS UTC+Z] Role: Message/Tool name being called`.
9
+ 3. Review the `Notes` and the `Recent Conversation` to identify any new or updated facts.
10
+ * Update global facts about the user or their preferences for the `long_term_note`.
11
+ * Update facts specific to the current project or directory for the `contextual_note`.
12
+ * **CRITICAL:** When updating `contextual_note`, you MUST determine the correct `context_path` by analyzing the `Recent Conversation`. For example, if a fact was established when the working directory was `/app`, the `context_path` MUST be `/app`.
13
+ * **CRITICAL:** The content for notes must be raw, unformatted text. Do not use Markdown. Notes should be timeless facts, not a log of events. Only update notes if the information has actually changed.
9
14
 
10
- **Step 2: Update Factual Notes**
15
+ **Step 2: Update Memory**
11
16
 
12
- 1. First, read the existing notes to understand the current state.
13
- 2. Call `write_long_term_note` AT MOST ONCE. Use it to add or update global facts about the user or their preferences.
14
- 3. Call `write_contextual_note` AT MOST ONCE. Use it to add or update facts specific to the current project or directory (`context_path`).
15
- 4. **CRITICAL:** When calling `write_contextual_note`, you MUST determine the correct `context_path` by analyzing the `Recent Conversation`. For example, if a fact was established when the working directory was `/app`, the `context_path` MUST be `/app`.
16
- 5. **CRITICAL:** The content for notes must be raw, unformatted text. Do not use Markdown. Notes should be timeless facts, not a log of events. Only update notes if the information has actually changed.
17
+ 1. Call the `update_conversation_memory` tool ONCE, providing all the information you consolidated in Step 1 as arguments.
@@ -35,6 +35,17 @@ class LLMContextConfig:
35
35
  all_sections.append((config_dir, sections))
36
36
  return all_sections
37
37
 
38
+ def _normalize_context_path(
39
+ self,
40
+ path_str: str,
41
+ relative_to_dir: str,
42
+ ) -> str:
43
+ """Normalizes a context path string to an absolute path."""
44
+ expanded_path = os.path.expanduser(path_str)
45
+ if os.path.isabs(expanded_path):
46
+ return os.path.abspath(expanded_path)
47
+ return os.path.abspath(os.path.join(relative_to_dir, expanded_path))
48
+
38
49
  def get_contexts(self, cwd: str | None = None) -> dict[str, str]:
39
50
  """Gathers all relevant contexts for a given path."""
40
51
  if cwd is None:
@@ -44,15 +55,14 @@ class LLMContextConfig:
44
55
  for config_dir, sections in reversed(all_sections):
45
56
  for key, value in sections.items():
46
57
  if key.startswith("Context:"):
47
- context_path = key[len("Context:") :].strip()
48
- if context_path == ".":
49
- context_path = config_dir
50
- elif not os.path.isabs(context_path):
51
- context_path = os.path.abspath(
52
- os.path.join(config_dir, context_path)
53
- )
54
- if os.path.isabs(context_path) or cwd.startswith(context_path):
55
- contexts[context_path] = value
58
+ context_path_str = key[len("Context:") :].strip()
59
+ abs_context_path = self._normalize_context_path(
60
+ context_path_str,
61
+ config_dir,
62
+ )
63
+ # A context is relevant if its path is an ancestor of cwd
64
+ if os.path.commonpath([cwd, abs_context_path]) == abs_context_path:
65
+ contexts[abs_context_path] = value
56
66
  return contexts
57
67
 
58
68
  def get_workflows(self, cwd: str | None = None) -> dict[str, str]:
@@ -61,60 +71,79 @@ class LLMContextConfig:
61
71
  cwd = os.getcwd()
62
72
  all_sections = self._get_all_sections(cwd)
63
73
  workflows: dict[str, str] = {}
64
- for _, sections in reversed(all_sections):
74
+ # Iterate from closest to farthest
75
+ for _, sections in all_sections:
65
76
  for key, value in sections.items():
66
77
  if key.startswith("Workflow:"):
67
- workflow_name = key[len("Workflow:") :].strip()
68
- workflow_name = key.replace("Workflow:", "").lower().strip()
69
- workflows[workflow_name] = value
78
+ workflow_name = key[len("Workflow:") :].strip().lower()
79
+ # First one found wins
80
+ if workflow_name not in workflows:
81
+ workflows[workflow_name] = value
70
82
  return workflows
71
83
 
84
+ def _format_context_path_for_writing(
85
+ self,
86
+ path_to_write: str,
87
+ cwd: str,
88
+ ) -> str:
89
+ """Formats a path for writing into a context file key."""
90
+ home_dir = os.path.expanduser("~")
91
+ abs_path_to_write = os.path.abspath(os.path.join(cwd, path_to_write))
92
+ abs_cwd = os.path.abspath(cwd)
93
+ # Rule 1: Inside CWD
94
+ if abs_path_to_write.startswith(abs_cwd):
95
+ if abs_path_to_write == abs_cwd:
96
+ return "."
97
+ return os.path.relpath(abs_path_to_write, abs_cwd)
98
+ # Rule 2: Inside Home
99
+ if abs_path_to_write.startswith(home_dir):
100
+ if abs_path_to_write == home_dir:
101
+ return "~"
102
+ return os.path.join("~", os.path.relpath(abs_path_to_write, home_dir))
103
+ # Rule 3: Absolute
104
+ return abs_path_to_write
105
+
72
106
  def write_context(
73
- self, content: str, context_path: str | None = None, cwd: str | None = None
107
+ self,
108
+ content: str,
109
+ context_path: str | None = None,
110
+ cwd: str | None = None,
74
111
  ):
75
- """Writes content to a context block in the nearest configuration file."""
112
+ """Writes content to a context block in CWD's configuration file."""
76
113
  if cwd is None:
77
114
  cwd = os.getcwd()
78
115
  if context_path is None:
79
116
  context_path = cwd
80
117
 
81
- config_files = self._find_config_files(cwd)
82
- if config_files:
83
- config_file = config_files[0] # Closest config file
84
- else:
85
- config_file = os.path.join(cwd, CFG.LLM_CONTEXT_FILE)
118
+ config_file = os.path.join(cwd, CFG.LLM_CONTEXT_FILE)
86
119
 
87
120
  sections = {}
88
121
  if os.path.exists(config_file):
89
122
  sections = self._parse_config(config_file)
90
123
 
91
- # Determine the section key
92
- section_key_path = context_path
93
- if not os.path.isabs(context_path):
94
- config_dir = os.path.dirname(config_file)
95
- section_key_path = os.path.abspath(os.path.join(config_dir, context_path))
124
+ abs_context_path = os.path.abspath(os.path.join(cwd, context_path))
96
125
 
97
- # Find existing key
98
- found_key = ""
126
+ found_key = None
99
127
  for key in sections.keys():
100
128
  if not key.startswith("Context:"):
101
129
  continue
102
- key_path = key.replace("Context:", "").strip()
103
- if key_path == ".":
104
- key_path = os.path.dirname(config_file)
105
- elif not os.path.isabs(key_path):
106
- key_path = os.path.abspath(
107
- os.path.join(os.path.dirname(config_file), key_path)
108
- )
109
- if key_path == section_key_path:
130
+ context_path_str = key[len("Context:") :].strip()
131
+ abs_key_path = self._normalize_context_path(
132
+ context_path_str,
133
+ os.path.dirname(config_file),
134
+ )
135
+ if abs_key_path == abs_context_path:
110
136
  found_key = key
111
137
  break
112
138
 
113
- if found_key != "":
139
+ if found_key:
114
140
  sections[found_key] = content
115
141
  else:
116
- # Add new entry
117
- new_key = f"Context: {context_path}"
142
+ formatted_path = self._format_context_path_for_writing(
143
+ context_path,
144
+ cwd,
145
+ )
146
+ new_key = f"Context: {formatted_path}"
118
147
  sections[new_key] = content
119
148
 
120
149
  # Serialize back to markdown
@@ -1,18 +1,46 @@
1
1
  import json
2
+ import os
2
3
  from collections.abc import Callable
3
4
  from copy import deepcopy
4
5
  from typing import Any
5
6
 
6
7
  from zrb.attr.type import StrAttr
8
+ from zrb.config.llm_context.config import llm_context_config
7
9
  from zrb.context.any_context import AnyContext
8
10
  from zrb.context.any_shared_context import AnySharedContext
9
11
  from zrb.task.llm.conversation_history_model import ConversationHistory
10
12
  from zrb.task.llm.typing import ListOfDict
11
13
  from zrb.util.attr import get_str_attr
12
- from zrb.util.file import write_file
14
+ from zrb.util.file import read_file, write_file
15
+ from zrb.util.llm.prompt import make_prompt_section
13
16
  from zrb.util.run import run_async
14
17
 
15
18
 
19
+ def inject_conversation_history_notes(conversation_history: ConversationHistory):
20
+ conversation_history.long_term_note = _fetch_long_term_note(
21
+ conversation_history.project_path
22
+ )
23
+ conversation_history.contextual_note = _fetch_contextual_note(
24
+ conversation_history.project_path
25
+ )
26
+
27
+
28
+ def _fetch_long_term_note(project_path: str) -> str:
29
+ contexts = llm_context_config.get_contexts(cwd=project_path)
30
+ return contexts.get("/", "")
31
+
32
+
33
+ def _fetch_contextual_note(project_path: str) -> str:
34
+ contexts = llm_context_config.get_contexts(cwd=project_path)
35
+ return "\n".join(
36
+ [
37
+ make_prompt_section(header, content)
38
+ for header, content in contexts.items()
39
+ if header != "/"
40
+ ]
41
+ )
42
+
43
+
16
44
  def get_history_file(
17
45
  ctx: AnyContext,
18
46
  conversation_history_file_attr: StrAttr | None,
@@ -27,6 +55,49 @@ def get_history_file(
27
55
  )
28
56
 
29
57
 
58
+ async def _read_from_source(
59
+ ctx: AnyContext,
60
+ reader: Callable[[AnyContext], dict[str, Any] | list | None] | None,
61
+ file_path: str | None,
62
+ ) -> "ConversationHistory | None":
63
+ # Priority 1: Reader function
64
+ if reader:
65
+ try:
66
+ raw_data = await run_async(reader(ctx))
67
+ if raw_data:
68
+ instance = ConversationHistory.parse_and_validate(
69
+ ctx, raw_data, "reader"
70
+ )
71
+ if instance:
72
+ return instance
73
+ except Exception as e:
74
+ ctx.log_warning(
75
+ f"Error executing conversation history reader: {e}. Ignoring."
76
+ )
77
+ # Priority 2: History file
78
+ if file_path and os.path.isfile(file_path):
79
+ try:
80
+ content = read_file(file_path)
81
+ raw_data = json.loads(content)
82
+ instance = ConversationHistory.parse_and_validate(
83
+ ctx, raw_data, f"file '{file_path}'"
84
+ )
85
+ if instance:
86
+ return instance
87
+ except json.JSONDecodeError:
88
+ ctx.log_warning(
89
+ f"Could not decode JSON from history file '{file_path}'. "
90
+ "Ignoring file content."
91
+ )
92
+ except Exception as e:
93
+ ctx.log_warning(
94
+ f"Error reading history file '{file_path}': {e}. "
95
+ "Ignoring file content."
96
+ )
97
+ # Fallback: Return default value
98
+ return None
99
+
100
+
30
101
  async def read_conversation_history(
31
102
  ctx: AnyContext,
32
103
  conversation_history_reader: (
@@ -46,7 +117,7 @@ async def read_conversation_history(
46
117
  ctx, conversation_history_file_attr, render_history_file
47
118
  )
48
119
  # Use the class method defined above
49
- history_data = await ConversationHistory.read_from_source(
120
+ history_data = await _read_from_source(
50
121
  ctx=ctx,
51
122
  reader=conversation_history_reader,
52
123
  file_path=history_file,
@@ -1,14 +1,9 @@
1
1
  import json
2
2
  import os
3
- from collections.abc import Callable
4
3
  from typing import Any
5
4
 
6
- from zrb.config.llm_context.config import llm_context_config
7
5
  from zrb.context.any_context import AnyContext
8
6
  from zrb.task.llm.typing import ListOfDict
9
- from zrb.util.file import read_file
10
- from zrb.util.llm.prompt import make_prompt_section
11
- from zrb.util.run import run_async
12
7
 
13
8
 
14
9
  class ConversationHistory:
@@ -41,50 +36,6 @@ class ConversationHistory:
41
36
  def model_dump_json(self, indent: int = 2) -> str:
42
37
  return json.dumps(self.to_dict(), indent=indent)
43
38
 
44
- @classmethod
45
- async def read_from_source(
46
- cls,
47
- ctx: AnyContext,
48
- reader: Callable[[AnyContext], dict[str, Any] | list | None] | None,
49
- file_path: str | None,
50
- ) -> "ConversationHistory | None":
51
- # Priority 1: Reader function
52
- if reader:
53
- try:
54
- raw_data = await run_async(reader(ctx))
55
- if raw_data:
56
- instance = cls.parse_and_validate(ctx, raw_data, "reader")
57
- if instance:
58
- return instance
59
- except Exception as e:
60
- ctx.log_warning(
61
- f"Error executing conversation history reader: {e}. Ignoring."
62
- )
63
- # Priority 2: History file
64
- if file_path and os.path.isfile(file_path):
65
- try:
66
- content = read_file(file_path)
67
- raw_data = json.loads(content)
68
- instance = cls.parse_and_validate(ctx, raw_data, f"file '{file_path}'")
69
- if instance:
70
- return instance
71
- except json.JSONDecodeError:
72
- ctx.log_warning(
73
- f"Could not decode JSON from history file '{file_path}'. "
74
- "Ignoring file content."
75
- )
76
- except Exception as e:
77
- ctx.log_warning(
78
- f"Error reading history file '{file_path}': {e}. "
79
- "Ignoring file content."
80
- )
81
- # Fallback: Return default value
82
- return None
83
-
84
- def fetch_newest_notes(self):
85
- self._fetch_long_term_note()
86
- self._fetch_contextual_note()
87
-
88
39
  @classmethod
89
40
  def parse_and_validate(
90
41
  cls, ctx: AnyContext, data: Any, source: str
@@ -121,122 +72,3 @@ class ConversationHistory:
121
72
  f"Error validating/parsing history data from {source}: {e}. Ignoring."
122
73
  )
123
74
  return cls()
124
-
125
- def write_past_conversation_summary(self, past_conversation_summary: str):
126
- """
127
- Write or update the past conversation summary.
128
-
129
- Use this tool to store or update a summary of previous conversations for
130
- future reference. This is useful for providing context to LLMs or other tools
131
- that need a concise history.
132
-
133
- Args:
134
- past_conversation_summary (str): The summary text to store.
135
-
136
- Returns:
137
- str: A JSON object indicating the success or failure of the operation.
138
-
139
- Raises:
140
- Exception: If the summary cannot be written.
141
- """
142
- self.past_conversation_summary = past_conversation_summary
143
- return json.dumps({"success": True})
144
-
145
- def write_past_conversation_transcript(self, past_conversation_transcript: str):
146
- """
147
- Write or update the past conversation transcript.
148
-
149
- Use this tool to store or update the full transcript of previous conversations.
150
- This is useful for providing detailed context to LLMs or for record-keeping.
151
-
152
- Args:
153
- past_conversation_transcript (str): The transcript text to store.
154
-
155
- Returns:
156
- str: A JSON object indicating the success or failure of the operation.
157
-
158
- Raises:
159
- Exception: If the transcript cannot be written.
160
- """
161
- self.past_conversation_transcript = past_conversation_transcript
162
- return json.dumps({"success": True})
163
-
164
- def read_long_term_note(self) -> str:
165
- """
166
- Read the content of the long-term references.
167
-
168
- This tool helps you retrieve knowledge or notes stored for long-term reference.
169
- If the note does not exist, you may want to create it using the write tool.
170
-
171
- Returns:
172
- str: JSON with content of the notes.
173
-
174
- Raises:
175
- Exception: If the note cannot be read.
176
- """
177
- return json.dumps({"content": self._fetch_long_term_note()})
178
-
179
- def write_long_term_note(self, content: str) -> str:
180
- """
181
- Write the entire content of the long-term references.
182
- This will overwrite any existing long-term notes.
183
-
184
- Args:
185
- content (str): The full content of the long-term notes.
186
-
187
- Returns:
188
- str: JSON indicating success.
189
- """
190
- llm_context_config.write_context(content, context_path="/")
191
- return json.dumps({"success": True})
192
-
193
- def read_contextual_note(self) -> str:
194
- """
195
- Read the content of the contextual references for the current project.
196
-
197
- This tool helps you retrieve knowledge or notes stored for contextual reference.
198
- If the note does not exist, you may want to create it using the write tool.
199
-
200
- Returns:
201
- str: JSON with content of the notes.
202
-
203
- Raises:
204
- Exception: If the note cannot be read.
205
- """
206
- return json.dumps({"content": self._fetch_contextual_note()})
207
-
208
- def write_contextual_note(
209
- self, content: str, context_path: str | None = None
210
- ) -> str:
211
- """
212
- Write the entire content of the contextual references for a specific path.
213
- This will overwrite any existing contextual notes for that path.
214
-
215
- Args:
216
- content (str): The full content of the contextual notes.
217
- context_path (str, optional): The directory path for the context.
218
- Defaults to the current project path.
219
-
220
- Returns:
221
- str: JSON indicating success.
222
- """
223
- if context_path is None:
224
- context_path = self.project_path
225
- llm_context_config.write_context(content, context_path=context_path)
226
- return json.dumps({"success": True})
227
-
228
- def _fetch_long_term_note(self):
229
- contexts = llm_context_config.get_contexts(cwd=self.project_path)
230
- self.long_term_note = contexts.get("/", "")
231
- return self.long_term_note
232
-
233
- def _fetch_contextual_note(self):
234
- contexts = llm_context_config.get_contexts(cwd=self.project_path)
235
- self.contextual_note = "\n".join(
236
- [
237
- make_prompt_section(header, content)
238
- for header, content in contexts.items()
239
- if header != "/"
240
- ]
241
- )
242
- return self.contextual_note
@@ -9,9 +9,13 @@ from zrb.context.any_context import AnyContext
9
9
  from zrb.task.llm.agent import run_agent_iteration
10
10
  from zrb.task.llm.conversation_history import (
11
11
  count_part_in_history_list,
12
+ inject_conversation_history_notes,
12
13
  replace_system_prompt_in_history,
13
14
  )
14
15
  from zrb.task.llm.conversation_history_model import ConversationHistory
16
+ from zrb.task.llm.history_summarization_tool import (
17
+ create_history_summarization_tool,
18
+ )
15
19
  from zrb.task.llm.typing import ListOfDict
16
20
  from zrb.util.attr import get_bool_attr, get_int_attr
17
21
  from zrb.util.cli.style import stylize_faint
@@ -93,6 +97,7 @@ async def summarize_history(
93
97
  """Runs an LLM call to update the conversation summary."""
94
98
  from pydantic_ai import Agent
95
99
 
100
+ inject_conversation_history_notes(conversation_history)
96
101
  ctx.log_info("Attempting to summarize conversation history...")
97
102
  # Construct the user prompt for the summarization agent
98
103
  user_prompt = "\n".join(
@@ -143,14 +148,7 @@ async def summarize_history(
143
148
  system_prompt=system_prompt,
144
149
  model_settings=settings,
145
150
  retries=retries,
146
- tools=[
147
- conversation_history.write_past_conversation_summary,
148
- conversation_history.write_past_conversation_transcript,
149
- conversation_history.read_long_term_note,
150
- conversation_history.write_long_term_note,
151
- conversation_history.read_contextual_note,
152
- conversation_history.write_contextual_note,
153
- ],
151
+ tools=[create_history_summarization_tool(conversation_history)],
154
152
  )
155
153
  try:
156
154
  ctx.print(stylize_faint(" 📝 Rollup Conversation"), plain=True)
@@ -0,0 +1,38 @@
1
+ import json
2
+ from typing import Callable
3
+
4
+ from zrb.config.llm_context.config import llm_context_config
5
+ from zrb.task.llm.conversation_history_model import ConversationHistory
6
+
7
+
8
+ def create_history_summarization_tool(
9
+ conversation_history: ConversationHistory,
10
+ ) -> Callable:
11
+ def update_conversation_memory(
12
+ past_conversation_summary: str,
13
+ past_conversation_transcript: str,
14
+ long_term_note: str | None = None,
15
+ contextual_note: str | None = None,
16
+ context_path: str | None = None,
17
+ ):
18
+ """
19
+ Update the conversation memory including summary, transcript, and notes.
20
+ - past_conversation_summary: A concise narrative that integrates the
21
+ previous summary with the recent conversation.
22
+ - past_conversation_transcript: MUST be ONLY the last 4 (four) turns
23
+ of the conversation.
24
+ - long_term_note: Global facts about the user or their preferences.
25
+ - contextual_note: Facts specific to the current project or directory.
26
+ - context_path: The directory path for the contextual note.
27
+ """
28
+ conversation_history.past_conversation_summary = past_conversation_summary
29
+ conversation_history.past_conversation_transcript = past_conversation_transcript
30
+ if long_term_note is not None:
31
+ llm_context_config.write_context(long_term_note, context_path="/")
32
+ if contextual_note is not None:
33
+ if context_path is None:
34
+ context_path = conversation_history.project_path
35
+ llm_context_config.write_context(contextual_note, context_path=context_path)
36
+ return json.dumps({"success": True})
37
+
38
+ return update_conversation_memory
zrb/task/llm_task.py CHANGED
@@ -17,6 +17,7 @@ from zrb.task.llm.config import (
17
17
  get_model_settings,
18
18
  )
19
19
  from zrb.task.llm.conversation_history import (
20
+ inject_conversation_history_notes,
20
21
  read_conversation_history,
21
22
  write_conversation_history,
22
23
  )
@@ -241,7 +242,7 @@ class LLMTask(BaseTask):
241
242
  render_history_file=self._render_history_file,
242
243
  conversation_history_attr=self._conversation_history,
243
244
  )
244
- conversation_history.fetch_newest_notes()
245
+ inject_conversation_history_notes(conversation_history)
245
246
  # 2. Get system prompt and user prompt
246
247
  system_prompt, user_message = get_system_and_user_prompt(
247
248
  ctx=ctx,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: zrb
3
- Version: 1.15.12
3
+ Version: 1.15.13
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
@@ -17,7 +17,7 @@ zrb/builtin/llm/previous-session.js,sha256=xMKZvJoAbrwiyHS0OoPrWuaKxWYLoyR5sgueP
17
17
  zrb/builtin/llm/tool/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
18
18
  zrb/builtin/llm/tool/api.py,sha256=vMEiZhhTZ3o2jRBxWcJ62b0M85wd_w4W0X4Hx23NXto,2380
19
19
  zrb/builtin/llm/tool/cli.py,sha256=8rugrKaNPEatHjr7nN4OIRLRT2TcF-oylEZGbLI9Brs,1254
20
- zrb/builtin/llm/tool/code.py,sha256=BACeH0tGhTdDo0rZ7sTAP6oRaLi9cS7gdEigXiTd0Jg,8842
20
+ zrb/builtin/llm/tool/code.py,sha256=fr9FbmtfwizQTyTztvuvwAb9MD_auRZhPZfoJVBlKT4,8777
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
23
  zrb/builtin/llm/tool/sub_agent.py,sha256=dPqdFCXxJ-3hZnPjheZr-bPeKNbfSBSDKcZZR5vkWFM,5075
@@ -223,10 +223,10 @@ zrb/config/default_prompt/interactive_system_prompt.md,sha256=XvXI51dMpQmuuYah_L
223
223
  zrb/config/default_prompt/persona.md,sha256=GfUJ4-Mlf_Bm1YTzxFNkPkdVbAi06ZDVYh-iIma3NOs,253
224
224
  zrb/config/default_prompt/repo_extractor_system_prompt.md,sha256=EGZ-zj78RlMEg2jduRBs8WzO4VJTkXHR96IpBepZMsY,3881
225
225
  zrb/config/default_prompt/repo_summarizer_system_prompt.md,sha256=RNy37Wg7ibXj3DlsFKaYvgMpMS-lyXlM1LZlc59_4ic,2009
226
- zrb/config/default_prompt/summarization_prompt.md,sha256=SWaZvy9FBEPvaZ4xmR3NaNFrM9MANiqIKQlYwx2LmTw,1602
226
+ zrb/config/default_prompt/summarization_prompt.md,sha256=GMqbw7mmDWQf7rhnJcJjXQFtGu7nVYIZfK6sStJ4coc,1472
227
227
  zrb/config/default_prompt/system_prompt.md,sha256=gEb6N-cFg6VvOV-7ZffNwVt39DavAGesMqn9u0epbRc,2282
228
228
  zrb/config/llm_config.py,sha256=xt-Xf8ZuNoUT_GKCSFz5yy0BhbeHzxP-jrezB06WeiY,8857
229
- zrb/config/llm_context/config.py,sha256=PDsrKAduQfsEUMYt4jirG0F7KDkY7jqhrbsptxdMOEg,4962
229
+ zrb/config/llm_context/config.py,sha256=TPQX_kU772r0AHmVFeo1WGLDAidacT-qDyuMWxY_avg,5878
230
230
  zrb/config/llm_context/config_parser.py,sha256=h95FbOjvVobhrsfGtG_BY3hxS-OLzQj-9F5vGZuehkY,1473
231
231
  zrb/config/llm_rate_limitter.py,sha256=_iQRv3d6kUPeRvmUYZX_iwCE7iDSEK1oKa4bQ9GROho,5261
232
232
  zrb/config/web_auth_config.py,sha256=_PXatQTYh2mX9H3HSYSQKp13zm1RlLyVIoeIr6KYMQ8,6279
@@ -348,18 +348,19 @@ zrb/task/http_check.py,sha256=Gf5rOB2Se2EdizuN9rp65HpGmfZkGc-clIAlHmPVehs,2565
348
348
  zrb/task/llm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
349
349
  zrb/task/llm/agent.py,sha256=jfC90N8oER2z-fTmPEuWH3ASPgw5t8cZm8rk98HBBlw,8876
350
350
  zrb/task/llm/config.py,sha256=n1SPmwab09K2i1sL_OCwrEOWHI0Owx_hvWelg3Dreus,3781
351
- zrb/task/llm/conversation_history.py,sha256=B_PDWYL_q66s0xwWBzMSomqPN6u3gkXlIeXBD5A0Apg,4416
352
- zrb/task/llm/conversation_history_model.py,sha256=DJ0KDBB0BriQuE5ugC_q0aSHhjNIBcfjUk1f0S_3I9U,9245
351
+ zrb/task/llm/conversation_history.py,sha256=oMdKUV2__mBZ4znnA-prl-gfyoleKC8Nj5KNpmLQJ4o,6764
352
+ zrb/task/llm/conversation_history_model.py,sha256=kk-7niTl29Rm2EUIhTHzPXgZ5tp4IThMnIB3dS-1OdU,3062
353
353
  zrb/task/llm/default_workflow/coding.md,sha256=2uythvPsnBpYfIhiIH1cCinQXX0i0yUqsL474Zpemw0,2484
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=_eWFP4cAn3tTfyt7YPjnPwm_PgMhMChPg9g2q2Gsf0c,8172
357
+ zrb/task/llm/history_summarization.py,sha256=UIT8bpdT3hy1xn559waDLFWZlNtIqdIpIvRGcZEpHm0,8057
358
+ zrb/task/llm/history_summarization_tool.py,sha256=Wazi4WMr3k1WJ1v7QgjAPbuY1JdBpHUsTWGt3DSTsLc,1706
358
359
  zrb/task/llm/print_node.py,sha256=fNTL0LtoZBQQPHYCAUaOFP97nNNfobPXvY2RlxewQCE,7556
359
360
  zrb/task/llm/prompt.py,sha256=FGXWYHecWtrNNkPnjg-uhnkqp7fYt8V91-AjFM_5fpA,11550
360
361
  zrb/task/llm/tool_wrapper.py,sha256=IavXwW9C0ojI3ivGDY8j7XbMJE_NTJeI86TVbHNRwJ0,9684
361
362
  zrb/task/llm/typing.py,sha256=c8VAuPBw_4A3DxfYdydkgedaP-LU61W9_wj3m3CAX1E,58
362
- zrb/task/llm_task.py,sha256=0c9F_AjeMLxQX8VlAJHfZAkC52PhRaWbcKoqVOggcMg,14451
363
+ zrb/task/llm_task.py,sha256=ctEp-5R7ZnjA3V6pSkthKN_o7xjASre8MgMcQVHtsj8,14504
363
364
  zrb/task/make_task.py,sha256=PD3b_aYazthS8LHeJsLAhwKDEgdurQZpymJDKeN60u0,2265
364
365
  zrb/task/rsync_task.py,sha256=WfqNSaicJgYWpunNU34eYxXDqHDHOftuDHyWJKjqwg0,6365
365
366
  zrb/task/scaffolder.py,sha256=rME18w1HJUHXgi9eTYXx_T2G4JdqDYzBoNOkdOOo5-o,6806
@@ -408,7 +409,7 @@ zrb/util/todo_model.py,sha256=hhzAX-uFl5rsg7iVX1ULlJOfBtblwQ_ieNUxBWfc-Os,1670
408
409
  zrb/util/truncate.py,sha256=eSzmjBpc1Qod3lM3M73snNbDOcARHukW_tq36dWdPvc,921
409
410
  zrb/xcom/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
410
411
  zrb/xcom/xcom.py,sha256=o79rxR9wphnShrcIushA0Qt71d_p3ZTxjNf7x9hJB78,1571
411
- zrb-1.15.12.dist-info/METADATA,sha256=KiHkwdLLBMFBj_uiZnvnEuet3XvcYqNDbYf22VGB5H8,9775
412
- zrb-1.15.12.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
413
- zrb-1.15.12.dist-info/entry_points.txt,sha256=-Pg3ElWPfnaSM-XvXqCxEAa-wfVI6BEgcs386s8C8v8,46
414
- zrb-1.15.12.dist-info/RECORD,,
412
+ zrb-1.15.13.dist-info/METADATA,sha256=lDKm2YdMNhKPRFayict53Twk3Bd_nnQExw7tZFqWe5c,9775
413
+ zrb-1.15.13.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
414
+ zrb-1.15.13.dist-info/entry_points.txt,sha256=-Pg3ElWPfnaSM-XvXqCxEAa-wfVI6BEgcs386s8C8v8,46
415
+ zrb-1.15.13.dist-info/RECORD,,
File without changes