quantalogic 0.32.0__py3-none-any.whl → 0.33.0__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.
quantalogic/agent.py CHANGED
@@ -52,11 +52,7 @@ class ObserveResponseResult(BaseModel):
52
52
  class Agent(BaseModel):
53
53
  """Enhanced QuantaLogic agent implementing ReAct framework."""
54
54
 
55
- model_config = ConfigDict(
56
- arbitrary_types_allowed=True,
57
- validate_assignment=True,
58
- extra="forbid"
59
- )
55
+ model_config = ConfigDict(arbitrary_types_allowed=True, validate_assignment=True, extra="forbid")
60
56
 
61
57
  specific_expertise: str
62
58
  model: GenerativeModel
@@ -95,7 +91,7 @@ class Agent(BaseModel):
95
91
  """Initialize the agent with model, memory, tools, and configurations."""
96
92
  try:
97
93
  logger.debug("Initializing agent...")
98
-
94
+
99
95
  # Create event emitter
100
96
  event_emitter = EventEmitter()
101
97
 
@@ -142,9 +138,9 @@ class Agent(BaseModel):
142
138
  compact_every_n_iterations=compact_every_n_iterations or 30,
143
139
  max_tokens_working_memory=max_tokens_working_memory,
144
140
  )
145
-
141
+
146
142
  self._model_name = model_name
147
-
143
+
148
144
  logger.debug(f"Memory will be compacted every {self.compact_every_n_iterations} iterations")
149
145
  logger.debug(f"Max tokens for working memory set to: {self.max_tokens_working_memory}")
150
146
  logger.debug("Agent initialized successfully.")
@@ -168,7 +164,9 @@ class Agent(BaseModel):
168
164
  """Clear the memory and reset the session."""
169
165
  self._reset_session(clear_memory=True)
170
166
 
171
- def solve_task(self, task: str, max_iterations: int = 30, streaming: bool = False, clear_memory: bool = True) -> str:
167
+ def solve_task(
168
+ self, task: str, max_iterations: int = 30, streaming: bool = False, clear_memory: bool = True
169
+ ) -> str:
172
170
  """Solve the given task using the ReAct framework.
173
171
 
174
172
  Args:
@@ -182,7 +180,7 @@ class Agent(BaseModel):
182
180
  str: The final response after task completion.
183
181
  """
184
182
  logger.debug(f"Solving task... {task}")
185
- self._reset_session(task_to_solve=task, max_iterations=max_iterations,clear_memory=clear_memory)
183
+ self._reset_session(task_to_solve=task, max_iterations=max_iterations, clear_memory=clear_memory)
186
184
 
187
185
  # Generate task summary
188
186
  self.task_to_solve_summary = self._generate_task_summary(task)
@@ -228,7 +226,9 @@ class Agent(BaseModel):
228
226
  # For streaming, collect the response chunks
229
227
  content = ""
230
228
  for chunk in self.model.generate_with_history(
231
- messages_history=self.memory.memory, prompt=current_prompt, streaming=True
229
+ messages_history=self.memory.memory,
230
+ prompt=current_prompt,
231
+ streaming=True,
232
232
  ):
233
233
  content += chunk
234
234
 
@@ -245,7 +245,8 @@ class Agent(BaseModel):
245
245
  )
246
246
  else:
247
247
  result = self.model.generate_with_history(
248
- messages_history=self.memory.memory, prompt=current_prompt, streaming=False
248
+ messages_history=self.memory.memory, prompt=current_prompt, streaming=False,
249
+ stop_words=["thinking"]
249
250
  )
250
251
 
251
252
  content = result.response
@@ -296,7 +297,7 @@ class Agent(BaseModel):
296
297
 
297
298
  return answer
298
299
 
299
- def _reset_session(self, task_to_solve: str = "", max_iterations: int = 30,clear_memory: bool = True):
300
+ def _reset_session(self, task_to_solve: str = "", max_iterations: int = 30, clear_memory: bool = True):
300
301
  """Reset the agent's session."""
301
302
  logger.debug("Resetting session...")
302
303
  self.task_to_solve = task_to_solve
@@ -316,29 +317,30 @@ class Agent(BaseModel):
316
317
  def _compact_memory_if_needed(self, current_prompt: str = ""):
317
318
  """Compacts the memory if it exceeds the maximum occupancy or token limit."""
318
319
  ratio_occupied = self._calculate_context_occupancy()
