quantalogic 0.33.0__tar.gz → 0.33.1__tar.gz

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.
Files changed (99) hide show
  1. {quantalogic-0.33.0 → quantalogic-0.33.1}/PKG-INFO +1 -1
  2. {quantalogic-0.33.0 → quantalogic-0.33.1}/pyproject.toml +1 -1
  3. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/agent.py +19 -8
  4. quantalogic-0.33.1/quantalogic/console_print_events.py +65 -0
  5. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/prompts.py +1 -1
  6. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/xml_parser.py +38 -36
  7. quantalogic-0.33.0/quantalogic/console_print_events.py +0 -66
  8. {quantalogic-0.33.0 → quantalogic-0.33.1}/LICENSE +0 -0
  9. {quantalogic-0.33.0 → quantalogic-0.33.1}/README.md +0 -0
  10. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/__init__.py +0 -0
  11. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/agent_config.py +0 -0
  12. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/agent_factory.py +0 -0
  13. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/coding_agent.py +0 -0
  14. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/config.py +0 -0
  15. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/console_print_token.py +0 -0
  16. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/docs_cli.py +0 -0
  17. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/event_emitter.py +0 -0
  18. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/generative_model.py +0 -0
  19. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/get_model_info.py +0 -0
  20. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/interactive_text_editor.py +0 -0
  21. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/llm.py +0 -0
  22. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/main.py +0 -0
  23. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/memory.py +0 -0
  24. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/model_info.py +0 -0
  25. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/model_info_list.py +0 -0
  26. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/model_info_litellm.py +0 -0
  27. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/model_names.py +0 -0
  28. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/search_agent.py +0 -0
  29. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/server/__init__.py +0 -0
  30. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/server/agent_server.py +0 -0
  31. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/server/models.py +0 -0
  32. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/server/routes.py +0 -0
  33. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/server/state.py +0 -0
  34. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/server/static/js/event_visualizer.js +0 -0
  35. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/server/static/js/quantalogic.js +0 -0
  36. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/server/templates/index.html +0 -0
  37. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/task_file_reader.py +0 -0
  38. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/task_runner.py +0 -0
  39. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/tool_manager.py +0 -0
  40. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/tools/__init__.py +0 -0
  41. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/tools/agent_tool.py +0 -0
  42. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/tools/dalle_e.py +0 -0
  43. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/tools/download_http_file_tool.py +0 -0
  44. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/tools/duckduckgo_search_tool.py +0 -0
  45. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/tools/edit_whole_content_tool.py +0 -0
  46. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/tools/elixir_tool.py +0 -0
  47. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/tools/execute_bash_command_tool.py +0 -0
  48. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/tools/generate_database_report_tool.py +0 -0
  49. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/tools/grep_app_tool.py +0 -0
  50. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/tools/input_question_tool.py +0 -0
  51. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/tools/jinja_tool.py +0 -0
  52. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/tools/language_handlers/__init__.py +0 -0
  53. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/tools/language_handlers/c_handler.py +0 -0
  54. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/tools/language_handlers/cpp_handler.py +0 -0
  55. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/tools/language_handlers/go_handler.py +0 -0
  56. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/tools/language_handlers/java_handler.py +0 -0
  57. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/tools/language_handlers/javascript_handler.py +0 -0
  58. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/tools/language_handlers/python_handler.py +0 -0
  59. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/tools/language_handlers/rust_handler.py +0 -0
  60. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/tools/language_handlers/scala_handler.py +0 -0
  61. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/tools/language_handlers/typescript_handler.py +0 -0
  62. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/tools/list_directory_tool.py +0 -0
  63. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/tools/llm_tool.py +0 -0
  64. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/tools/llm_vision_tool.py +0 -0
  65. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/tools/markitdown_tool.py +0 -0
  66. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/tools/nodejs_tool.py +0 -0
  67. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/tools/python_tool.py +0 -0
  68. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/tools/read_file_block_tool.py +0 -0
  69. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/tools/read_file_tool.py +0 -0
  70. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/tools/read_html_tool.py +0 -0
  71. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/tools/replace_in_file_tool.py +0 -0
  72. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/tools/ripgrep_tool.py +0 -0
  73. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/tools/search_definition_names.py +0 -0
  74. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/tools/serpapi_search_tool.py +0 -0
  75. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/tools/sql_query_tool.py +0 -0
  76. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/tools/task_complete_tool.py +0 -0
  77. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/tools/tool.py +0 -0
  78. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/tools/unified_diff_tool.py +0 -0
  79. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/tools/utils/__init__.py +0 -0
  80. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/tools/utils/create_sample_database.py +0 -0
  81. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/tools/utils/generate_database_report.py +0 -0
  82. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/tools/wikipedia_search_tool.py +0 -0
  83. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/tools/write_file_tool.py +0 -0
  84. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/utils/__init__.py +0 -0
  85. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/utils/ask_user_validation.py +0 -0
  86. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/utils/check_version.py +0 -0
  87. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/utils/download_http_file.py +0 -0
  88. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/utils/get_all_models.py +0 -0
  89. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/utils/get_coding_environment.py +0 -0
  90. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/utils/get_environment.py +0 -0
  91. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/utils/get_quantalogic_rules_content.py +0 -0
  92. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/utils/git_ls.py +0 -0
  93. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/utils/lm_studio_model_info.py +0 -0
  94. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/utils/read_file.py +0 -0
  95. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/utils/read_http_text_content.py +0 -0
  96. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/version.py +0 -0
  97. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/version_check.py +0 -0
  98. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/welcome_message.py +0 -0
  99. {quantalogic-0.33.0 → quantalogic-0.33.1}/quantalogic/xml_tool_parser.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: quantalogic
