unrealon 1.1.6__py3-none-any.whl → 2.0.4__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.
Files changed (145) hide show
  1. {unrealon-1.1.6.dist-info/licenses → unrealon-2.0.4.dist-info}/LICENSE +1 -1
  2. unrealon-2.0.4.dist-info/METADATA +491 -0
  3. unrealon-2.0.4.dist-info/RECORD +129 -0
  4. {unrealon-1.1.6.dist-info → unrealon-2.0.4.dist-info}/WHEEL +2 -1
  5. unrealon-2.0.4.dist-info/entry_points.txt +3 -0
  6. unrealon-2.0.4.dist-info/top_level.txt +3 -0
  7. unrealon_browser/__init__.py +5 -6
  8. unrealon_browser/cli/browser_cli.py +18 -9
  9. unrealon_browser/cli/interactive_mode.py +13 -4
  10. unrealon_browser/core/browser_manager.py +29 -16
  11. unrealon_browser/dto/__init__.py +21 -0
  12. unrealon_browser/dto/bot_detection.py +175 -0
  13. unrealon_browser/dto/models/config.py +9 -3
  14. unrealon_browser/managers/__init__.py +1 -1
  15. unrealon_browser/managers/logger_bridge.py +1 -4
  16. unrealon_browser/stealth/__init__.py +27 -0
  17. unrealon_browser/stealth/bypass_techniques.pyc +0 -0
  18. unrealon_browser/stealth/manager.pyc +0 -0
  19. unrealon_browser/stealth/nodriver_stealth.pyc +0 -0
  20. unrealon_browser/stealth/playwright_stealth.pyc +0 -0
  21. unrealon_browser/stealth/scanner_tester.pyc +0 -0
  22. unrealon_browser/stealth/undetected_chrome.pyc +0 -0
  23. unrealon_core/__init__.py +160 -0
  24. unrealon_core/config/__init__.py +16 -0
  25. unrealon_core/config/environment.py +98 -0
  26. unrealon_core/config/urls.py +93 -0
  27. unrealon_core/enums/__init__.py +24 -0
  28. unrealon_core/enums/status.py +216 -0
  29. unrealon_core/enums/types.py +240 -0
  30. unrealon_core/error_handling/__init__.py +45 -0
  31. unrealon_core/error_handling/circuit_breaker.py +292 -0
  32. unrealon_core/error_handling/error_context.py +324 -0
  33. unrealon_core/error_handling/recovery.py +371 -0
  34. unrealon_core/error_handling/retry.py +268 -0
  35. unrealon_core/exceptions/__init__.py +46 -0
  36. unrealon_core/exceptions/base.py +292 -0
  37. unrealon_core/exceptions/communication.py +22 -0
  38. unrealon_core/exceptions/driver.py +11 -0
  39. unrealon_core/exceptions/proxy.py +11 -0
  40. unrealon_core/exceptions/task.py +12 -0
  41. unrealon_core/exceptions/validation.py +17 -0
  42. unrealon_core/models/__init__.py +98 -0
  43. unrealon_core/models/arq_context.py +252 -0
  44. unrealon_core/models/arq_responses.py +125 -0
  45. unrealon_core/models/base.py +291 -0
  46. unrealon_core/models/bridge_stats.py +58 -0
  47. unrealon_core/models/communication.py +39 -0
  48. unrealon_core/models/config.py +47 -0
  49. unrealon_core/models/connection_stats.py +47 -0
  50. unrealon_core/models/driver.py +30 -0
  51. unrealon_core/models/driver_details.py +98 -0
  52. unrealon_core/models/logging.py +28 -0
  53. unrealon_core/models/task.py +21 -0
  54. unrealon_core/models/typed_responses.py +210 -0
  55. unrealon_core/models/websocket/__init__.py +91 -0
  56. unrealon_core/models/websocket/base.py +49 -0
  57. unrealon_core/models/websocket/config.py +200 -0
  58. unrealon_core/models/websocket/driver.py +215 -0
  59. unrealon_core/models/websocket/errors.py +138 -0
  60. unrealon_core/models/websocket/heartbeat.py +100 -0
  61. unrealon_core/models/websocket/logging.py +261 -0
  62. unrealon_core/models/websocket/proxy.py +496 -0
  63. unrealon_core/models/websocket/tasks.py +275 -0
  64. unrealon_core/models/websocket/utils.py +153 -0
  65. unrealon_core/models/websocket_session.py +144 -0
  66. unrealon_core/monitoring/__init__.py +43 -0
  67. unrealon_core/monitoring/alerts.py +398 -0
  68. unrealon_core/monitoring/dashboard.py +307 -0
  69. unrealon_core/monitoring/health_check.py +354 -0
  70. unrealon_core/monitoring/metrics.py +352 -0
  71. unrealon_core/utils/__init__.py +11 -0
  72. unrealon_core/utils/time.py +61 -0
  73. unrealon_core/version.py +219 -0
  74. unrealon_driver/__init__.py +90 -51
  75. unrealon_driver/core_module/__init__.py +34 -0
  76. unrealon_driver/core_module/base.py +184 -0
  77. unrealon_driver/core_module/config.py +30 -0
  78. unrealon_driver/core_module/event_manager.py +127 -0
  79. unrealon_driver/core_module/protocols.py +98 -0
  80. unrealon_driver/core_module/registry.py +146 -0
  81. unrealon_driver/decorators/__init__.py +15 -0
  82. unrealon_driver/decorators/retry.py +117 -0
  83. unrealon_driver/decorators/schedule.py +137 -0
  84. unrealon_driver/decorators/task.py +61 -0
  85. unrealon_driver/decorators/timing.py +132 -0
  86. unrealon_driver/driver/__init__.py +20 -0
  87. unrealon_driver/driver/communication/__init__.py +10 -0
  88. unrealon_driver/driver/communication/session.py +203 -0
  89. unrealon_driver/driver/communication/websocket_client.py +197 -0
  90. unrealon_driver/driver/core/__init__.py +10 -0
  91. unrealon_driver/driver/core/config.py +85 -0
  92. unrealon_driver/driver/core/driver.py +221 -0
  93. unrealon_driver/driver/factory/__init__.py +9 -0
  94. unrealon_driver/driver/factory/manager_factory.py +130 -0
  95. unrealon_driver/driver/lifecycle/__init__.py +11 -0
  96. unrealon_driver/driver/lifecycle/daemon.py +76 -0
  97. unrealon_driver/driver/lifecycle/initialization.py +97 -0
  98. unrealon_driver/driver/lifecycle/shutdown.py +48 -0
  99. unrealon_driver/driver/monitoring/__init__.py +9 -0
  100. unrealon_driver/driver/monitoring/health.py +63 -0
  101. unrealon_driver/driver/utilities/__init__.py +10 -0
  102. unrealon_driver/driver/utilities/logging.py +51 -0
  103. unrealon_driver/driver/utilities/serialization.py +61 -0
  104. unrealon_driver/managers/__init__.py +32 -0
  105. unrealon_driver/managers/base.py +174 -0
  106. unrealon_driver/managers/browser.py +98 -0
  107. unrealon_driver/managers/cache.py +116 -0
  108. unrealon_driver/managers/http.py +107 -0
  109. unrealon_driver/managers/logger.py +286 -0
  110. unrealon_driver/managers/proxy.py +99 -0
  111. unrealon_driver/managers/registry.py +87 -0
  112. unrealon_driver/managers/threading.py +54 -0
  113. unrealon_driver/managers/update.py +107 -0
  114. unrealon_driver/utils/__init__.py +9 -0
  115. unrealon_driver/utils/time.py +10 -0
  116. unrealon-1.1.6.dist-info/METADATA +0 -625
  117. unrealon-1.1.6.dist-info/RECORD +0 -55
  118. unrealon-1.1.6.dist-info/entry_points.txt +0 -9
  119. unrealon_browser/managers/stealth.py +0 -388
  120. unrealon_driver/README.md +0 -0
  121. unrealon_driver/exceptions.py +0 -33
  122. unrealon_driver/html_analyzer/__init__.py +0 -32
  123. unrealon_driver/html_analyzer/cleaner.py +0 -657
  124. unrealon_driver/html_analyzer/config.py +0 -64
  125. unrealon_driver/html_analyzer/manager.py +0 -247
  126. unrealon_driver/html_analyzer/models.py +0 -115
  127. unrealon_driver/html_analyzer/websocket_analyzer.py +0 -157
  128. unrealon_driver/models/__init__.py +0 -31
  129. unrealon_driver/models/websocket.py +0 -98
  130. unrealon_driver/parser/__init__.py +0 -36
  131. unrealon_driver/parser/cli_manager.py +0 -142
  132. unrealon_driver/parser/daemon_manager.py +0 -403
  133. unrealon_driver/parser/managers/__init__.py +0 -25
  134. unrealon_driver/parser/managers/config.py +0 -293
  135. unrealon_driver/parser/managers/error.py +0 -412
  136. unrealon_driver/parser/managers/result.py +0 -321
  137. unrealon_driver/parser/parser_manager.py +0 -458
  138. unrealon_driver/smart_logging/__init__.py +0 -24
  139. unrealon_driver/smart_logging/models.py +0 -44
  140. unrealon_driver/smart_logging/smart_logger.py +0 -406
  141. unrealon_driver/smart_logging/unified_logger.py +0 -525
  142. unrealon_driver/websocket/__init__.py +0 -31
  143. unrealon_driver/websocket/client.py +0 -249
  144. unrealon_driver/websocket/config.py +0 -188
  145. unrealon_driver/websocket/manager.py +0 -90