319
-
320
+
320
321
  # Compact memory if any of these conditions are met:
321
322
  # 1. Memory occupancy exceeds MAX_OCCUPANCY, or
322
323
  # 2. Current iteration is a multiple of compact_every_n_iterations, or
323
324
  # 3. Working memory exceeds max_tokens_working_memory (if set)
324
325
  should_compact_by_occupancy = ratio_occupied >= MAX_OCCUPANCY
325
326
  should_compact_by_iteration = (
326
- self.compact_every_n_iterations is not None and
327
- self.current_iteration > 0 and
328
- self.current_iteration % self.compact_every_n_iterations == 0
327
+ self.compact_every_n_iterations is not None
328
+ and self.current_iteration > 0
329
+ and self.current_iteration % self.compact_every_n_iterations == 0
329
330
  )
330
331
  should_compact_by_token_limit = (
331
- self.max_tokens_working_memory is not None and
332
- self.total_tokens > self.max_tokens_working_memory
332
+ self.max_tokens_working_memory is not None and self.total_tokens > self.max_tokens_working_memory
333
333
  )
334
-
334
+
335
335
  if should_compact_by_occupancy or should_compact_by_iteration or should_compact_by_token_limit:
336
336
  if should_compact_by_occupancy:
337
337
  logger.debug(f"Memory compaction triggered: Occupancy {ratio_occupied}% exceeds {MAX_OCCUPANCY}%")
338
-
338
+
339
339
  if should_compact_by_iteration:
340
- logger.debug(f"Memory compaction triggered: Iteration {self.current_iteration} is a multiple of {self.compact_every_n_iterations}")
341
-
340
+ logger.debug(
341
+ f"Memory compaction triggered: Iteration {self.current_iteration} is a multiple of {self.compact_every_n_iterations}"
342
+ )
343
+
342
344
  self._emit_event("memory_full")
343
345
  self.memory.compact()
344
346
  self.total_tokens = self.model.token_counter_with_history(self.memory.memory, current_prompt)
@@ -399,7 +401,7 @@ class Agent(BaseModel):
399
401
  return self._handle_tool_execution_failure(response)
400
402
 
401
403
  variable_name = self.variable_store.add(response)
402
- new_prompt = self._format_observation_response(response, variable_name, iteration)
404
+ new_prompt = self._format_observation_response(response, executed_tool, variable_name, iteration)
403
405
 
404
406
  return ObserveResponseResult(
405
407
  next_prompt=new_prompt,
@@ -414,7 +416,7 @@ class Agent(BaseModel):
414
416
  """Extract tool usage from the response content."""
415
417
  if not content or not isinstance(content, str):
416
418
  return {}
417
-
419
+
418
420
  xml_parser = ToleranceXMLParser()
419
421
  tool_names = self.tools.tool_names()
420
422
  return xml_parser.extract_elements(text=content, element_names=tool_names)
@@ -461,7 +463,7 @@ class Agent(BaseModel):
461
463
  answer=None,
462
464
  )
463
465
 
464
- def _handle_repeated_tool_call(self, tool_name: str, arguments_with_values: dict) -> (str,str):
466
+ def _handle_repeated_tool_call(self, tool_name: str, arguments_with_values: dict) -> (str, str):
465
467
  """Handle the case where a tool call is repeated."""
466
468
  repeat_count = self.last_tool_call.get("count", 0)
467
469
  error_message = (
@@ -494,7 +496,9 @@ class Agent(BaseModel):
494
496
  answer=None,
495
497
  )
496
498
 
497
- def _format_observation_response(self, response: str, variable_name: str, iteration: int) -> str:
499
+ def _format_observation_response(
500
+ self, response: str, last_exectured_tool: str, variable_name: str, iteration: int
501
+ ) -> str:
498
502
  """Format the observation response with the given response, variable name, and iteration."""
499
503
  response_display = response
500
504
  if len(response) > MAX_RESPONSE_LENGTH:
@@ -504,29 +508,45 @@ class Agent(BaseModel):
504
508
  )
505
509
 
506
510
  # Format the response message
