optexity-browser-use 0.9.5__tar.gz → 0.9.5.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 (147) hide show
  1. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/PKG-INFO +1 -1
  2. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/dom/serializer/serializer.py +59 -11
  3. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/dom/views.py +16 -1
  4. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/pyproject.toml +1 -1
  5. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/.gitignore +0 -0
  6. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/LICENSE +0 -0
  7. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/README.md +0 -0
  8. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/__init__.py +0 -0
  9. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/actor/__init__.py +0 -0
  10. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/actor/element.py +0 -0
  11. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/actor/mouse.py +0 -0
  12. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/actor/page.py +0 -0
  13. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/actor/playground/flights.py +0 -0
  14. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/actor/playground/mixed_automation.py +0 -0
  15. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/actor/playground/playground.py +0 -0
  16. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/actor/utils.py +0 -0
  17. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/agent/cloud_events.py +0 -0
  18. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/agent/gif.py +0 -0
  19. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/agent/judge.py +0 -0
  20. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/agent/message_manager/service.py +0 -0
  21. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/agent/message_manager/utils.py +0 -0
  22. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/agent/message_manager/views.py +0 -0
  23. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/agent/prompts.py +0 -0
  24. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/agent/service.py +0 -0
  25. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/agent/system_prompt.md +0 -0
  26. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/agent/system_prompt_flash.md +0 -0
  27. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/agent/system_prompt_no_thinking.md +0 -0
  28. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/agent/views.py +0 -0
  29. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/browser/__init__.py +0 -0
  30. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/browser/cloud/cloud.py +0 -0
  31. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/browser/cloud/views.py +0 -0
  32. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/browser/events.py +0 -0
  33. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/browser/profile.py +0 -0
  34. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/browser/python_highlights.py +0 -0
  35. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/browser/session.py +0 -0
  36. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/browser/session_manager.py +0 -0
  37. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/browser/video_recorder.py +0 -0
  38. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/browser/views.py +0 -0
  39. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/browser/watchdog_base.py +0 -0
  40. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/browser/watchdogs/__init__.py +0 -0
  41. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/browser/watchdogs/aboutblank_watchdog.py +0 -0
  42. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/browser/watchdogs/crash_watchdog.py +0 -0
  43. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/browser/watchdogs/default_action_watchdog.py +0 -0
  44. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/browser/watchdogs/dom_watchdog.py +0 -0
  45. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/browser/watchdogs/downloads_watchdog.py +0 -0
  46. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/browser/watchdogs/local_browser_watchdog.py +0 -0
  47. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/browser/watchdogs/permissions_watchdog.py +0 -0
  48. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/browser/watchdogs/popups_watchdog.py +0 -0
  49. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/browser/watchdogs/recording_watchdog.py +0 -0
  50. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/browser/watchdogs/screenshot_watchdog.py +0 -0
  51. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/browser/watchdogs/security_watchdog.py +0 -0
  52. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/browser/watchdogs/storage_state_watchdog.py +0 -0
  53. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/cli.py +0 -0
  54. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/code_use/__init__.py +0 -0
  55. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/code_use/formatting.py +0 -0
  56. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/code_use/namespace.py +0 -0
  57. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/code_use/notebook_export.py +0 -0
  58. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/code_use/service.py +0 -0
  59. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/code_use/system_prompt.md +0 -0
  60. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/code_use/utils.py +0 -0
  61. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/code_use/views.py +0 -0
  62. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/config.py +0 -0
  63. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/controller/__init__.py +0 -0
  64. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/dom/enhanced_snapshot.py +0 -0
  65. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/dom/markdown_extractor.py +0 -0
  66. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/dom/playground/extraction.py +0 -0
  67. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/dom/playground/multi_act.py +0 -0
  68. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/dom/serializer/clickable_elements.py +0 -0
  69. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/dom/serializer/code_use_serializer.py +0 -0
  70. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/dom/serializer/eval_serializer.py +0 -0
  71. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/dom/serializer/html_serializer.py +0 -0
  72. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/dom/serializer/paint_order.py +0 -0
  73. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/dom/service.py +0 -0
  74. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/dom/utils.py +0 -0
  75. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/exceptions.py +0 -0
  76. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/filesystem/__init__.py +0 -0
  77. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/filesystem/file_system.py +0 -0
  78. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/init_cmd.py +0 -0
  79. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/integrations/gmail/__init__.py +0 -0
  80. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/integrations/gmail/actions.py +0 -0
  81. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/integrations/gmail/service.py +0 -0
  82. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/llm/__init__.py +0 -0
  83. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/llm/anthropic/chat.py +0 -0
  84. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/llm/anthropic/serializer.py +0 -0
  85. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/llm/aws/__init__.py +0 -0
  86. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/llm/aws/chat_anthropic.py +0 -0
  87. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/llm/aws/chat_bedrock.py +0 -0
  88. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/llm/aws/serializer.py +0 -0
  89. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/llm/azure/chat.py +0 -0
  90. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/llm/base.py +0 -0
  91. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/llm/browser_use/__init__.py +0 -0
  92. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/llm/browser_use/chat.py +0 -0
  93. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/llm/cerebras/chat.py +0 -0
  94. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/llm/cerebras/serializer.py +0 -0
  95. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/llm/deepseek/chat.py +0 -0
  96. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/llm/deepseek/serializer.py +0 -0
  97. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/llm/exceptions.py +0 -0
  98. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/llm/google/__init__.py +0 -0
  99. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/llm/google/chat.py +0 -0
  100. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/llm/google/serializer.py +0 -0
  101. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/llm/groq/chat.py +0 -0
  102. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/llm/groq/parser.py +0 -0
  103. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/llm/groq/serializer.py +0 -0
  104. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/llm/messages.py +0 -0
  105. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/llm/models.py +0 -0
  106. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/llm/oci_raw/__init__.py +0 -0
  107. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/llm/oci_raw/chat.py +0 -0
  108. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/llm/oci_raw/serializer.py +0 -0
  109. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/llm/ollama/chat.py +0 -0
  110. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/llm/ollama/serializer.py +0 -0
  111. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/llm/openai/chat.py +0 -0
  112. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/llm/openai/like.py +0 -0
  113. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/llm/openai/serializer.py +0 -0
  114. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/llm/openrouter/chat.py +0 -0
  115. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/llm/openrouter/serializer.py +0 -0
  116. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/llm/schema.py +0 -0
  117. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/llm/views.py +0 -0
  118. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/logging_config.py +0 -0
  119. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/mcp/__init__.py +0 -0
  120. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/mcp/__main__.py +0 -0
  121. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/mcp/client.py +0 -0
  122. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/mcp/controller.py +0 -0
  123. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/mcp/server.py +0 -0
  124. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/observability.py +0 -0
  125. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/py.typed +0 -0
  126. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/sandbox/__init__.py +0 -0
  127. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/sandbox/sandbox.py +0 -0
  128. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/sandbox/views.py +0 -0
  129. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/screenshots/__init__.py +0 -0
  130. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/screenshots/service.py +0 -0
  131. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/sync/__init__.py +0 -0
  132. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/sync/auth.py +0 -0
  133. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/sync/service.py +0 -0
  134. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/telemetry/__init__.py +0 -0
  135. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/telemetry/service.py +0 -0
  136. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/telemetry/views.py +0 -0
  137. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/tokens/__init__.py +0 -0
  138. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/tokens/custom_pricing.py +0 -0
  139. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/tokens/mappings.py +0 -0
  140. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/tokens/service.py +0 -0
  141. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/tokens/views.py +0 -0
  142. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/tools/registry/service.py +0 -0
  143. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/tools/registry/views.py +0 -0
  144. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/tools/service.py +0 -0
  145. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/tools/utils.py +0 -0
  146. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/tools/views.py +0 -0
  147. {optexity_browser_use-0.9.5 → optexity_browser_use-0.9.5.1}/browser_use/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: optexity-browser-use