@@ -0,0 +1,98 @@
1
+ """
2
+ UnrealOn Core Models
3
+
4
+ All Pydantic models used across the UnrealOn system.
5
+ These models provide strict validation and serialization for:
6
+ - WebSocket communication
7
+ - RPC calls
8
+ - Database operations
9
+ - Configuration management
10
+
11
+ Phase 1: Foundation models with 100% validation coverage
12
+ """
13
+
14
+ from .base import (
15
+ UnrealOnBaseModel,
16
+ TimestampedModel,
17
+ IdentifiedModel,
18
+ StatusModel,
19
+ MetadataModel,
20
+ FullBaseModel,
21
+ SimpleBaseModel
22
+ )
23
+
24
+ from .communication import (
25
+ WebSocketMessage
26
+ )
27
+
28
+ from .driver import (
29
+ DriverInfo,
30
+ DriverConfig,
31
+ DriverCapability
32
+ )
33
+
34
+ from .task import (
35
+ TaskAssignmentData,
36
+ TaskResultData,
37
+ TaskParameters,
38
+ TaskMetadata
39
+ )
40
+
41
+ # Proxy models moved to websocket.proxy
42
+
43
+ from .logging import (
44
+ LogEntry,
45
+ LogQuery,
46
+ LogMetrics
47
+ )
48
+
49
+ from .config import (
50
+ SystemConfig,
51
+ HttpConfig,
52
+ ProxyConfig,
53
+ BrowserConfig,
54
+ LoggingConfig,
55
+ CacheConfig,
56
+ ThreadConfig
57
+ )
58
+
59
+ __all__ = [
60
+ # Base models
61
+ "UnrealOnBaseModel",
62
+ "TimestampedModel",
63
+ "IdentifiedModel",
64
+ "StatusModel",
65
+ "MetadataModel",
66
+ "FullBaseModel",
67
+ "SimpleBaseModel",
68
+
69
+ # Communication models
70
+ "WebSocketMessage",
71
+
72
+ # Driver models
73
+ "DriverInfo",
74
+ "DriverConfig",
75
+ "DriverCapability",
76
+
77
+ # Task models
78
+ "TaskAssignmentData",
79
+ "TaskResultData",
80
+ "TaskParameters",
81
+ "TaskMetadata",
82
+
83
+ # Proxy models moved to websocket.proxy
84
+
85
+ # Logging models
86
+ "LogEntry",
87
+ "LogQuery",
88
+ "LogMetrics",
89
+
90
+ # Configuration models
91
+ "SystemConfig",
92
+ "HttpConfig",
93
+ "ProxyConfig",
94
+ "BrowserConfig",
95
+ "LoggingConfig",
96
+ "CacheConfig",
97
+ "ThreadConfig",
98
+ ]
@@ -0,0 +1,252 @@
1
+ """
2
+ ARQ Context Models
3
+
4
+ Strictly typed models for ARQ worker context and job parameters.
5
+ Following critical requirements - no raw Dict[str, Any].
6
+
7
+ Phase 2: Core Systems - ARQ Context
8
+ """
9
+
10
+ from datetime import datetime
11
+ from typing import Optional
12
+ from pydantic import BaseModel, Field, ConfigDict
13
+
14
+ from .base import UnrealOnBaseModel
15
+
16
+
17
+ class ARQWorkerStats(UnrealOnBaseModel):
18
+ """ARQ worker statistics."""
19
+
20
+ model_config = ConfigDict(
21
+ validate_assignment=True,
22
+ extra="forbid"
23
+ )
24
+
25
+ processed_jobs: int = Field(default=0, description="Number of processed jobs")
26
+ failed_jobs: int = Field(default=0, description="Number of failed jobs")
27
+ start_time: datetime = Field(description="Worker start time")
28
+ websocket_messages_sent: int = Field(default=0, description="WebSocket messages sent")
29
+ websocket_messages_failed: int = Field(default=0, description="Failed WebSocket messages")
30
+
31
+
32
+ class ARQWorkerContext(UnrealOnBaseModel):
33
+ """ARQ worker context with strict typing."""
34
+
35
+ model_config = ConfigDict(
36
+ validate_assignment=True,
37
+ extra="forbid"
38
+ )
39
+
40
+ stats: ARQWorkerStats = Field(description="Worker statistics")
41
+ websocket_bridge: Optional[object] = Field(default=None, description="WebSocket bridge instance")
42
+
43
+
44
+ class TaskAssignmentParams(UnrealOnBaseModel):
45
+ """Parameters for task assignment job."""
46
+
47
+ model_config = ConfigDict(
48
+ validate_assignment=True,
49
+ extra="forbid"
50
+ )
51
+
52
+ task_type: str = Field(description="Type of task")
53
+ task_data: "TaskDataModel" = Field(description="Task data")
54
+ driver_id: Optional[str] = Field(default=None, description="Target driver ID")
55
+ priority: str = Field(default="normal", description="Task priority")
56
+ timeout: float = Field(default=300.0, description="Task timeout in seconds")
57
+ retry_count: int = Field(default=3, description="Number of retries")
58
+
59
+
60
+ class TaskDataModel(UnrealOnBaseModel):
61
+ """Strictly typed task data."""
62
+
63
+ model_config = ConfigDict(
64
+ validate_assignment=True,
65
+ extra="forbid"
66
+ )
67
+
68
+ task_id: str = Field(description="Unique task identifier")
69
+ url: str = Field(description="Target URL")
70
+ parser_type: Optional[str] = Field(default=None, description="Parser type")
71
+ options: Optional["TaskOptionsModel"] = Field(default=None, description="Task options")
72
+
73
+
74
+ class TaskOptionsModel(UnrealOnBaseModel):
75
+ """Task options model."""
76
+
77
+ model_config = ConfigDict(
78
+ validate_assignment=True,
79
+ extra="forbid"
80
+ )
81
+
82
+ timeout_seconds: Optional[float] = Field(default=None, description="Request timeout")
83
+ user_agent: Optional[str] = Field(default=None, description="User agent string")
84
+ headers: Optional["HeadersModel"] = Field(default=None, description="HTTP headers")
85
+ proxy_enabled: bool = Field(default=True, description="Whether to use proxy")
86
+
87
+
88
+ class HeadersModel(UnrealOnBaseModel):
89
+ """HTTP headers model."""
90
+
91
+ model_config = ConfigDict(
92
+ validate_assignment=True,
93
+ extra="forbid"
94
+ )
95
+
96
+ accept: Optional[str] = Field(default=None, description="Accept header")
97
+ accept_language: Optional[str] = Field(default=None, description="Accept-Language header")
98
+ referer: Optional[str] = Field(default=None, description="Referer header")
99
+ authorization: Optional[str] = Field(default=None, description="Authorization header")
100
+
101
+
102
+ class TaskResultParams(UnrealOnBaseModel):
103
+ """Parameters for task result processing."""
104
+
105
+ model_config = ConfigDict(
106
+ validate_assignment=True,
107
+ extra="forbid"
108
+ )
109
+
110
+ driver_id: str = Field(description="Driver ID")
111
+ connection_id: str = Field(description="WebSocket connection ID")
112
+ result_data: "TaskResultDataModel" = Field(description="Task result data")
113
+
114
+
115
+ class TaskResultDataModel(UnrealOnBaseModel):
116
+ """Task result data model."""
117
+
118
+ model_config = ConfigDict(
119
+ validate_assignment=True,
120
+ extra="forbid"
121
+ )
122
+
123
+ task_id: str = Field(description="Task ID")
124
+ status: str = Field(description="Task status")
125
+ result_data: Optional["ParsedDataModel"] = Field(default=None, description="Parsed data")
126
+ error_message: Optional[str] = Field(default=None, description="Error message if failed")
127
+ execution_time_seconds: float = Field(description="Execution time")
128
+
129
+
130
+ class ParsedDataModel(UnrealOnBaseModel):
131
+ """Parsed data model."""
132
+
133
+ model_config = ConfigDict(
134
+ validate_assignment=True,
135
+ extra="forbid"
136
+ )
137
+
138
+ title: Optional[str] = Field(default=None, description="Page title")
139
+ content: Optional[str] = Field(default=None, description="Page content")
140
+ links: Optional[list[str]] = Field(default=None, description="Extracted links")
141
+ images: Optional[list[str]] = Field(default=None, description="Extracted images")
142
+ metadata: Optional["MetadataModel"] = Field(default=None, description="Page metadata")
143
+
144
+
145
+ class MetadataModel(UnrealOnBaseModel):
146
+ """Page metadata model."""
147
+
148
+ model_config = ConfigDict(
149
+ validate_assignment=True,
150
+ extra="forbid"
151
+ )
152
+
153
+ description: Optional[str] = Field(default=None, description="Page description")
154
+ keywords: Optional[str] = Field(default=None, description="Page keywords")
155
+ author: Optional[str] = Field(default=None, description="Page author")
156
+ language: Optional[str] = Field(default=None, description="Page language")
157
+
158
+
159
+ class LogEntryParams(UnrealOnBaseModel):
160
+ """Parameters for log entry processing."""
161
+
162
+ model_config = ConfigDict(
163
+ validate_assignment=True,
164
+ extra="forbid"
165
+ )
166
+
167
+ driver_id: str = Field(description="Driver ID")
168
+ connection_id: str = Field(description="WebSocket connection ID")
169
+ log_data: "LogDataModel" = Field(description="Log data")
170
+
171
+
172
+ class LogDataModel(UnrealOnBaseModel):
173
+ """Log data model."""
174
+
175
+ model_config = ConfigDict(
176
+ validate_assignment=True,
177
+ extra="forbid"
178
+ )
179
+
180
+ level: str = Field(description="Log level")
181
+ message: str = Field(description="Log message")
182
+ logger_name: str = Field(description="Logger name")
183
+ module: str = Field(description="Module name")
184
+ timestamp: datetime = Field(description="Log timestamp")
185
+
186
+
187
+ class DriverRegistrationParams(UnrealOnBaseModel):
188
+ """Parameters for driver registration."""
189
+
190
+ model_config = ConfigDict(
191
+ validate_assignment=True,
192
+ extra="forbid"
193
+ )
194
+
195
+ connection_id: str = Field(description="WebSocket connection ID")
196
+ driver_data: "DriverDataModel" = Field(description="Driver data")
197
+
198
+
199
+ class DriverDataModel(UnrealOnBaseModel):
200
+ """Driver data model."""
201
+
202
+ model_config = ConfigDict(
203
+ validate_assignment=True,
204
+ extra="forbid"
205
+ )
206
+
207
+ driver_id: str = Field(description="Driver ID")
208
+ driver_type: str = Field(description="Driver type")
209
+ version: str = Field(description="Driver version")
210
+ capabilities: list[str] = Field(description="Driver capabilities")
211
+
212
+
213
+ class HeartbeatParams(UnrealOnBaseModel):
214
+ """Parameters for heartbeat processing."""
215
+
216
+ model_config = ConfigDict(
217
+ validate_assignment=True,
218
+ extra="forbid"
219
+ )
220
+
221
+ driver_id: str = Field(description="Driver ID")
222
+ connection_id: str = Field(description="WebSocket connection ID")
223
+ heartbeat_data: "HeartbeatDataModel" = Field(description="Heartbeat data")
224
+
225
+
226
+ class HeartbeatDataModel(UnrealOnBaseModel):
227
+ """Heartbeat data model."""
228
+
229
+ model_config = ConfigDict(
230
+ validate_assignment=True,
231
+ extra="forbid"
232
+ )
233
+
234
+ driver_id: str = Field(description="Driver ID")
235
+ driver_status: str = Field(description="Driver status")
236
+ cpu_usage: float = Field(description="CPU usage percentage")
237
+ memory_usage: float = Field(description="Memory usage in MB")
238
+ active_tasks: int = Field(description="Number of active tasks")
239
+ completed_tasks: int = Field(description="Number of completed tasks")
240
+ failed_tasks: int = Field(description="Number of failed tasks")
241
+
242
+
243
+ # Update forward references
244
+ TaskAssignmentParams.model_rebuild()
245
+ TaskDataModel.model_rebuild()
246
+ TaskOptionsModel.model_rebuild()
247
+ TaskResultParams.model_rebuild()
248
+ TaskResultDataModel.model_rebuild()
249
+ ParsedDataModel.model_rebuild()
250
+ LogEntryParams.model_rebuild()
251
+ DriverRegistrationParams.model_rebuild()
252
+ HeartbeatParams.model_rebuild()
@@ -0,0 +1,125 @@
1
+ """
2
+ ARQ Response Models
3
+
4
+ Strictly typed response models for ARQ job functions.
5
+ Following critical requirements - no raw Dict[str, Any].
6
+
7
+ Phase 2: Core Systems - ARQ Responses
8
+ """
9
+
10
+ from datetime import datetime
11
+ from typing import Optional
12
+ from pydantic import Field, ConfigDict
13
+
14
+ from .base import UnrealOnBaseModel
15
+ from ..utils.time import utc_now
16
+
17
+
18
+ class JobResponseBase(UnrealOnBaseModel):
19
+ """Base response model for ARQ jobs."""
20
+
21
+ model_config = ConfigDict(
22
+ validate_assignment=True,
23
+ extra="forbid"
24
+ )
25
+
26
+ success: bool = Field(description="Whether operation succeeded")
27
+ message: str = Field(description="Response message")
28
+ timestamp: datetime = Field(default_factory=utc_now, description="Response timestamp")
29
+ error_code: Optional[str] = Field(default=None, description="Error code if failed")
30
+
31
+
32
+ class TaskAssignmentResponse(JobResponseBase):
33
+ """Response for task assignment job."""
34
+
35
+ task_id: str = Field(description="Assigned task ID")
36
+ driver_id: str = Field(description="Target driver ID")
37
+ task_type: str = Field(description="Task type")
38
+ priority: str = Field(description="Task priority")
39
+
40
+
41
+ class TaskResultResponse(JobResponseBase):
42
+ """Response for task result processing job."""
43
+
44
+ task_id: str = Field(description="Task ID")
45
+ driver_id: str = Field(description="Driver ID")
46
+ status: str = Field(description="Task status")
47
+ processing_time: Optional[float] = Field(default=None, description="Processing time in seconds")
48
+
49
+
50
+ class LogEntryResponse(JobResponseBase):
51
+ """Response for log entry processing job."""
52
+
53
+ driver_id: str = Field(description="Driver ID")
54
+ level: str = Field(description="Log level")
55
+ entries_processed: int = Field(default=1, description="Number of log entries processed")
56
+
57
+
58
+ class DriverRegistrationResponse(JobResponseBase):
59
+ """Response for driver registration job."""
60
+
61
+ driver_id: str = Field(description="Driver ID")
62
+ driver_type: str = Field(description="Driver type")
63
+ capabilities: list[str] = Field(description="Driver capabilities")
64
+ connection_id: str = Field(description="WebSocket connection ID")
65
+
66
+
67
+ class HeartbeatResponse(JobResponseBase):
68
+ """Response for heartbeat processing job."""
69
+
70
+ driver_id: str = Field(description="Driver ID")
71
+ status: str = Field(description="Driver status")
72
+ is_healthy: bool = Field(description="Whether driver is healthy")
73
+ success_rate: Optional[float] = Field(default=None, description="Driver success rate")
74
+
75
+
76
+ class ConfigurationUpdateResponse(JobResponseBase):
77
+ """Response for configuration update job."""
78
+
79
+ driver_id: str = Field(description="Driver ID")
80
+ configuration_applied: bool = Field(description="Whether configuration was applied")
81
+ restart_required: bool = Field(default=False, description="Whether restart is required")
82
+
83
+
84
+ class PingResponse(JobResponseBase):
85
+ """Response for ping job."""
86
+
87
+ pong_timestamp: datetime = Field(description="Pong timestamp")
88
+ latency_ms: Optional[float] = Field(default=None, description="Latency in milliseconds")
89
+
90
+
91
+ class DriverStatusResponse(JobResponseBase):
92
+ """Response for driver status query."""
93
+
94
+ driver_id: str = Field(description="Driver ID")
95
+ status: str = Field(description="Driver status")
96
+ last_seen: Optional[datetime] = Field(default=None, description="Last seen timestamp")
97
+ active_tasks: int = Field(default=0, description="Number of active tasks")
98
+
99
+
100
+ class DriverListResponse(JobResponseBase):
101
+ """Response for driver list query."""
102
+
103
+ drivers: list["DriverInfo"] = Field(description="List of available drivers")
104
+ total_count: int = Field(description="Total number of drivers")
105
+ filter_applied: Optional[str] = Field(default=None, description="Filter that was applied")
106
+
107
+
108
+ class DriverInfo(UnrealOnBaseModel):
109
+ """Driver information for list response."""
110
+
111
+ model_config = ConfigDict(
112
+ validate_assignment=True,
113
+ extra="forbid"
114
+ )
115
+
116
+ driver_id: str = Field(description="Driver ID")
117
+ driver_type: str = Field(description="Driver type")
118
+ status: str = Field(description="Driver status")
119
+ capabilities: list[str] = Field(description="Driver capabilities")
120
+ last_seen: Optional[datetime] = Field(default=None, description="Last seen timestamp")
121
+ active_tasks: int = Field(default=0, description="Number of active tasks")
122
+
123
+
124
+ # Update forward references
125
+ DriverListResponse.model_rebuild()