507
- formatted_response = (
508
- f"Your next step: you Must now plan the next tool call to complete the based on this new observation\n"
509
- f"\n--- Observations for iteration {iteration} / max {self.max_iterations} ---\n"
510
- f"\n--- Tool execution result in ${variable_name}$ ---\n"
511
- f"<{variable_name}>\n{response_display}\n</{variable_name}>\n\n"
512
- f"--- Tools ---\n{self._get_tools_names_prompt()}\n"
513
- f"--- Variables ---\n{self._get_variable_prompt()}\n"
514
- "Analyze this response to determine the next steps. If the step failed, reconsider your approach.\n"
515
- f"--- Task to solve summary ---\n{self.task_to_solve_summary}\n"
516
- "--- Format ---\n"
517
- "Respond only with two XML blocks in markdown as specified in system prompt.\n"
518
- "No extra comments must be added.\n"
511
+ formatted_response = formatted_response = (
512
+ "# Analysis and Next Action Decision Point\n\n"
513
+ f"📊 Progress: Iteration {iteration}/{self.max_iterations}\n\n"
514
+ "## Current Context\n"
515
+ f"```\n{self.task_to_solve_summary}```\n\n"
516
+ f"## Latest Tool {last_exectured_tool} Execution Result:\n"
517
+ f"Variable: ${variable_name}$\n"
518
+ f"```\n{response_display}```\n\n"
519
+ "## Available Resources\n"
520
+ f"🛠️ Tools:\n{self._get_tools_names_prompt()}\n\n"
521
+ f"📦 Variables:\n{self._get_variable_prompt()}\n\n"
522
+ "## Your Task\n"
523
+ "1. Analyze the execution result and progress, formalize if the current step is solved according to the task.\n"
524
+ "2. Determine the most effective next step\n"
525
+ "3. Select exactly ONE tool from the available list\n"
526
+ "4. Utilize variable interpolation where needed\n"
527
+ "## Response Requirements\n"
528
+ "Provide TWO markdown-formatted XML blocks:\n"
529
+ "1. Your analysis of the progression resulting from the execution of the tool in <thinking> tags, don't include <context_analysis/>\n"
530
+ "2. Your tool execution plan in <tool_name> tags\n\n"
531
+ "## Response Format\n"
519
532
  "```xml\n"
520
533
  "<thinking>\n"
521
- "...\n"
534
+ "[Detailed analysis of progress, and reasoning for next step]\n"
522
535
  "</thinking>\n"
523
536
  "```\n"
524
537
  "```xml\n"
525
- "< ...tool_name... >\n"
526
- "...\n"
527
- "</ ...tool_name... >\n"
528
- "```"
529
- )
538
+ "<action>\n"
539
+ "<selected_tool_name>\n"
540
+ "[Precise instruction for tool execution]\n"
541
+ "</selected_tool_name>\n"
542
+ "</action>\n"
543
+ "```\n\n"
544
+ "⚠️ Important:\n"
545
+ "- Respond ONLY with the two XML blocks\n"
546
+ "- No additional commentary\n"
547
+ "- If previous step failed, revise approach\n"
548
+ "- Ensure variable interpolation syntax is correct\n"
549
+ "- Utilize the <task_complete> tool to indicate task completion, display the result or if the task is deemed unfeasible.")
530
550
 
531
551
  return formatted_response
532
552
 
@@ -589,10 +609,10 @@ class Agent(BaseModel):
589
609
  arguments_with_values_interpolated = {
590
610
  key: self._interpolate_variables(value) for key, value in arguments_with_values.items()
591
611
  }
592
-
612
+
593
613
  arguments_with_values_interpolated = arguments_with_values_interpolated
594
614
 
595
- # test if tool need variables in context
615
+ # test if tool need variables in context
596
616
  if tool.need_variables:
597
617
  # Inject variables into the tool if needed
598
618
  arguments_with_values_interpolated["variables"] = self.variable_store
@@ -603,8 +623,7 @@ class Agent(BaseModel):
603
623
  try:
604
624
  # Convert arguments to proper types
605
625
  converted_args = self.tools.validate_and_convert_arguments(
606
- tool_name,
607
- arguments_with_values_interpolated
626
+ tool_name, arguments_with_values_interpolated
608
627
  )
609
628
  except ValueError as e:
610
629
  return "", f"Argument Error: {str(e)}"
@@ -637,9 +656,10 @@ class Agent(BaseModel):
637
656
  """Interpolate variables using $var$ syntax in the given text."""
638
657
  try:
639
658
  import re
659
+
640
660
  for var in self.variable_store.keys():
641
661
  # Escape the variable name for regex, but use raw value for replacement
