unrealon 2.0.5__tar.gz → 2.0.7__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 (135) hide show
  1. {unrealon-2.0.5/unrealon.egg-info → unrealon-2.0.7}/PKG-INFO +1 -1
  2. {unrealon-2.0.5 → unrealon-2.0.7}/pyproject.toml +1 -1
  3. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-core/src/unrealon_core/__init__.py +10 -1
  4. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-core/src/unrealon_core/enums/types.py +1 -0
  5. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-core/src/unrealon_core/models/websocket/__init__.py +13 -1
  6. unrealon-2.0.7/unrealon-core/src/unrealon_core/models/websocket/broadcast.py +168 -0
  7. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-driver/src/unrealon_driver/driver/communication/session.py +12 -3
  8. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-driver/src/unrealon_driver/driver/communication/websocket_client.py +17 -12
  9. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-driver/src/unrealon_driver/driver/lifecycle/daemon.py +1 -0
  10. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-driver/src/unrealon_driver/driver/lifecycle/initialization.py +14 -1
  11. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-driver/src/unrealon_driver/managers/logger.py +5 -0
  12. {unrealon-2.0.5 → unrealon-2.0.7/unrealon.egg-info}/PKG-INFO +1 -1
  13. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon.egg-info/SOURCES.txt +1 -0
  14. {unrealon-2.0.5 → unrealon-2.0.7}/LICENSE +0 -0
  15. {unrealon-2.0.5 → unrealon-2.0.7}/MANIFEST.in +0 -0
  16. {unrealon-2.0.5 → unrealon-2.0.7}/README.md +0 -0
  17. {unrealon-2.0.5 → unrealon-2.0.7}/setup.cfg +0 -0
  18. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-browser/src/unrealon_browser/README.md +0 -0
  19. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-browser/src/unrealon_browser/__init__.py +0 -0
  20. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-browser/src/unrealon_browser/cli/__init__.py +0 -0
  21. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-browser/src/unrealon_browser/cli/browser_cli.py +0 -0
  22. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-browser/src/unrealon_browser/cli/cookies_cli.py +0 -0
  23. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-browser/src/unrealon_browser/cli/interactive_mode.py +0 -0
  24. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-browser/src/unrealon_browser/cli/main.py +0 -0
  25. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-browser/src/unrealon_browser/core/__init__.py +0 -0
  26. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-browser/src/unrealon_browser/core/browser_manager.py +0 -0
  27. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-browser/src/unrealon_browser/dto/__init__.py +0 -0
  28. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-browser/src/unrealon_browser/dto/bot_detection.py +0 -0
  29. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-browser/src/unrealon_browser/dto/models/config.py +0 -0
  30. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-browser/src/unrealon_browser/dto/models/core.py +0 -0
  31. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-browser/src/unrealon_browser/dto/models/dataclasses.py +0 -0
  32. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-browser/src/unrealon_browser/dto/models/detection.py +0 -0
  33. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-browser/src/unrealon_browser/dto/models/enums.py +0 -0
  34. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-browser/src/unrealon_browser/dto/models/statistics.py +0 -0
  35. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-browser/src/unrealon_browser/managers/__init__.py +0 -0
  36. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-browser/src/unrealon_browser/managers/captcha.py +0 -0
  37. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-browser/src/unrealon_browser/managers/cookies.py +0 -0
  38. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-browser/src/unrealon_browser/managers/logger_bridge.py +0 -0
  39. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-browser/src/unrealon_browser/managers/page_wait_manager.py +0 -0
  40. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-browser/src/unrealon_browser/managers/profile.py +0 -0
  41. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-browser/src/unrealon_browser/stealth/__init__.py +0 -0
  42. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-browser/src/unrealon_browser/stealth/bypass_techniques.pyc +0 -0
  43. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-browser/src/unrealon_browser/stealth/manager.pyc +0 -0
  44. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-browser/src/unrealon_browser/stealth/nodriver_stealth.pyc +0 -0
  45. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-browser/src/unrealon_browser/stealth/playwright_stealth.pyc +0 -0
  46. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-browser/src/unrealon_browser/stealth/scanner_tester.pyc +0 -0
  47. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-browser/src/unrealon_browser/stealth/undetected_chrome.pyc +0 -0
  48. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-core/src/unrealon_core/config/__init__.py +0 -0
  49. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-core/src/unrealon_core/config/environment.py +0 -0
  50. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-core/src/unrealon_core/config/urls.py +0 -0
  51. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-core/src/unrealon_core/enums/__init__.py +0 -0
  52. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-core/src/unrealon_core/enums/status.py +0 -0
  53. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-core/src/unrealon_core/error_handling/__init__.py +0 -0
  54. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-core/src/unrealon_core/error_handling/circuit_breaker.py +0 -0
  55. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-core/src/unrealon_core/error_handling/error_context.py +0 -0
  56. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-core/src/unrealon_core/error_handling/recovery.py +0 -0
  57. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-core/src/unrealon_core/error_handling/retry.py +0 -0
  58. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-core/src/unrealon_core/exceptions/__init__.py +0 -0
  59. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-core/src/unrealon_core/exceptions/base.py +0 -0
  60. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-core/src/unrealon_core/exceptions/communication.py +0 -0
  61. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-core/src/unrealon_core/exceptions/driver.py +0 -0
  62. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-core/src/unrealon_core/exceptions/proxy.py +0 -0
  63. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-core/src/unrealon_core/exceptions/task.py +0 -0
  64. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-core/src/unrealon_core/exceptions/validation.py +0 -0
  65. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-core/src/unrealon_core/models/__init__.py +0 -0
  66. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-core/src/unrealon_core/models/arq_context.py +0 -0
  67. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-core/src/unrealon_core/models/arq_responses.py +0 -0
  68. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-core/src/unrealon_core/models/base.py +0 -0
  69. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-core/src/unrealon_core/models/bridge_stats.py +0 -0
  70. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-core/src/unrealon_core/models/communication.py +0 -0
  71. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-core/src/unrealon_core/models/connection_stats.py +0 -0
  72. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-core/src/unrealon_core/models/driver.py +0 -0
  73. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-core/src/unrealon_core/models/driver_details.py +0 -0
  74. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-core/src/unrealon_core/models/logging.py +0 -0
  75. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-core/src/unrealon_core/models/task.py +0 -0
  76. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-core/src/unrealon_core/models/typed_responses.py +0 -0
  77. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-core/src/unrealon_core/models/websocket/base.py +0 -0
  78. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-core/src/unrealon_core/models/websocket/config.py +0 -0
  79. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-core/src/unrealon_core/models/websocket/driver.py +0 -0
  80. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-core/src/unrealon_core/models/websocket/errors.py +0 -0
  81. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-core/src/unrealon_core/models/websocket/heartbeat.py +0 -0
  82. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-core/src/unrealon_core/models/websocket/logging.py +0 -0
  83. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-core/src/unrealon_core/models/websocket/proxy.py +0 -0
  84. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-core/src/unrealon_core/models/websocket/tasks.py +0 -0
  85. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-core/src/unrealon_core/models/websocket/utils.py +0 -0
  86. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-core/src/unrealon_core/models/websocket_session.py +0 -0
  87. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-core/src/unrealon_core/monitoring/__init__.py +0 -0
  88. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-core/src/unrealon_core/monitoring/alerts.py +0 -0
  89. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-core/src/unrealon_core/monitoring/dashboard.py +0 -0
  90. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-core/src/unrealon_core/monitoring/health_check.py +0 -0
  91. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-core/src/unrealon_core/monitoring/metrics.py +0 -0
  92. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-core/src/unrealon_core/utils/__init__.py +0 -0
  93. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-core/src/unrealon_core/utils/time.py +0 -0
  94. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-core/src/unrealon_core/version.py +0 -0
  95. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-driver/src/unrealon_driver/__init__.py +0 -0
  96. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-driver/src/unrealon_driver/core_module/__init__.py +0 -0
  97. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-driver/src/unrealon_driver/core_module/base.py +0 -0
  98. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-driver/src/unrealon_driver/core_module/config.py +0 -0
  99. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-driver/src/unrealon_driver/core_module/event_manager.py +0 -0
  100. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-driver/src/unrealon_driver/core_module/protocols.py +0 -0
  101. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-driver/src/unrealon_driver/core_module/registry.py +0 -0
  102. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-driver/src/unrealon_driver/decorators/__init__.py +0 -0
  103. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-driver/src/unrealon_driver/decorators/retry.py +0 -0
  104. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-driver/src/unrealon_driver/decorators/schedule.py +0 -0
  105. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-driver/src/unrealon_driver/decorators/task.py +0 -0
  106. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-driver/src/unrealon_driver/decorators/timing.py +0 -0
  107. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-driver/src/unrealon_driver/driver/__init__.py +0 -0
  108. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-driver/src/unrealon_driver/driver/communication/__init__.py +0 -0
  109. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-driver/src/unrealon_driver/driver/core/__init__.py +0 -0
  110. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-driver/src/unrealon_driver/driver/core/config.py +0 -0
  111. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-driver/src/unrealon_driver/driver/core/driver.py +0 -0
  112. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-driver/src/unrealon_driver/driver/factory/__init__.py +0 -0
  113. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-driver/src/unrealon_driver/driver/factory/manager_factory.py +0 -0
  114. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-driver/src/unrealon_driver/driver/lifecycle/__init__.py +0 -0
  115. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-driver/src/unrealon_driver/driver/lifecycle/shutdown.py +0 -0
  116. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-driver/src/unrealon_driver/driver/monitoring/__init__.py +0 -0
  117. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-driver/src/unrealon_driver/driver/monitoring/health.py +0 -0
  118. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-driver/src/unrealon_driver/driver/utilities/__init__.py +0 -0
  119. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-driver/src/unrealon_driver/driver/utilities/logging.py +0 -0
  120. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-driver/src/unrealon_driver/driver/utilities/serialization.py +0 -0
  121. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-driver/src/unrealon_driver/managers/__init__.py +0 -0
  122. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-driver/src/unrealon_driver/managers/base.py +0 -0
  123. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-driver/src/unrealon_driver/managers/browser.py +0 -0
  124. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-driver/src/unrealon_driver/managers/cache.py +0 -0
  125. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-driver/src/unrealon_driver/managers/http.py +0 -0
  126. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-driver/src/unrealon_driver/managers/proxy.py +0 -0
  127. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-driver/src/unrealon_driver/managers/registry.py +0 -0
  128. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-driver/src/unrealon_driver/managers/threading.py +0 -0
  129. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-driver/src/unrealon_driver/managers/update.py +0 -0
  130. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-driver/src/unrealon_driver/utils/__init__.py +0 -0
  131. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon-driver/src/unrealon_driver/utils/time.py +0 -0
  132. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon.egg-info/dependency_links.txt +0 -0
  133. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon.egg-info/entry_points.txt +0 -0
  134. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon.egg-info/requires.txt +0 -0
  135. {unrealon-2.0.5 → unrealon-2.0.7}/unrealon.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: unrealon