3
- Version: 0.33.0
3
+ Version: 0.33.1
4
4
  Summary: QuantaLogic ReAct Agents
5
5
  Author: Raphaël MANSUY
6
6
  Author-email: raphael.mansuy@gmail.com
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "quantalogic"
3
- version = "0.33.0"
3
+ version = "0.33.1"
4
4
  description = "QuantaLogic ReAct Agents"
5
5
  authors = ["Raphaël MANSUY <raphael.mansuy@gmail.com>"]
6
6
  readme = "README.md"
@@ -417,9 +417,18 @@ class Agent(BaseModel):
417
417
  if not content or not isinstance(content, str):
418
418
  return {}
419
419
 
420
+ # Extract action
420
421
  xml_parser = ToleranceXMLParser()
422
+ action = xml_parser.extract_elements(text=content, element_names=["action"])
423
+
421
424
  tool_names = self.tools.tool_names()
422
- return xml_parser.extract_elements(text=content, element_names=tool_names)
425
+
426
+ if action:
427
+ return xml_parser.extract_elements(text=action["action"], element_names=tool_names)
428
+ else:
429
+ # Fallback to extracting tool usage directly
430
+ return xml_parser.extract_elements(text=content, element_names=tool_names)
431
+
423
432
 
424
433
  def _parse_tool_arguments(self, tool, tool_input: str) -> dict:
425
434
  """Parse the tool arguments from the tool input."""
@@ -511,11 +520,8 @@ class Agent(BaseModel):
511
520
  formatted_response = formatted_response = (
512
521
  "# Analysis and Next Action Decision Point\n\n"
513
522
  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"
523
+ "## Global Task summary:\n"
524
+ f"```\n\n{self.task_to_solve_summary}```\n\n"
519
525
  "## Available Resources\n"
520
526
  f"🛠️ Tools:\n{self._get_tools_names_prompt()}\n\n"
521
527
  f"📦 Variables:\n{self._get_variable_prompt()}\n\n"
@@ -528,6 +534,9 @@ class Agent(BaseModel):
528
534
  "Provide TWO markdown-formatted XML blocks:\n"
529
535
  "1. Your analysis of the progression resulting from the execution of the tool in <thinking> tags, don't include <context_analysis/>\n"
530
536
  "2. Your tool execution plan in <tool_name> tags\n\n"
537
+ "## Last executed action result\n"
538
+ f"Last executed tool {last_exectured_tool} Execution Result:\n"
539
+ f"\n<{variable_name}>\n{response_display}\n</{variable_name}>\n"
531
540
  "## Response Format\n"
532
541
  "```xml\n"
533
542
  "<thinking>\n"
@@ -545,8 +554,10 @@ class Agent(BaseModel):
545
554
  "- Respond ONLY with the two XML blocks\n"
546
555
  "- No additional commentary\n"
547
556
  "- 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.")