642
- pattern = rf'\${re.escape(var)}\$'
662
+ pattern = rf"\${re.escape(var)}\$"
643
663
  replacement = self.variable_store[var]
644
664
  text = re.sub(pattern, replacement, text)
645
665
  return text
@@ -729,9 +749,7 @@ class Agent(BaseModel):
729
749
  # Remove the last assistant / user message
730
750
  user_message = memory_copy.pop()
731
751
  assistant_message = memory_copy.pop()
732
- summary = self.model.generate_with_history(
733
- messages_history=memory_copy, prompt=prompt_summary
734
- )
752
+ summary = self.model.generate_with_history(messages_history=memory_copy, prompt=prompt_summary)
735
753
  # Remove user message
736
754
  memory_copy.pop()
737
755
  # Replace by summary
@@ -123,7 +123,8 @@ class GenerativeModel:
123
123
 
124
124
  # Generate a response with conversation history and optional streaming
125
125
  def generate_with_history(
126
- self, messages_history: list[Message], prompt: str, image_url: str | None = None, streaming: bool = False
126
+ self, messages_history: list[Message], prompt: str, image_url: str | None = None, streaming: bool = False,
127
+ stop_words: list[str] | None = None
127
128
  ) -> ResponseStats:
128
129
  """Generate a response with conversation history and optional image.
129
130
 
@@ -132,6 +133,7 @@ class GenerativeModel:
132
133
  prompt: Current user prompt.
133
134
  image_url: Optional image URL for visual queries.
134
135
  streaming: Whether to stream the response.
136
+ stop_words: Optional list of stop words for streaming
135
137
 
136
138
  Returns:
137
139
  Detailed response statistics or a generator in streaming mode.
@@ -163,6 +165,7 @@ class GenerativeModel:
163
165
  model=self.model,
164
166
  messages=messages,
165
167
  num_retries=MIN_RETRIES,
168
+ stop=stop_words,
166
169
  )
167
170
 
168
171
  token_usage = TokenUsage(
@@ -181,7 +184,7 @@ class GenerativeModel:
181
184
  except Exception as e:
182
185
  self._handle_generation_exception(e)
183
186
 
184
- def _stream_response(self, messages):
187
+ def _stream_response(self, messages, stop_words: list[str] | None = None):
185
188
  """Private method to handle streaming responses."""
186
189
  try:
187
190
  for chunk in generate_completion(
@@ -189,7 +192,8 @@ class GenerativeModel:
189
192
  model=self.model,
190
193
  messages=messages,
191
194
  num_retries=MIN_RETRIES,
192
- stream=True, # Enable streaming
195
+ stream=True, # Enable streaming,
196
+ stop=stop_words,
193
197
  ):
194
198
  if chunk.choices[0].delta.content is not None:
195
199
  self.event_emitter.emit("stream_chunk", chunk.choices[0].delta.content)
quantalogic/llm.py CHANGED
@@ -60,6 +60,12 @@ PROVIDERS = {
60
60
  provider="openai",
61
61
  base_url="https://integrate.api.nvidia.com/v1",
62
62
  env_var="NVIDIA_API_KEY"
63
+ ),
64
+ "ovh": ModelProviderConfig(
65
+ prefix="ovh/",
66
+ provider="openai",
67
+ base_url="https://deepseek-r1-distill-llama-70b.endpoints.kepler.ai.cloud.ovh.net/api/openai_compat/v1",
68
+ env_var="OVH_API_KEY"
63
69
  )
64
70
  }
65
71
 
@@ -52,6 +52,9 @@ model_info = {
52
52
  max_output_tokens=8 * 1024,
53
53
  max_input_tokens=1024 * 64,
54
54
  ),
55
-
56
-
55
+ "ovh/DeepSeek-R1-Distill-Llama-70B": ModelInfo(
56
+ model_name="ovh/DeepSeek-R1-Distill-Llama-70B",
57
+ max_output_tokens=8 * 1024,
58
+ max_input_tokens=1024 * 64,
59
+ ),
57
60
  }
quantalogic/prompts.py CHANGED
@@ -1,119 +1,116 @@
1
+ from quantalogic.version import get_version
2
+
1
3
 
2
4
  def system_prompt(tools: str, environment: str, expertise: str = ""):
3
- """System prompt for the ReAct chatbot."""
5
+ """System prompt for the ReAct chatbot with enhanced cognitive architecture."""
4
6
  return f"""