3
- Version: 2.0.5
3
+ Version: 2.0.7
4
4
  Summary: Enterprise-grade web scraping platform with AI-powered automation and real-time orchestration capabilities
5
5
  Author-email: UnrealOn Team <team@unrealon.com>
6
6
  License: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "unrealon"
7
- version = "2.0.5"
7
+ version = "2.0.7"
8
8
  description = "Enterprise-grade web scraping platform with AI-powered automation and real-time orchestration capabilities"
9
9
  authors = [
10
10
  {name = "UnrealOn Team", email = "team@unrealon.com"}
@@ -42,7 +42,10 @@ from .models.communication import (
42
42
  create_error_message, create_ack_message,
43
43
  # Data models for strict typing
44
44
  TaskAssignmentData, TaskResultData,
45
- DriverRegistrationData, HeartbeatData, LogEntryData, LogContext
45
+ DriverRegistrationData, HeartbeatData, LogEntryData, LogContext,
46
+ # Broadcast models
47
+ DriverBroadcastData, DriverRegisterBroadcast,
48
+ DriverHeartbeatBroadcast, DriverDisconnectBroadcast
46
49
  )
47
50
  from .enums.status import DriverStatus, TaskStatus, ProxyStatus, LogLevel
48
51
  from .enums.types import MessageType, ProxyType, TaskPriority
@@ -127,6 +130,12 @@ __all__ = [
127
130
  "LogEntryData",
128
131
  "LogContext",
129
132
 
133
+ # Broadcast models
134
+ "DriverBroadcastData",
135
+ "DriverRegisterBroadcast",
136
+ "DriverHeartbeatBroadcast",
137
+ "DriverDisconnectBroadcast",
138
+
130
139
  # Status enums
131
140
  "DriverStatus",
132
141
  "TaskStatus",
@@ -53,6 +53,7 @@ class MessageType(str, Enum):
53
53
  LOG_BATCH = "log_batch" # Batch of log messages
54
54
 
55
55
  # System messages
56
+ WELCOME = "welcome" # Welcome message from server
56
57
  PING = "ping" # Ping message
57
58
  PONG = "pong" # Pong response
58
59
  ERROR = "error" # Error message
@@ -38,6 +38,12 @@ from .proxy import (
38
38
  )
39
39
 
40
40
  from .utils import create_error_message, create_ack_message
41
+ from .broadcast import (
42
+ DriverBroadcastData,
43
+ DriverRegisterBroadcast,
44
+ DriverHeartbeatBroadcast,
45
+ DriverDisconnectBroadcast
46
+ )
41
47
 
42
48
  __all__ = [
43
49
  # Base
@@ -87,5 +93,11 @@ __all__ = [
87
93
 
88
94
  # Utilities
89
95
  'create_error_message',
90
- 'create_ack_message'
96
+ 'create_ack_message',
97
+
98
+ # Broadcast messages
99
+ 'DriverBroadcastData',
100
+ 'DriverRegisterBroadcast',
101
+ 'DriverHeartbeatBroadcast',
102
+ 'DriverDisconnectBroadcast'
91
103
  ]
@@ -0,0 +1,168 @@
1
+ """
2
+ Broadcast WebSocket Models.
3
+
4
+ Strictly typed models for broadcasting driver events to monitoring clients.
5
+ These are Server → Client messages for real-time monitoring.
6
+
7
+ Phase 2: Core Systems - WebSocket Bridge
8
+ """
9
+
10
+ from typing import List, Optional
11
+ from pydantic import Field, ConfigDict
12
+
13
+ from ..base import UnrealOnBaseModel
14
+ from .base import WebSocketMessage, MessageType
15
+
16
+
17
+ class DriverBroadcastData(UnrealOnBaseModel):
18
+ """Driver broadcast data payload - strictly typed."""
19
+
20
+ model_config = ConfigDict(
21
+ validate_assignment=True,
22
+ extra="forbid"
23
+ )
24
+
25
+ driver_id: str = Field(
26
+ description="Unique driver identifier",
27
+ min_length=1
28
+ )
29
+
30
+ driver_type: str = Field(
31
+ description="Type of driver (e.g., 'universal', 'ecommerce')",
32
+ min_length=1
33
+ )
34
+
35
+ status: str = Field(
36
+ default="active",
37
+ pattern=r"^(active|idle|busy|offline|error)$",
38
+ description="Current driver status"
39
+ )
40
+
41
+ capabilities: List[str] = Field(
42
+ default_factory=list,
43
+ description="List of supported task types"
44
+ )
45
+
46
+ active_tasks: int = Field(
47
+ default=0,
48
+ ge=0,
49
+ description="Number of currently active tasks"
50
+ )
51
+
52
+ completed_tasks: int = Field(
53
+ default=0,
54
+ ge=0,
55
+ description="Total completed tasks since startup"
56
+ )
57
+
58
+ failed_tasks: int = Field(
59
+ default=0,
60
+ ge=0,
61
+ description="Total failed tasks since startup"
62
+ )
63
+
64
+ uptime_seconds: float = Field(
65
+ default=0.0,
66
+ ge=0.0,
67
+ description="Driver uptime in seconds"
68
+ )
69
+
70
+ last_seen: Optional[str] = Field(
71
+ default=None,
72
+ description="ISO timestamp of last heartbeat"
73
+ )
74
+
75
+ connected_at: Optional[str] = Field(
76
+ default=None,
77
+ description="ISO timestamp when driver connected"
78
+ )
79
+
80
+ disconnected_at: Optional[str] = Field(
81
+ default=None,
82
+ description="ISO timestamp when driver disconnected"
83
+ )
84
+
85
+ # Additional fields for complete driver information
86
+ version: Optional[str] = Field(
87
+ default=None,
88
+ description="Driver version"
89
+ )
90
+
91
+ driver_name: Optional[str] = Field(
92
+ default=None,
93
+ description="Human-readable driver name"
94
+ )
95
+
96
+ environment: Optional[str] = Field(
97
+ default=None,
98
+ description="Driver environment (development, production, etc.)"
99
+ )
100
+
101
+ region: Optional[str] = Field(
102
+ default=None,
103
+ description="Driver region"
104
+ )
105
+
106
+ max_concurrent_tasks: Optional[int] = Field(
107
+ default=None,
108
+ ge=1,
109
+ description="Maximum concurrent tasks"
110
+ )
111
+
112
+ tags: List[str] = Field(
113
+ default_factory=list,
114
+ description="Driver tags"
115
+ )
116
+
117
+
118
+ class DriverRegisterBroadcast(WebSocketMessage):
119
+ """Driver registration broadcast message (Server → Monitoring Clients)."""
120
+
121
+ model_config = ConfigDict(
122
+ validate_assignment=True,
123
+ extra="forbid"
124
+ )
125
+
126
+ type: MessageType = Field(
127
+ default=MessageType.DRIVER_REGISTER
128
+ )
129
+
130
+ data: DriverBroadcastData = Field(
131
+ description="Driver registration broadcast data"
132
+ )
133
+
134
+
135
+ class DriverHeartbeatBroadcast(WebSocketMessage):
136
+ """Driver heartbeat broadcast message (Server → Monitoring Clients)."""
137
+
138
+ model_config = ConfigDict(
139
+ validate_assignment=True,
140
+ extra="forbid"
141
+ )
142
+
143
+ type: MessageType = Field(
144
+ default=MessageType.DRIVER_HEARTBEAT,
145
+ frozen=True
146
+ )
147
+
148
+ data: DriverBroadcastData = Field(
149
+ description="Driver heartbeat broadcast data"
150
+ )
151
+
152
+
153
+ class DriverDisconnectBroadcast(WebSocketMessage):
154
+ """Driver disconnect broadcast message (Server → Monitoring Clients)."""
155
+
156
+ model_config = ConfigDict(
157
+ validate_assignment=True,
158
+ extra="forbid"
159
+ )
160
+
161
+ type: MessageType = Field(
162
+ default=MessageType.DRIVER_DISCONNECT,
163
+ frozen=True
164
+ )
165
+
166
+ data: DriverBroadcastData = Field(
167
+ description="Driver disconnect broadcast data"
168
+ )
@@ -12,6 +12,7 @@ from pydantic import BaseModel, Field
12
12
 
13
13
  from unrealon_core.models.websocket import (
14
14
  TaskAssignmentData,
15
+ TaskAssignmentMessage,
15
16
  TaskResultData,
16
17
  WebSocketMessage
17
18
  )
@@ -69,21 +70,26 @@ class DriverSession:
69
70
 
70
71
  try:
71
72
  # Connect WebSocket
73
+ logger.info(f"🔌 Connecting WebSocket for driver: {self.driver_id}")
72
74
  self.status = SessionStatus.CONNECTING
73
75
  if not await self.websocket_client.connect():
76
+ logger.error(f"❌ WebSocket connection failed for driver: {self.driver_id}")
74
77
  self.status = SessionStatus.ERROR
75
78
  return False
76
79
 
80
+ logger.info(f"✅ WebSocket connected for driver: {self.driver_id}")
77
81
  self.status = SessionStatus.CONNECTED
78
82
  self.stats.connected_at = utc_now()
79
83
 
80
84
  # Register driver
85
+ logger.info(f"📝 Registering driver: {self.driver_id} with capabilities: {capabilities}")
81
86
  if await self.register(capabilities or []):
82
87
  self.status = SessionStatus.REGISTERED
83
88
  self.stats.registered_at = utc_now()
84
- logger.info(f"Session started for driver: {self.driver_id}")
89
+ logger.info(f"Session started for driver: {self.driver_id}")
85
90
  return True
86
91
  else:
92
+ logger.error(f"❌ Driver registration failed for: {self.driver_id}")
87
93
  self.status = SessionStatus.ERROR
88
94
  return False
89
95
 
@@ -139,8 +145,11 @@ class DriverSession:
139
145
  async def _handle_task_assignment(self, message: WebSocketMessage):
140
146
  """Handle task assignment."""
141
147
  try:
142
- # Validate task data
143
- task_data = TaskAssignmentData.model_validate(message.data)
148
+ # Parse as TaskAssignmentMessage
149
+
150
+ # Convert to proper task assignment message
151
+ task_message = TaskAssignmentMessage.model_validate(message.model_dump())
152
+ task_data = task_message.data
144
153
 
145
154
  # Find handler
146
155
  handler = self.task_handlers.get(task_data.task_type)
@@ -40,9 +40,11 @@ class WebSocketClient:
40
40
  - Clean error handling
41
41
  """
42
42
 
43
- def __init__(self, websocket_url: str, driver_id: str):
43
+ def __init__(self, websocket_url: str, driver_id: str, custom_logger=None):
44
44
  self.websocket_url = websocket_url
45
45
  self.driver_id = driver_id
46
+ # Use custom logger if provided, otherwise use default
47
+ self._logger = custom_logger if custom_logger else logger
46
48
  self.websocket: Optional[ClientConnection] = None
47
49
  self.connected = False
48
50
  self.running = False
@@ -94,20 +96,20 @@ class WebSocketClient:
94
96
  self.websocket = None
95
97
 
96
98
  self.connected = False
97
- logger.info("WebSocket client stopped")
99
+ self._logger.info("WebSocket client stopped")
98
100
 
99
101
  async def _establish_connection(self) -> bool:
100
102
  """Establish WebSocket connection."""
101
103
  try:
102
- logger.info(f"Connecting to WebSocket: {self.websocket_url}")
104
+ self._logger.info(f"Connecting to WebSocket: {self.websocket_url}")
103
105
  self.websocket = await websockets.connect(self.websocket_url)
104
106
  self.connected = True
105
107
  self.reconnect_attempts = 0
106
108
  self.reconnect_delay = 1.0
107
- logger.info("WebSocket connected successfully")
109
+ self._logger.info("WebSocket connected successfully")
108
110
  return True
109
111
  except Exception as e:
110
- logger.error(f"WebSocket connection failed: {e}")
112
+ self._logger.error(f"WebSocket connection failed: {e}")
111
113
  self.connected = False
112
114
  return False
113
115
 
@@ -115,10 +117,10 @@ class WebSocketClient:
115
117
  """Monitor connection and handle reconnection."""
116
118
  while self.running:
117
119
  if not self.connected and self.running:
118
- logger.info(f"Attempting reconnection (attempt {self.reconnect_attempts + 1})")
120
+ self._logger.info(f"Attempting reconnection (attempt {self.reconnect_attempts + 1})")
119
121
 
120
122
  if await self._establish_connection():
121
- logger.info("Reconnection successful")
123
+ self._logger.info("Reconnection successful")
122
124
  else:
123
125
  self.reconnect_attempts += 1
124
126
  # Exponential backoff
@@ -136,13 +138,16 @@ class WebSocketClient:
136
138
  if self.connected and self.websocket and self.message_queue:
137
139
  try:
138
140
  message = self.message_queue.popleft()
141
+ self._logger.info(f"📤 Sending WebSocket message: {message[:200]}...") # Log first 200 chars
139
142
  await self.websocket.send(message)
143
+ self._logger.info(f"✅ Message sent successfully")
140
144
  except (websockets.exceptions.ConnectionClosed, ConnectionResetError):
141
145
  self.connected = False
142
146
  # Put message back in queue
143
147
  self.message_queue.appendleft(message)
148
+ self._logger.warning("🔌 Connection lost, message queued for retry")
144
149
  except Exception as e:
145
- logger.error(f"Error sending message: {e}")
150
+ self._logger.error(f"Error sending message: {e}")
146
151
  else:
147
152
  await asyncio.sleep(0.1)
148
153
 
@@ -163,9 +168,9 @@ class WebSocketClient:
163
168
 
164
169
  except (websockets.exceptions.ConnectionClosed, ConnectionResetError):
165
170
  self.connected = False
166
- logger.warning("WebSocket connection lost")
171
+ self._logger.warning("WebSocket connection lost")
167
172
  except Exception as e:
168
- logger.error(f"Error receiving message: {e}")
173
+ self._logger.error(f"Error receiving message: {e}")
169
174
  else:
170
175
  await asyncio.sleep(0.1)
171
176
 
@@ -197,9 +202,9 @@ class WebSocketClient:
197
202
  # Queue for sending
198
203
  self.send(registration_message)
199
204
 
200
- logger.info(f"Driver registration queued: {self.driver_id}")
205
+ self._logger.info(f"Driver registration queued: {self.driver_id}")
201
206
  return True
202
207
 
203
208
  except Exception as e:
204
- logger.error(f"Driver registration failed: {e}")
209
+ self._logger.error(f"Driver registration failed: {e}")
205
210
  return False
@@ -47,6 +47,7 @@ class DaemonManager:
47
47
 
48
48
  try:
49
49
  # Initialize driver with capabilities
50
+ logger.info(f"🎯 Daemon initializing driver with capabilities: {driver.capabilities}")
50
51
  success = await DriverInitializer.initialize_driver(driver, driver.capabilities)
51
52
  if not success:
52
53
  raise RuntimeError("Driver initialization failed")
@@ -10,6 +10,8 @@ from typing import List, TYPE_CHECKING
10
10
  from ..core.config import DriverMode
11
11
  from ..communication.websocket_client import WebSocketClient
12
12
  from ..communication.session import DriverSession
13
+ from unrealon_core.config.environment import get_environment_config
14
+
13
15
 
14
16
  if TYPE_CHECKING:
15
17
  from ..core.driver import UniversalDriver
@@ -37,6 +39,14 @@ class DriverInitializer:
37
39
 
38
40
  try:
39
41
  logger.info(f"Initializing UniversalDriver: {driver.driver_id}")
42
+ logger.info(f"🔧 Driver mode: {driver.config.mode}")
43
+ logger.info(f"📡 WebSocket URL: {driver.config.effective_websocket_url}")
44
+ logger.info(f"🎯 Capabilities: {capabilities}")
45
+
46
+ # Log environment info if available
47
+ env_config = get_environment_config()
48
+ logger.info(f"🌐 Environment: {env_config.environment.value}")
49
+ print(f"🌐 Environment: {env_config.environment}")
40
50
 
41
51
  # Initialize manager system
42
52
  if not await driver.manager_registry.initialize_all():
@@ -65,9 +75,12 @@ class DriverInitializer:
65
75
 
66
76
  # Setup WebSocket client if URL available
67
77
  if websocket_url:
78
+ # Pass driver's logger to WebSocket client for unified logging
79
+ custom_logger = driver.logger_manager.local_logger if driver.logger_manager else None
68
80
  driver.websocket_client = WebSocketClient(
69
81
  websocket_url,
70
- driver.driver_id
82
+ driver.driver_id,
83
+ custom_logger=custom_logger
71
84
  )
72
85
 
73
86
  # Set WebSocket client for logger (always for logging)
@@ -89,6 +89,11 @@ class LoggerManager(BaseManager):
89
89
  self.local_logger.addHandler(handler)
90
90
  self.local_logger.setLevel(getattr(logging, self.config.log_level))
91
91
 
92
+ # Also configure root unrealon_driver logger to use same handler
93
+ unrealon_logger = logging.getLogger('unrealon_driver')
94
+ unrealon_logger.addHandler(handler)
95
+ unrealon_logger.setLevel(getattr(logging, self.config.log_level))
96
+
92
97
  except Exception as e:
93
98
  logger.error(f"Failed to setup local logging: {e}")
94
99
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: unrealon
3
- Version: 2.0.5
3
+ Version: 2.0.7
4
4
  Summary: Enterprise-grade web scraping platform with AI-powered automation and real-time orchestration capabilities
5
5
  Author-email: UnrealOn Team <team@unrealon.com>
6
6
  License: MIT
@@ -67,6 +67,7 @@ unrealon-core/src/unrealon_core/models/typed_responses.py
67
67
  unrealon-core/src/unrealon_core/models/websocket_session.py
68
68
  unrealon-core/src/unrealon_core/models/websocket/__init__.py
69
69
  unrealon-core/src/unrealon_core/models/websocket/base.py
70
+ unrealon-core/src/unrealon_core/models/websocket/broadcast.py
70
71
  unrealon-core/src/unrealon_core/models/websocket/config.py
71
72
  unrealon-core/src/unrealon_core/models/websocket/driver.py
72
73
  unrealon-core/src/unrealon_core/models/websocket/errors.py
File without changes
File without changes
File without changes
File without changes