557
+ "- Use interpolated variables ($variable_name$) where required in tool calls, to minimize token usage, if possible\n"
558
+ "- strictly follow the required arguments for each tool as defined in system prompt\n"
559
+ "- Utilize <action><task_complete><answer>...</answer></task_complete><action> to indicate task completion, display the result or if the task is deemed unfeasible."
560
+ )
550
561
 
551
562
  return formatted_response
552
563
 
@@ -0,0 +1,65 @@
1
+ from typing import Any
2
+
3
+ from rich import box
4
+ from rich.console import Console
5
+ from rich.panel import Panel
6
+ from rich.text import Text
7
+ from rich.tree import Tree
8
+
9
+
10
+ def console_print_events(event: str, data: dict[str, Any] | None = None):
11
+ """Print events with elegant compact formatting."""
12
+ console = Console()
13
+
14
+ # Stylish no-data presentation
15
+ if not data:
16
+ console.print(
17
+ Panel.fit(
18
+ Text(f"ⓘ No event data", justify="center", style="italic cyan"),
19
+ title=f"✨ {event}",
20
+ border_style="cyan",
21
+ box=box.ROUNDED,
22
+ padding=(0, 2),
23
+ )
24
+ )
25
+ return
26
+
27
+ # Enhanced tree rendering with subtle decorations
28
+ def render_tree(data: dict[str, Any], tree: Tree) -> None:
29
+ for key, value in data.items():
30
+ key_text = Text(f"◈ {key}", style="bright_magenta")
31
+ if isinstance(value, dict):
32
+ branch = tree.add(key_text)
33
+ render_tree(value, branch)
34
+ elif isinstance(value, list):
35
+ branch = tree.add(key_text)
36
+ for item in value:
37
+ if isinstance(item, dict):
38
+ sub_branch = branch.add(Text("○", style="cyan"))
39
+ render_tree(item, sub_branch)
40
+ else:
41
+ branch.add(Text(f"• {item}", style="dim green"))
42
+ else:
43
+ tree.add(Text.assemble(
44
+ key_text,
45
+ (" → ", "dim"),
46
+ str(value), style="bright_white"
47
+ ))
48
+
49
+ # Create a compact tree with subtle styling
50
+ tree = Tree("", guide_style="dim cyan", hide_root=True)
51
+ render_tree(data, tree)
52
+
53
+ # Elegant panel design
54
+ console.print(
55
+ Panel(
56
+ tree,
57
+ title=f"🎯 [bold bright_cyan]{event}[/]",
58
+ border_style="bright_blue",
59
+ box=box.DOUBLE_EDGE,
60
+ padding=(0, 1),
61
+ subtitle=f"[dim]Items: {len(data)}[/dim]",
62
+ subtitle_align="right",
63
+ ),
64
+ no_wrap=True
65
+ )
@@ -39,7 +39,7 @@ Task Format: <task>task_description</task>
39
39
  <!-- ONGOING OPERATIONS -->
40
40
  • 🔄 Analyze Last Operation Results: Result, Impact, Effectiveness
41
41
  • 📊 Progress Map: Completed%, Remaining%, Blockers
42
- • 💾 Variable State: $var: value pairs
42
+ • 💾 Variable State: $var: short description of the content of each variable.
43
43
  • 📈 Performance Metrics: Speed, Quality, Resource Usage
44
44
  </execution_analysis>
45
45
 
@@ -7,7 +7,6 @@ with support for handling malformed XML and CDATA sections.
7
7
  import html
8
8
  import re
9
9
  from collections import defaultdict
10
- from functools import lru_cache
11
10
  from typing import Self
12
11
 
13
12
  from loguru import logger