5
- ### Core Identity
6
- You are QuantaLogic, an advanced ReAct AI Agent specializing in systematic problem-solving.
7
+ ### Agent Identity: QuantaLogic {get_version()}
8
+ Expert ReAct AI Agent implementing OODA (Observe-Orient-Decide-Act) loop with advanced problem-solving capabilities.
7
9
 
8
- ### Specific Expertise
10
+ ### Domain Expertise
9
11
  {expertise}
10
12
 
11
- ### Task Format
12
- Tasks will be presented within XML tags:
13
- <task>task_description</task>
13
+ ### Input Protocol
14
+ Task Format: <task>task_description</task>
15
+
16
+ ### Cognitive Framework
17
+ 1. 🔍 OBSERVE: Gather and process information
18
+ 2. 🧭 ORIENT: Analyze context and evaluate options
19
+ 3. 🎯 DECIDE: Select optimal action path
20
+ 4. ⚡ ACT: Execute precise tool operations
14
21
 
15
- ### Response Protocol
16
- Every response must contain exactly two XML blocks:
22
+ ### Response Schema [MANDATORY TWO-BLOCK FORMAT]
17
23
 
18
- 1. **Analysis Block**:
24
+ 1. 🧠 Analysis Block:
19
25
  ```xml
20
26
  <thinking>
21
- <!-- Follow this precise format. Be concise, dense, and use abbreviations, emojis, and Unicode characters to maximize density. -->
22
- <task_analysis_if_no_history>
23
- <!-- Only include if no conversation history exists: -->
24
- * Rewrite the <task> and its context in your own words, ensuring clarity and specificity.
25
- * Define detailed criteria for task completion if not already provided.
26
- * Identify key components, constraints, and potential challenges.
27
- * Break the <task> into smaller, manageable sub-tasks if necessary.
28
- - Each sub-task should have a clear objective, specific deliverables, and a logical sequence for progress tracking.
29
- </task_analysis_if_no_history>
30
- <success_criteria_if_no_history>
31
- <!-- Only include if no conversation history exists: -->
32
- * Specify measurable outcomes for task completion.
33
- * Define explicit quality benchmarks and performance indicators.
34
- * Note any constraints or limitations affecting the task.
35
- </success_criteria_if_no_history>
36
- <strategic_approach_if_no_history>
37
- <!-- Only include if no conversation history exists: -->
38
- * Outline a high-level strategy for solving the task.
39
- * Identify required resources, tools, or information.
40
- * Anticipate potential roadblocks and propose contingency plans.
41
- </strategic_approach_if_no_history>
42
- <last_observation>
43
- <!-- Include if conversation history exists: -->
44
- <variable>
45
- <name>...variable name...</name>
46
- <description>...concise description...</description>
47
- </variable>
48
- <result>
49
- ...concise description of the result...
50
- How does this result contribute to task progress?
51
- </result>
52
- </last_observation>
53
- <progress_analysis>
54
- <!-- Include if conversation history exists: -->
55
- * Summarize completed and failed steps concisely.
56
- * Identify and evaluate blockers or challenges.
57
- * Highlight repetitions and suggest reevaluating the approach if necessary.
58
- * Propose potential solutions or alternative strategies.
59
- </progress_analysis>
60
- <variables>
61
- <!-- Include if conversation history exists: -->
62
- * List all variable names and their current values concisely.
63
- </variables>
64
- <next_steps>
65
- * Outline immediate actions required.
66
- * Justify tool selection and parameter choices.
67
- * Use variable interpolation (e.g., `$var1$`) to minimize token generation.
68
- * Consider alternatives or reevaluate the plan if previous attempts failed.
69
- * Use the `task_complete` tool to confirm task completion.
70
- </next_steps>
71
- <taskpad>
72
- <!-- Optional: Use for notes about intermediate steps. -->
73
- <note>...</note>
74
- </taskpad>
27
+ <!-- COGNITIVE PROCESSING MATRIX -->
28
+
29
+ <!-- INITIAL TASK ANALYSIS - INCLUDE ONLY IF NO MESSAGE HISTORY EXISTS -->
30
+ <context_analysis when="no_history">
31
+ 📋 Task Decomposition based on task and history: Steps, Dependencies, Constraints
32
+ 🎯 Success Metrics: Quantifiable Outcomes
33
+ 🛠️ Resource Requirements: Tools, Data, Variables
34
+ ⚠️ Risk Assessment: Potential Failures, Mitigations
35
+ </context_analysis>
36
+
37
+ <!-- ALWAYS INCLUDE FOR ONGOING OPERATIONS -->
38
+ <execution_analysis>
39
+ <!-- ONGOING OPERATIONS -->
40
+ 🔄 Analyze Last Operation Results: Result, Impact, Effectiveness
41
+ • 📊 Progress Map: Completed%, Remaining%, Blockers
42
+ • 💾 Variable State: $var: value pairs
43
+ 📈 Performance Metrics: Speed, Quality, Resource Usage
44
+ </execution_analysis>
45
+
46
+ <decision_matrix>
47
+ <!-- ACTION PLANNING -->
48
+ • 🎯 Next Action: Tool Selection + Rationale
49
+ 📥 Input Parameters: Values + Variable Interpolation
50
+ • 🔄 Fallback Strategy: Alternative Approaches
51
+ ✅ Exit Criteria: Completion Conditions
52
+ </decision_matrix>
53
+
54
+ <memory_pad>
55
+ <!-- OPERATIONAL NOTES -->
56
+ 📝 Key Observations
57
+ • ⚡ Quick Access Data
58
+ </memory_pad>
75
59
  </thinking>
76
60
  ```