3
- Version: 0.9.5
3
+ Version: 0.9.5.1
4
4
  Summary: Make websites accessible for AI agents
5
5
  Project-URL: Repository, https://github.com/browser-use/browser-use
6
6
  Author: Gregor Zunic
@@ -792,19 +792,22 @@ class DOMTreeSerializer:
792
792
  return False
793
793
 
794
794
  @staticmethod
795
- def serialize_tree(node: SimplifiedNode | None, include_attributes: list[str], depth: int = 0) -> str:
795
+ def serialize_tree(node: SimplifiedNode | None, include_attributes: list[str], depth: int = 0, remove_empty_nodes: bool = False) -> (list[str], bool):
796
796
  """Serialize the optimized tree to string format."""
797
797
  if not node:
798
- return ''
798
+ return [], False
799
+
800
+ is_empty_node = False
799
801
 
800
802
  # Skip rendering excluded nodes, but process their children
801
803
  if hasattr(node, 'excluded_by_parent') and node.excluded_by_parent:
802
804
  formatted_text = []
803
805
  for child in node.children:
804
- child_text = DOMTreeSerializer.serialize_tree(child, include_attributes, depth)
806
+ child_formatted_text, child_is_interactive = DOMTreeSerializer.serialize_tree(child, include_attributes, depth, remove_empty_nodes)
807
+ child_text = '\n'.join(child_formatted_text)
805
808
  if child_text:
806
809
  formatted_text.append(child_text)
807
- return '\n'.join(formatted_text)
810
+ return formatted_text, node.is_interactive
808
811
 
809
812
  formatted_text = []
810
813
  depth_str = depth * '\t'
@@ -814,10 +817,11 @@ class DOMTreeSerializer:
814
817
  # Skip displaying nodes marked as should_display=False
815
818
  if not node.should_display:
816
819
  for child in node.children:
817
- child_text = DOMTreeSerializer.serialize_tree(child, include_attributes, depth)
820
+ child_formatted_text, child_is_interactive = DOMTreeSerializer.serialize_tree(child, include_attributes, depth, remove_empty_nodes)
821
+ child_text = '\n'.join(child_formatted_text)
818
822
  if child_text:
819
823
  formatted_text.append(child_text)
820
- return '\n'.join(formatted_text)
824
+ return formatted_text, node.is_interactive
821
825
 
822
826
  # Special handling for SVG elements - show the tag but collapse children
823
827
  if node.original_node.tag_name.lower() == 'svg':
@@ -843,7 +847,7 @@ class DOMTreeSerializer:
843
847
  line += ' /> <!-- SVG content collapsed -->'
844
848
  formatted_text.append(line)
845
849
  # Don't process children for SVG
846
- return '\n'.join(formatted_text)
850
+ return formatted_text, node.is_interactive
847
851
 
848
852
  # Add element if clickable, scrollable, or iframe
849
853
  is_any_scrollable = node.original_node.is_actually_scrollable or node.original_node.is_scrollable
@@ -936,6 +940,14 @@ class DOMTreeSerializer:
936
940
  scroll_info_text = node.original_node.get_scroll_info_text()
937
941
  if scroll_info_text:
938
942
  line += f' ({scroll_info_text})'
943
+ else:
944
+ '''
945
+ We mark the node as empty if it has no attributes. like <button />.
946
+ But if it has some attributes, we don't mark it as empty. Like <button class="btn btn-primary">Login</button>.
947
+ We also don't touch scroll stuff as I do not know about that.
948
+ '''
949
+ if not attributes_html_str:
950
+ is_empty_node = True
939
951
 
940
952
  formatted_text.append(line)
941
953
 
@@ -950,7 +962,8 @@ class DOMTreeSerializer:
950
962
 
951
963
  # Process shadow DOM children
952
964
  for child in node.children:
953
- child_text = DOMTreeSerializer.serialize_tree(child, include_attributes, next_depth)
965
+ child_formatted_text, child_is_interactive = DOMTreeSerializer.serialize_tree(child, include_attributes, next_depth, remove_empty_nodes)
966
+ child_text = '\n'.join(child_formatted_text)
954
967
  if child_text:
955
968
  formatted_text.append(child_text)
956
969
 
@@ -972,13 +985,48 @@ class DOMTreeSerializer:
972
985
 
973
986
  # Process children (for non-shadow elements)
974
987
  if node.original_node.node_type != NodeType.DOCUMENT_FRAGMENT_NODE:
988
+ child_texts: list[str] = []
989
+ child_is_interactives: list[bool] = []
975
990
  for child in node.children:
976
- child_text = DOMTreeSerializer.serialize_tree(child, include_attributes, next_depth)
991
+ child_formatted_text, child_is_interactive = DOMTreeSerializer.serialize_tree(child, include_attributes, next_depth, remove_empty_nodes)
992
+ child_text = '\n'.join(child_formatted_text)
993
+ if child_text!='':
994
+ child_texts.append(child_text)
995
+ child_is_interactives.append(child_is_interactive)
996
+
997
+ if remove_empty_nodes:
998
+ if is_empty_node and depth >= 0:
999
+
1000
+ if len(child_texts) == 1 and len(formatted_text) > 0:
1001
+ if child_is_interactives[0]:
1002
+ formatted_text.pop()
1003
+
1004
+ '''
1005
+ bring child one level up as this is the new level of child
1006
+ '''
1007
+ if child_texts[0].startswith('\t'):
1008
+ temp = [a[1:] for a in child_texts[0].split("\n")]
1009
+ child_texts[0] = "\n".join(temp)
1010
+
1011
+
1012
+ if len(child_texts) > 1 and len(formatted_text) > 0:
1013
+ if all(child_is_interactives):
1014
+ formatted_text.pop()
1015
+
1016
+ '''
1017
+ bring all children one level up as this is the new level of child if they start with a tab
1018
+ '''
1019
+ if all([child_text.startswith('\t') for child_text in child_texts]):
1020
+ for i in range(len(child_texts)):
1021
+ temp = [a[1:] for a in child_texts[i].split("\n")]
1022
+ child_texts[i] = "\n".join(temp)
1023
+
1024
+ for child_text in child_texts:
977
1025
  if child_text:
978
1026
  formatted_text.append(child_text)
979
1027
 
980
- return '\n'.join(formatted_text)
981
-
1028
+ return formatted_text, node.is_interactive
1029
+
982
1030
  @staticmethod
983
1031
  def _build_attributes_string(node: EnhancedDOMTreeNode, include_attributes: list[str], text: str) -> str:
984
1032
  """Build the attributes string for an element."""
@@ -817,6 +817,7 @@ class SerializedDOMState:
817
817
  def llm_representation(
818
818
  self,
819
819
  include_attributes: list[str] | None = None,
820
+ remove_empty_nodes: bool = False,
820
821
  ) -> str:
821
822
  """Kinda ugly, but leaving this as an internal method because include_attributes are a parameter on the agent, so we need to leave it as a 2 step process"""
822
823
  from browser_use.dom.serializer.serializer import DOMTreeSerializer
@@ -826,7 +827,21 @@ class SerializedDOMState:
826
827
 
827
828
  include_attributes = include_attributes or DEFAULT_INCLUDE_ATTRIBUTES
828
829
 
829
- return DOMTreeSerializer.serialize_tree(self._root, include_attributes)
830
+ formatted_text, is_interactive = DOMTreeSerializer.serialize_tree(self._root, include_attributes, remove_empty_nodes=remove_empty_nodes)
831
+ final_text = '\n'.join(formatted_text)
832
+ if remove_empty_nodes:
833
+ '''
834
+ remove extra tabs from the beginning of the lines
835
+ '''
836
+ formatted_text = final_text.split('\n')
837
+ for i in range(1,len(formatted_text)):
838
+ prev_tabs = len(formatted_text[i-1]) - len(formatted_text[i-1].lstrip('\t'))
839
+ curr_tabs = len(formatted_text[i]) - len(formatted_text[i].lstrip('\t'))
840
+ while curr_tabs - prev_tabs>1:
841
+ formatted_text[i] = formatted_text[i][1:]
842
+ curr_tabs = len(formatted_text[i]) - len(formatted_text[i].lstrip('\t'))
843
+ final_text = '\n'.join(formatted_text)
844
+ return final_text
830
845
 
831
846
  @observe_debug(ignore_input=True, ignore_output=True, name='eval_representation')
832
847
  def eval_representation(
@@ -2,7 +2,7 @@
2
2
  name = "optexity-browser-use"
3
3
  description = "Make websites accessible for AI agents"
4
4
  authors = [{ name = "Gregor Zunic" }]
5
- version = "0.9.5"
5
+ version = "0.9.5.1"
6
6
  readme = "README.md"
7
7
  requires-python = ">=3.11,<4.0"
8
8
  classifiers = [