@@ -53,29 +52,22 @@ class ToleranceXMLParser:
53
52
  """
54
53
 
55
54
  # Default mappings for element name normalization
56
- DEFAULT_NAME_MAP = {
57
- "o": "output",
58
- "i": "input",
59
- "opt": "optional"
60
- }
55
+ DEFAULT_NAME_MAP = {"o": "output", "i": "input", "opt": "optional"}
61
56
 
62
57
  def __init__(self: Self) -> None:
63
58
  """Initialize the parser with regex patterns for matching XML-like elements."""
64
59
  # Pattern for matching individual XML elements with better whitespace handling
65
- self.element_pattern = re.compile(
66
- r"<\s*([^/>]+?)\s*>(.*?)(?:</\s*\1\s*>|<\s*\1\s*>)",
67
- re.DOTALL
68
- )
60
+ self.element_pattern = re.compile(r"<\s*([^/>]+?)\s*>(.*?)(?:</\s*\1\s*>|<\s*\1\s*>)", re.DOTALL)
69
61
  # Pattern for matching CDATA sections
70
62
  self.cdata_pattern = re.compile(r"<!\[CDATA\[(.*?)]]>", re.DOTALL)
71
63
  logger.debug("Initialized ToleranceXMLParser with regex patterns")
72
64
 
73
65
  def _validate_input(self, text: str) -> None:
74
66
  """Validate input text before processing.
75
-
67
+
76
68
  Args:
77
69
  text: Input text to validate.
78
-
70
+
79
71
  Raises:
80
72
  ValueError: If input text is invalid.
81
73
  """
@@ -120,7 +112,6 @@ class ToleranceXMLParser:
120
112
  # Only unescape HTML entities, preserve everything else exactly as is
121
113
  return html.unescape(content)
122
114
 
123
- @lru_cache(maxsize=128)
124
115
  def _map_element_name(self: Self, name: str) -> str:
125
116
  """Map element names to their canonical form.
126
117
 
@@ -134,10 +125,10 @@ class ToleranceXMLParser:
134
125
 
135
126
  def _build_element_pattern(self, element_name: str) -> re.Pattern[str]:
136
127
  """Build regex pattern for finding specific XML elements.
137
-
128
+
138
129
  Args:
139
130
  element_name: Name of the element to match.
140
-
131
+
141
132
  Returns:
142
133
  Compiled regex pattern for matching the element.
143
134
  """
@@ -145,53 +136,45 @@ class ToleranceXMLParser:
145
136
  cdata_section = r"(?:<!\[CDATA\[.*?]]>)?"
146
137
  content_pattern = f"({non_cdata}{cdata_section}{non_cdata})"
147
138
  closing_pattern = "(?:</\1>|<\1>)"
148
-
149
- return re.compile(
150
- f"<{element_name}>{content_pattern}{closing_pattern}",
151
- re.DOTALL
152
- )
139
+
140
+ return re.compile(f"<{element_name}>{content_pattern}{closing_pattern}", re.DOTALL)
153
141
 
154
142
  def _find_all_elements(self, text: str) -> list[tuple[str, str]]:
155
143
  """Find all XML elements in text.
156
-
144
+
157
145
  Args:
158
146
  text: Input text to search.
159
-
147
+
160
148
  Returns:
161
149
  List of tuples containing element names and their content.
162
150
  """
163
- return [(match.group(1), match.group(2) or "")
164
- for match in self.element_pattern.finditer(text)]
151
+ return [(match.group(1), match.group(2) or "") for match in self.element_pattern.finditer(text)]
165
152
 
166
153
  def _process_element_content(self, content: str, preserve_cdata: bool) -> str:
167
154
  """Process content of a single element.
168
-
155
+
169
156
  Args:
170
157
  content: Raw element content.
171
158
  preserve_cdata: Whether to preserve CDATA sections.
172
-
159
+
173
160
  Returns:
174
161
  Processed content string.
175
162
  """
176
163
  content, cdata_sections = self._extract_and_remove_cdata(content, preserve_cdata)
177
164
  content = self._clean_content(content)
178
-
165
+
179
166
  # If content is empty but we have CDATA sections and we're not preserving them
180
167
  if not content.strip() and cdata_sections and not preserve_cdata:
181
168
  return cdata_sections[0]
182
169
  return content
183
170
 