77
61
 
78
- 2. **Action Block**:
62
+ 2. Action Block:
79
63
  ```xml
64
+ <action>
80
65
  <tool_name>
81
- <!-- Replace `tool_name` with the name of the tool from the available tools. -->
82
- <parameter1>
83
- <!-- Use variable interpolation (e.g., `$var1$`) to pass context and minimize token generation. -->
84
- value1
85
- </parameter1>
86
- <parameter2>value2</parameter2>
66
+ <!-- PRECISE TOOL EXECUTION -->
67
+ <param1>value1</param1> <!-- Use $var$ for variable interpolation -->
68
+ <param2>value2</param2> <!-- Keep parameters minimal but sufficient -->
87
69
  </tool_name>
70
+ </action>
88
71
  ```
89
72
 
90
- ### Examples of Action Blocks
91
- - **New Task Example**:
73
+ ### Action Patterns
74
+ 1. 🆕 New Task:
92
75
  ```xml
93
- <data_analyzer>
94
- <file_path>$input_file$</file_path>
95
- <operation>validate_structure</operation>
96
- </data_analyzer>
76
+ <action>
77
+ <analyzer>
78
+ <input>$data$</input>
79
+ <mode>initialize</mode>
80
+ </analyzer>
81
+ </action>
97
82
  ```
98
83
 
99
- - **Continuing Task Example**:
84
+ 2. 🔄 Continuation:
100
85
  ```xml
101
- <memory_optimizer>
102
- <process_id>$current_process$</process_id>
103
- <target_utilization>75%</target_utilization>
104
- </memory_optimizer>
86
+ <action>
87
+ <processor>
88
+ <state>$current$</state>
89
+ <action>optimize</action>
90
+ </processor>
91
+ </action>
105
92
  ```
106
93
 
107
- - **Task Completion Example / When a task is completed**:
94
+ 3. Completion:
108
95
  ```xml
96
+ <action>
109
97
  <task_complete>
110
- <answer>Task completed successfully</answer>
98
+ <result>$final_output$</result>
111
99
  </task_complete>
100
+ </action>
112
101
  ```
113
102
 
114
- ### Available Tools
115
- {tools}
103
+ ### Operational Parameters
104
+ 🛠️ Tools: {tools}
105
+ 🌐 Environment: {environment}
116
106
 