184
- def _process_elements(
185
- self,
186
- elements: list[tuple[str, str]],
187
- preserve_cdata: bool
188
- ) -> dict[str, str]:
171
+ def _process_elements(self, elements: list[tuple[str, str]], preserve_cdata: bool) -> dict[str, str]:
189
172
  """Process found elements and handle CDATA sections.
190
-
173
+
191
174
  Args:
192
175
  elements: List of element name and content tuples.
193
176
  preserve_cdata: Whether to preserve CDATA sections.
194
-
177
+
195
178
  Returns:
196
179
  Dictionary mapping element names to their processed content.
197
180
  """
@@ -199,12 +182,12 @@ class ToleranceXMLParser:
199
182
  for name, content in elements:
200
183
  name = self._map_element_name(name)
201
184
  result[name] = self._process_element_content(content, preserve_cdata)
202
-
185
+
203
186
  # Handle nested elements
204
187
  nested_elements = self._find_all_elements(content)
205
188
  nested_results = self._process_elements(nested_elements, preserve_cdata)
206
189
  result.update(nested_results)
207
-
190
+
208
191
  return dict(result)
209
192
 
210
193
  def _extract_element_content(self: Self, text: str, preserve_cdata: bool = False) -> dict[str, str]:
@@ -301,3 +284,22 @@ class ToleranceXMLParser:
301
284
  error_msg = error_msg + f"\n{text}\n"
302
285
  logger.error(error_msg)
303
286
  raise ValueError(error_msg)
287
+
288
+
289
+ if __name__ == "__main__":
290
+ xml_content = """
291
+ <action>
292
+ <task_complete>
293
+ <answer>Hello</answer>
294
+ </task_complete>
295
+ </action>
296
+ """
297
+
298
+ parser = ToleranceXMLParser()
299
+ parsed_values = parser.extract_elements(xml_content)
300
+ print(parsed_values)
301
+ if "action" in parsed_values:
302
+ print(parsed_values["action"])
303
+ action = parser.extract_elements(text=xml_content, element_names=["action"])
304
+ print(action["action"])
305
+
@@ -1,66 +0,0 @@
1
- from typing import Any
2
-
3
- from rich import box
4
- from rich.console import Console
5
- from rich.panel import Panel
6
- from rich.tree import Tree
7
-
8
-
9
- def console_print_events(event: str, data: dict[str, Any] | None = None):
10
- """Print events with rich formatting.
11
-
12
- Args:
13
- event (str): Name of the event.
14
- data (Dict[str, Any], optional): Additional event data. Defaults to None.
15
- """
16
- console = Console()
17
-
18
- # Define panel title with enhanced styling
19
- panel_title = f"[bold cyan]Event: {event}[/bold cyan]"
20
-
21
- if not data:
22
- # Display a friendly message when no data is available
23
- console.print(
24
- Panel(
25
- "[italic yellow]No additional event data available.[/italic yellow]",
26
- title=panel_title,
27
- border_style="dim",
28
- expand=True,
29
- padding=(1, 2),
30
- )
31
- )
32
- return
33
-
34
- # Function to render nested dictionaries as a tree
35
- def render_tree(data: dict[str, any], tree: Tree):
36
- for key, value in data.items():
37
- if isinstance(value, dict):
38
- branch = tree.add(f"[bold magenta]{key}[/bold magenta]")
39
- render_tree(value, branch)
40
- elif isinstance(value, list):
41
- branch = tree.add(f"[bold magenta]{key}[/bold magenta]")
42
- for index, item in enumerate(value, start=1):
43
- if isinstance(item, dict):
44
- sub_branch = branch.add(f"[cyan]Item {index}[/cyan]")
45
- render_tree(item, sub_branch)
46
- else:
47
- branch.add(f"[green]{item}[/green]")
48
- else:
49
- tree.add(f"[bold yellow]{key}[/bold yellow]: [white]{value}[/white]")
50
-
51
- # Create a Tree to represent nested data
52
- tree = Tree(f"[bold blue]{event} Details[/bold blue]", guide_style="bold bright_blue")
53
-
54
- render_tree(data, tree)
55
-
56
- # Create a panel to display the tree
57
- panel = Panel(
58
- tree,
59
- title=panel_title,
60
- border_style="bright_blue",
61
- padding=(1, 2),
62
- box=box.ROUNDED,
63
- expand=True,
64
- )
65
-
66
- console.print(panel)
File without changes
File without changes