117
- ### Environment Details
118
- {environment}
107
+ ### Execution Guidelines
108
+ 1. 🎯 Maintain laser focus on task objectives
109
+ 2. 📊 Use data-driven decision making
110
+ 3. 🔄 Implement feedback loops for continuous optimization
111
+ 4. ⚡ Maximize efficiency through variable interpolation
112
+ 5. 🔍 Monitor and validate each action's impact
113
+ 6. 🛑 Fail fast and adapt when encountering blockers
114
+ 7. ✅ Verify completion criteria rigorously
119
115
  """
116
+
@@ -62,6 +62,7 @@ class ReplaceInFileTool(Tool):
62
62
  "Updates sections of content in an existing file using SEARCH/REPLACE blocks. "
63
63
  "If exact matches are not found, the tool attempts to find similar sections based on similarity. "
64
64
  "Returns the updated content or an error."
65
+ "⚠️ THIS TOOL MUST BE USED IN PRIORITY TO UPDATE AN EXISTING FILE."
65
66
  )
66
67
  need_validation: bool = True
67
68
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: quantalogic
3
- Version: 0.32.0
3
+ Version: 0.33.0
4
4
  Summary: QuantaLogic ReAct Agents
5
5
  Author: Raphaël MANSUY
6
6
  Author-email: raphael.mansuy@gmail.com
@@ -1,5 +1,5 @@
1
1
  quantalogic/__init__.py,sha256=Su8CnOEdqKu4zTytjiP9P5olg-oIDuUA3fMWM1WUdRY,925
2
- quantalogic/agent.py,sha256=VqxM_VizDpwH3SLAnoSFMjH4a1ijBVOHaI6rXahHP7M,33289
2
+ quantalogic/agent.py,sha256=3LllyyFILkmm6wz1CmT6942jIgT1oymqiYNzRYO6fAg,34272
3
3
  quantalogic/agent_config.py,sha256=SIRVSF0kkrYfvtyHiMCJhnm_nYqJCD2p1pN-reMIy24,7868
4
4
  quantalogic/agent_factory.py,sha256=HWKwN_DN57EPmME-hoCD2uJE0DqsPCzGU_V7nq54XzI,5284
5
5
  quantalogic/coding_agent.py,sha256=Z7ik6LUvLKDnaW9Ax1iZGC7p1WMnlYEUIlE5lkBP414,4975
@@ -8,17 +8,17 @@ quantalogic/console_print_events.py,sha256=KB-DGi52As8M96eUs1N_vgNqKIFtqv_H8NTOd
8
8
  quantalogic/console_print_token.py,sha256=qSU-3kmoZk4T5-1ybrEBi8tIXDPcz7eyWKhGh3E8uIg,395
9
9
  quantalogic/docs_cli.py,sha256=3giVbUpespB9ZdTSJ955A3BhcOaBl5Lwsn1AVy9XAeY,1663
10
10
  quantalogic/event_emitter.py,sha256=jqot2g4JRXc88K6PW837Oqxbf7shZfO-xdPaUWmzupk,7901
11
- quantalogic/generative_model.py,sha256=ut_BFy4BqDxNqUXVbM8e_C_CzwNuJkvGWRsbpbKaees,13423
11
+ quantalogic/generative_model.py,sha256=K0lbtZuuQrI5McPC4pUZ_FdjL32dAy1vM18egmPGaa8,13638
12
12
  quantalogic/get_model_info.py,sha256=_9Nb9JQ09HZzT-_gZUSvl4Er7uCXs5ys36sIBa-8DXA,3005
13
13
  quantalogic/interactive_text_editor.py,sha256=1vW4poJl7SItRGEeGQgtCFcmRDXmfCM8PE-uBtDBJuE,16658
14
- quantalogic/llm.py,sha256=Nk2Dn1lJh1-323Fs7ADfR9ov_eAoJOEEnzyGswZSbJI,5460
14
+ quantalogic/llm.py,sha256=98osu6LmjuYw4g-CDIp1SJkYlfoHNwdvq6yJqI-K5NA,5692
15
15
  quantalogic/main.py,sha256=__-4pX2pgoSFvt-aLdp6Qlrq55_SrwP_l8u2uTaQbjg,9262
16
16
  quantalogic/memory.py,sha256=zbtRuM05jaS2lJll-92dt5JfYVLERnF_m_9xqp2x-k0,6304
17
17
  quantalogic/model_info.py,sha256=j7QqvjEFQDGpDOgQs8uTkVyI3a50Oa_nrsQjyxizTLc,272
18
- quantalogic/model_info_list.py,sha256=bJu2ohQFgZOwmcqydfh5oi5R1G8ZY7jtQlERsR1Z47s,1816
18
+ quantalogic/model_info_list.py,sha256=qGDKI5oBbu5oyJSH4o4jGYGqyqYEUMXFRi_qMDAQ2nU,1997
19
19
  quantalogic/model_info_litellm.py,sha256=m1Yt4SIiOBRWLx7S8f8k4fcTiKJZKtOvcPN_QvQ_Oxk,1880
20
20
  quantalogic/model_names.py,sha256=UZlz25zG9B2dpfwdw_e1Gw5qFsKQ7iME9FJh9Ts4u6s,938
21
- quantalogic/prompts.py,sha256=M-7rCaQoylnwxedhvy7VmQdgBG6TT1vmcf8_UzPTyY0,4035
21
+ quantalogic/prompts.py,sha256=2DgL979NBXzSfHfBw3KBf7-55wSzIk5vK-uDZbzRQTY,3158
22
22
  quantalogic/search_agent.py,sha256=EA_FAPP0dVuUbJ_lAGKfYq1FIJ6oLYzGMgKLMvBL4ZQ,2472
23
23
  quantalogic/server/__init__.py,sha256=8sz_PYAUCrkM6JM5EAUeIzNM4NPW6j6UT72JVkc21WQ,91
24
24
  quantalogic/server/agent_server.py,sha256=VXaaWqReUSZOCX7CaKS14jria8yZn1kLEc52E2hV7ZA,22510
@@ -62,7 +62,7 @@ quantalogic/tools/python_tool.py,sha256=70HLbfU2clOBgj4axDOtIKzXwEBMNGEAX1nGSf-K
62
62
  quantalogic/tools/read_file_block_tool.py,sha256=FTcDAUOOPQOvWRjnRI6nMI1Upus90klR4PC0pbPP_S8,5266
63
63
  quantalogic/tools/read_file_tool.py,sha256=l6k-SOIV9krpXAmUTkxzua51S-KHgzGqkcDlD5AD8K0,2710
64
64
  quantalogic/tools/read_html_tool.py,sha256=Vq2rHY8a36z1-4rN6c_kYjPUTQ4I2UT154PMpaoWSkA,11139
65
- quantalogic/tools/replace_in_file_tool.py,sha256=wC7OlV8UpR5JGCD3VGUWlBEE6fMdGEDRcwE22cDSG2E,13764
65
+ quantalogic/tools/replace_in_file_tool.py,sha256=95GqcOC0sZzbWHWzYDVwq7rEwChlOgKxb5cxKk-Y7W8,13844
66
66
  quantalogic/tools/ripgrep_tool.py,sha256=sRzHaWac9fa0cCGhECJN04jw_Ko0O3u45KDWzMIYcvY,14291
67
67
  quantalogic/tools/search_definition_names.py,sha256=ui0304UgUke6Ca-H3-S4JP9TsdHhRCR5uk9kPuobIDA,18769
68
68
  quantalogic/tools/serpapi_search_tool.py,sha256=sX-Noch77kGP2XiwislPNFyy3_4TH6TwMK6C81L3q9Y,5316
@@ -92,8 +92,8 @@ quantalogic/version_check.py,sha256=cttR1lR3OienGLl7NrK1Te1fhDkqSjCci7HC1vFUTSY,
92
92
  quantalogic/welcome_message.py,sha256=IXMhem8h7srzNUwvw8G_lmEkHU8PFfote021E_BXmVk,3039
93
93
  quantalogic/xml_parser.py,sha256=8yDxvKzAEnefNwUAR-wjerMDOj5T5cxak4WPIA83SBw,11516
94
94
  quantalogic/xml_tool_parser.py,sha256=Vz4LEgDbelJynD1siLOVkJ3gLlfHsUk65_gCwbYJyGc,3784
95
- quantalogic-0.32.0.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
96
- quantalogic-0.32.0.dist-info/METADATA,sha256=w5kJUS98ou0kVeY9fy-WImrW-W9wWZFOXmIQx4xK-_M,23461
97
- quantalogic-0.32.0.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
98
- quantalogic-0.32.0.dist-info/entry_points.txt,sha256=h74O_Q3qBRCrDR99qvwB4BpBGzASPUIjCfxHq6Qnups,183
99
- quantalogic-0.32.0.dist-info/RECORD,,
95
+ quantalogic-0.33.0.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
96
+ quantalogic-0.33.0.dist-info/METADATA,sha256=ZPa-Y4-EhqTp_3ixcWa0hLI_grOtN8v5SnoWoZP9to0,23461
97
+ quantalogic-0.33.0.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
98
+ quantalogic-0.33.0.dist-info/entry_points.txt,sha256=h74O_Q3qBRCrDR99qvwB4BpBGzASPUIjCfxHq6Qnups,183
99
+ quantalogic-0.33.0.dist-info/RECORD,,