claude-mpm 4.0.32__py3-none-any.whl → 4.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- claude_mpm/VERSION +1 -1
- claude_mpm/agents/INSTRUCTIONS.md +70 -2
- claude_mpm/agents/OUTPUT_STYLE.md +0 -11
- claude_mpm/agents/WORKFLOW.md +14 -2
- claude_mpm/agents/templates/documentation.json +51 -34
- claude_mpm/agents/templates/research.json +0 -11
- claude_mpm/cli/__init__.py +111 -33
- claude_mpm/cli/commands/agent_manager.py +10 -8
- claude_mpm/cli/commands/agents.py +82 -0
- claude_mpm/cli/commands/cleanup_orphaned_agents.py +150 -0
- claude_mpm/cli/commands/mcp_pipx_config.py +199 -0
- claude_mpm/cli/parsers/agents_parser.py +27 -0
- claude_mpm/cli/parsers/base_parser.py +6 -0
- claude_mpm/cli/startup_logging.py +75 -0
- claude_mpm/core/framework_loader.py +173 -84
- claude_mpm/dashboard/static/css/dashboard.css +449 -0
- claude_mpm/dashboard/static/dist/components/agent-inference.js +1 -1
- claude_mpm/dashboard/static/dist/components/event-viewer.js +1 -1
- claude_mpm/dashboard/static/dist/components/file-tool-tracker.js +1 -1
- claude_mpm/dashboard/static/dist/components/module-viewer.js +1 -1
- claude_mpm/dashboard/static/dist/components/session-manager.js +1 -1
- claude_mpm/dashboard/static/dist/dashboard.js +1 -1
- claude_mpm/dashboard/static/dist/socket-client.js +1 -1
- claude_mpm/dashboard/static/js/components/agent-hierarchy.js +774 -0
- claude_mpm/dashboard/static/js/components/agent-inference.js +257 -3
- claude_mpm/dashboard/static/js/components/build-tracker.js +323 -0
- claude_mpm/dashboard/static/js/components/event-viewer.js +168 -39
- claude_mpm/dashboard/static/js/components/file-tool-tracker.js +17 -0
- claude_mpm/dashboard/static/js/components/session-manager.js +23 -3
- claude_mpm/dashboard/static/js/components/socket-manager.js +2 -0
- claude_mpm/dashboard/static/js/dashboard.js +207 -31
- claude_mpm/dashboard/static/js/socket-client.js +92 -11
- claude_mpm/dashboard/templates/index.html +1 -0
- claude_mpm/hooks/claude_hooks/connection_pool.py +25 -4
- claude_mpm/hooks/claude_hooks/event_handlers.py +81 -19
- claude_mpm/hooks/claude_hooks/hook_handler.py +125 -163
- claude_mpm/hooks/claude_hooks/hook_handler_eventbus.py +398 -0
- claude_mpm/hooks/claude_hooks/response_tracking.py +10 -0
- claude_mpm/services/agents/deployment/agent_deployment.py +34 -48
- claude_mpm/services/agents/deployment/agent_discovery_service.py +4 -1
- claude_mpm/services/agents/deployment/agent_template_builder.py +20 -11
- claude_mpm/services/agents/deployment/agent_version_manager.py +4 -1
- claude_mpm/services/agents/deployment/agents_directory_resolver.py +10 -25
- claude_mpm/services/agents/deployment/multi_source_deployment_service.py +396 -13
- claude_mpm/services/agents/deployment/pipeline/steps/target_directory_step.py +3 -2
- claude_mpm/services/agents/deployment/strategies/system_strategy.py +10 -3
- claude_mpm/services/agents/deployment/strategies/user_strategy.py +10 -14
- claude_mpm/services/agents/deployment/system_instructions_deployer.py +8 -85
- claude_mpm/services/agents/memory/content_manager.py +98 -105
- claude_mpm/services/event_bus/__init__.py +18 -0
- claude_mpm/services/event_bus/config.py +165 -0
- claude_mpm/services/event_bus/event_bus.py +349 -0
- claude_mpm/services/event_bus/relay.py +297 -0
- claude_mpm/services/events/__init__.py +44 -0
- claude_mpm/services/events/consumers/__init__.py +18 -0
- claude_mpm/services/events/consumers/dead_letter.py +296 -0
- claude_mpm/services/events/consumers/logging.py +183 -0
- claude_mpm/services/events/consumers/metrics.py +242 -0
- claude_mpm/services/events/consumers/socketio.py +376 -0
- claude_mpm/services/events/core.py +470 -0
- claude_mpm/services/events/interfaces.py +230 -0
- claude_mpm/services/events/producers/__init__.py +14 -0
- claude_mpm/services/events/producers/hook.py +269 -0
- claude_mpm/services/events/producers/system.py +327 -0
- claude_mpm/services/mcp_gateway/auto_configure.py +372 -0
- claude_mpm/services/mcp_gateway/core/process_pool.py +411 -0
- claude_mpm/services/mcp_gateway/server/stdio_server.py +13 -0
- claude_mpm/services/monitor_build_service.py +345 -0
- claude_mpm/services/socketio/event_normalizer.py +667 -0
- claude_mpm/services/socketio/handlers/connection.py +81 -23
- claude_mpm/services/socketio/handlers/hook.py +14 -5
- claude_mpm/services/socketio/migration_utils.py +329 -0
- claude_mpm/services/socketio/server/broadcaster.py +26 -33
- claude_mpm/services/socketio/server/core.py +29 -5
- claude_mpm/services/socketio/server/eventbus_integration.py +189 -0
- claude_mpm/services/socketio/server/main.py +25 -0
- {claude_mpm-4.0.32.dist-info → claude_mpm-4.1.0.dist-info}/METADATA +28 -9
- {claude_mpm-4.0.32.dist-info → claude_mpm-4.1.0.dist-info}/RECORD +82 -56
- {claude_mpm-4.0.32.dist-info → claude_mpm-4.1.0.dist-info}/WHEEL +0 -0
- {claude_mpm-4.0.32.dist-info → claude_mpm-4.1.0.dist-info}/entry_points.txt +0 -0
- {claude_mpm-4.0.32.dist-info → claude_mpm-4.1.0.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-4.0.32.dist-info → claude_mpm-4.1.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Event Bus Producers
|
|
3
|
+
==================
|
|
4
|
+
|
|
5
|
+
Various producer implementations for publishing events to the event bus.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from .hook import HookEventProducer
|
|
9
|
+
from .system import SystemEventProducer
|
|
10
|
+
|
|
11
|
+
__all__ = [
|
|
12
|
+
"HookEventProducer",
|
|
13
|
+
"SystemEventProducer",
|
|
14
|
+
]
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Hook Event Producer
|
|
3
|
+
==================
|
|
4
|
+
|
|
5
|
+
Publishes hook system events to the event bus.
|
|
6
|
+
This replaces direct Socket.IO emission in the hook handler.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import uuid
|
|
10
|
+
from datetime import datetime
|
|
11
|
+
from typing import Any, Dict, List, Optional
|
|
12
|
+
|
|
13
|
+
from claude_mpm.core.logging_config import get_logger
|
|
14
|
+
|
|
15
|
+
from ..core import Event, EventPriority
|
|
16
|
+
from ..interfaces import IEventBus, IEventProducer
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class HookEventProducer(IEventProducer):
|
|
20
|
+
"""
|
|
21
|
+
Publishes hook events to the event bus.
|
|
22
|
+
|
|
23
|
+
This producer is used by the hook handler to publish events
|
|
24
|
+
without knowing about Socket.IO or other consumers.
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
def __init__(self, event_bus: IEventBus):
|
|
28
|
+
"""
|
|
29
|
+
Initialize hook event producer.
|
|
30
|
+
|
|
31
|
+
Args:
|
|
32
|
+
event_bus: The event bus to publish to
|
|
33
|
+
"""
|
|
34
|
+
self.logger = get_logger("HookEventProducer")
|
|
35
|
+
self.event_bus = event_bus
|
|
36
|
+
self._source_name = "hook_handler"
|
|
37
|
+
|
|
38
|
+
# Metrics
|
|
39
|
+
self._metrics = {
|
|
40
|
+
"events_published": 0,
|
|
41
|
+
"events_failed": 0,
|
|
42
|
+
"batch_published": 0,
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
async def publish(self, event: Event) -> bool:
|
|
46
|
+
"""Publish a hook event to the bus."""
|
|
47
|
+
try:
|
|
48
|
+
success = await self.event_bus.publish(event)
|
|
49
|
+
|
|
50
|
+
if success:
|
|
51
|
+
self._metrics["events_published"] += 1
|
|
52
|
+
else:
|
|
53
|
+
self._metrics["events_failed"] += 1
|
|
54
|
+
|
|
55
|
+
return success
|
|
56
|
+
|
|
57
|
+
except Exception as e:
|
|
58
|
+
self.logger.error(f"Error publishing hook event: {e}")
|
|
59
|
+
self._metrics["events_failed"] += 1
|
|
60
|
+
return False
|
|
61
|
+
|
|
62
|
+
async def publish_batch(self, events: List[Event]) -> int:
|
|
63
|
+
"""Publish multiple hook events."""
|
|
64
|
+
successful = 0
|
|
65
|
+
|
|
66
|
+
for event in events:
|
|
67
|
+
if await self.publish(event):
|
|
68
|
+
successful += 1
|
|
69
|
+
|
|
70
|
+
self._metrics["batch_published"] += 1
|
|
71
|
+
return successful
|
|
72
|
+
|
|
73
|
+
@property
|
|
74
|
+
def source_name(self) -> str:
|
|
75
|
+
"""Get the name of this event source."""
|
|
76
|
+
return self._source_name
|
|
77
|
+
|
|
78
|
+
# Convenience methods for common hook events
|
|
79
|
+
|
|
80
|
+
async def publish_response(
|
|
81
|
+
self,
|
|
82
|
+
response_data: Dict[str, Any],
|
|
83
|
+
correlation_id: Optional[str] = None,
|
|
84
|
+
) -> bool:
|
|
85
|
+
"""
|
|
86
|
+
Publish an assistant response event.
|
|
87
|
+
|
|
88
|
+
Args:
|
|
89
|
+
response_data: The response data
|
|
90
|
+
correlation_id: Optional correlation ID
|
|
91
|
+
|
|
92
|
+
Returns:
|
|
93
|
+
True if published successfully
|
|
94
|
+
"""
|
|
95
|
+
event = Event(
|
|
96
|
+
id=str(uuid.uuid4()),
|
|
97
|
+
topic="hook.response",
|
|
98
|
+
type="AssistantResponse",
|
|
99
|
+
timestamp=datetime.now(),
|
|
100
|
+
source=self.source_name,
|
|
101
|
+
data=response_data,
|
|
102
|
+
correlation_id=correlation_id,
|
|
103
|
+
priority=EventPriority.HIGH,
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
return await self.publish(event)
|
|
107
|
+
|
|
108
|
+
async def publish_tool_use(
|
|
109
|
+
self,
|
|
110
|
+
tool_name: str,
|
|
111
|
+
tool_params: Dict[str, Any],
|
|
112
|
+
tool_result: Optional[Any] = None,
|
|
113
|
+
correlation_id: Optional[str] = None,
|
|
114
|
+
) -> bool:
|
|
115
|
+
"""
|
|
116
|
+
Publish a tool usage event.
|
|
117
|
+
|
|
118
|
+
Args:
|
|
119
|
+
tool_name: Name of the tool used
|
|
120
|
+
tool_params: Parameters passed to the tool
|
|
121
|
+
tool_result: Optional tool result
|
|
122
|
+
correlation_id: Optional correlation ID
|
|
123
|
+
|
|
124
|
+
Returns:
|
|
125
|
+
True if published successfully
|
|
126
|
+
"""
|
|
127
|
+
event = Event(
|
|
128
|
+
id=str(uuid.uuid4()),
|
|
129
|
+
topic="hook.tool",
|
|
130
|
+
type="ToolUse",
|
|
131
|
+
timestamp=datetime.now(),
|
|
132
|
+
source=self.source_name,
|
|
133
|
+
data={
|
|
134
|
+
"tool": tool_name,
|
|
135
|
+
"params": tool_params,
|
|
136
|
+
"result": tool_result,
|
|
137
|
+
},
|
|
138
|
+
correlation_id=correlation_id,
|
|
139
|
+
priority=EventPriority.NORMAL,
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
return await self.publish(event)
|
|
143
|
+
|
|
144
|
+
async def publish_error(
|
|
145
|
+
self,
|
|
146
|
+
error_type: str,
|
|
147
|
+
error_message: str,
|
|
148
|
+
error_details: Optional[Dict[str, Any]] = None,
|
|
149
|
+
correlation_id: Optional[str] = None,
|
|
150
|
+
) -> bool:
|
|
151
|
+
"""
|
|
152
|
+
Publish an error event.
|
|
153
|
+
|
|
154
|
+
Args:
|
|
155
|
+
error_type: Type of error
|
|
156
|
+
error_message: Error message
|
|
157
|
+
error_details: Optional additional details
|
|
158
|
+
correlation_id: Optional correlation ID
|
|
159
|
+
|
|
160
|
+
Returns:
|
|
161
|
+
True if published successfully
|
|
162
|
+
"""
|
|
163
|
+
event = Event(
|
|
164
|
+
id=str(uuid.uuid4()),
|
|
165
|
+
topic="hook.error",
|
|
166
|
+
type="Error",
|
|
167
|
+
timestamp=datetime.now(),
|
|
168
|
+
source=self.source_name,
|
|
169
|
+
data={
|
|
170
|
+
"error_type": error_type,
|
|
171
|
+
"message": error_message,
|
|
172
|
+
"details": error_details or {},
|
|
173
|
+
},
|
|
174
|
+
correlation_id=correlation_id,
|
|
175
|
+
priority=EventPriority.CRITICAL,
|
|
176
|
+
)
|
|
177
|
+
|
|
178
|
+
return await self.publish(event)
|
|
179
|
+
|
|
180
|
+
async def publish_subagent_event(
|
|
181
|
+
self,
|
|
182
|
+
subagent_name: str,
|
|
183
|
+
event_type: str,
|
|
184
|
+
event_data: Dict[str, Any],
|
|
185
|
+
correlation_id: Optional[str] = None,
|
|
186
|
+
) -> bool:
|
|
187
|
+
"""
|
|
188
|
+
Publish a subagent-related event.
|
|
189
|
+
|
|
190
|
+
Args:
|
|
191
|
+
subagent_name: Name of the subagent
|
|
192
|
+
event_type: Type of subagent event
|
|
193
|
+
event_data: Event data
|
|
194
|
+
correlation_id: Optional correlation ID
|
|
195
|
+
|
|
196
|
+
Returns:
|
|
197
|
+
True if published successfully
|
|
198
|
+
"""
|
|
199
|
+
event = Event(
|
|
200
|
+
id=str(uuid.uuid4()),
|
|
201
|
+
topic=f"hook.subagent.{event_type.lower()}",
|
|
202
|
+
type=f"Subagent{event_type}",
|
|
203
|
+
timestamp=datetime.now(),
|
|
204
|
+
source=self.source_name,
|
|
205
|
+
data={
|
|
206
|
+
"subagent": subagent_name,
|
|
207
|
+
**event_data,
|
|
208
|
+
},
|
|
209
|
+
correlation_id=correlation_id,
|
|
210
|
+
priority=EventPriority.NORMAL,
|
|
211
|
+
)
|
|
212
|
+
|
|
213
|
+
return await self.publish(event)
|
|
214
|
+
|
|
215
|
+
async def publish_raw_hook_event(
|
|
216
|
+
self,
|
|
217
|
+
hook_type: str,
|
|
218
|
+
hook_data: Dict[str, Any],
|
|
219
|
+
correlation_id: Optional[str] = None,
|
|
220
|
+
) -> bool:
|
|
221
|
+
"""
|
|
222
|
+
Publish a raw hook event.
|
|
223
|
+
|
|
224
|
+
This is for hook events that don't fit the standard patterns.
|
|
225
|
+
|
|
226
|
+
Args:
|
|
227
|
+
hook_type: Type of hook event
|
|
228
|
+
hook_data: Raw hook data
|
|
229
|
+
correlation_id: Optional correlation ID
|
|
230
|
+
|
|
231
|
+
Returns:
|
|
232
|
+
True if published successfully
|
|
233
|
+
"""
|
|
234
|
+
# Determine topic based on hook type
|
|
235
|
+
if "response" in hook_type.lower():
|
|
236
|
+
topic = "hook.response"
|
|
237
|
+
elif "tool" in hook_type.lower():
|
|
238
|
+
topic = "hook.tool"
|
|
239
|
+
elif "error" in hook_type.lower():
|
|
240
|
+
topic = "hook.error"
|
|
241
|
+
elif "subagent" in hook_type.lower():
|
|
242
|
+
topic = "hook.subagent"
|
|
243
|
+
else:
|
|
244
|
+
topic = "hook.generic"
|
|
245
|
+
|
|
246
|
+
# Determine priority
|
|
247
|
+
if "error" in hook_type.lower() or "critical" in hook_type.lower():
|
|
248
|
+
priority = EventPriority.CRITICAL
|
|
249
|
+
elif "response" in hook_type.lower():
|
|
250
|
+
priority = EventPriority.HIGH
|
|
251
|
+
else:
|
|
252
|
+
priority = EventPriority.NORMAL
|
|
253
|
+
|
|
254
|
+
event = Event(
|
|
255
|
+
id=str(uuid.uuid4()),
|
|
256
|
+
topic=topic,
|
|
257
|
+
type=hook_type,
|
|
258
|
+
timestamp=datetime.now(),
|
|
259
|
+
source=self.source_name,
|
|
260
|
+
data=hook_data,
|
|
261
|
+
correlation_id=correlation_id,
|
|
262
|
+
priority=priority,
|
|
263
|
+
)
|
|
264
|
+
|
|
265
|
+
return await self.publish(event)
|
|
266
|
+
|
|
267
|
+
def get_metrics(self) -> Dict[str, Any]:
|
|
268
|
+
"""Get producer metrics."""
|
|
269
|
+
return self._metrics
|
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
"""
|
|
2
|
+
System Event Producer
|
|
3
|
+
====================
|
|
4
|
+
|
|
5
|
+
Publishes system-level events to the event bus.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import uuid
|
|
9
|
+
from datetime import datetime
|
|
10
|
+
from typing import Any, Dict, List, Optional
|
|
11
|
+
|
|
12
|
+
from claude_mpm.core.logging_config import get_logger
|
|
13
|
+
|
|
14
|
+
from ..core import Event, EventPriority
|
|
15
|
+
from ..interfaces import IEventBus, IEventProducer
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class SystemEventProducer(IEventProducer):
|
|
19
|
+
"""
|
|
20
|
+
Publishes system events to the event bus.
|
|
21
|
+
|
|
22
|
+
Used for:
|
|
23
|
+
- Service lifecycle events
|
|
24
|
+
- Configuration changes
|
|
25
|
+
- Health status updates
|
|
26
|
+
- Performance metrics
|
|
27
|
+
- System errors
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
def __init__(self, event_bus: IEventBus, source_name: str = "system"):
|
|
31
|
+
"""
|
|
32
|
+
Initialize system event producer.
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
event_bus: The event bus to publish to
|
|
36
|
+
source_name: Name of the system component
|
|
37
|
+
"""
|
|
38
|
+
self.logger = get_logger("SystemEventProducer")
|
|
39
|
+
self.event_bus = event_bus
|
|
40
|
+
self._source_name = source_name
|
|
41
|
+
|
|
42
|
+
# Metrics
|
|
43
|
+
self._metrics = {
|
|
44
|
+
"events_published": 0,
|
|
45
|
+
"events_failed": 0,
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
async def publish(self, event: Event) -> bool:
|
|
49
|
+
"""Publish a system event to the bus."""
|
|
50
|
+
try:
|
|
51
|
+
success = await self.event_bus.publish(event)
|
|
52
|
+
|
|
53
|
+
if success:
|
|
54
|
+
self._metrics["events_published"] += 1
|
|
55
|
+
else:
|
|
56
|
+
self._metrics["events_failed"] += 1
|
|
57
|
+
|
|
58
|
+
return success
|
|
59
|
+
|
|
60
|
+
except Exception as e:
|
|
61
|
+
self.logger.error(f"Error publishing system event: {e}")
|
|
62
|
+
self._metrics["events_failed"] += 1
|
|
63
|
+
return False
|
|
64
|
+
|
|
65
|
+
async def publish_batch(self, events: List[Event]) -> int:
|
|
66
|
+
"""Publish multiple system events."""
|
|
67
|
+
successful = 0
|
|
68
|
+
|
|
69
|
+
for event in events:
|
|
70
|
+
if await self.publish(event):
|
|
71
|
+
successful += 1
|
|
72
|
+
|
|
73
|
+
return successful
|
|
74
|
+
|
|
75
|
+
@property
|
|
76
|
+
def source_name(self) -> str:
|
|
77
|
+
"""Get the name of this event source."""
|
|
78
|
+
return self._source_name
|
|
79
|
+
|
|
80
|
+
# Convenience methods for common system events
|
|
81
|
+
|
|
82
|
+
async def publish_startup(
|
|
83
|
+
self,
|
|
84
|
+
service_name: str,
|
|
85
|
+
version: str,
|
|
86
|
+
config: Optional[Dict[str, Any]] = None,
|
|
87
|
+
) -> bool:
|
|
88
|
+
"""
|
|
89
|
+
Publish a service startup event.
|
|
90
|
+
|
|
91
|
+
Args:
|
|
92
|
+
service_name: Name of the service
|
|
93
|
+
version: Service version
|
|
94
|
+
config: Optional configuration data
|
|
95
|
+
|
|
96
|
+
Returns:
|
|
97
|
+
True if published successfully
|
|
98
|
+
"""
|
|
99
|
+
event = Event(
|
|
100
|
+
id=str(uuid.uuid4()),
|
|
101
|
+
topic="system.lifecycle.startup",
|
|
102
|
+
type="ServiceStartup",
|
|
103
|
+
timestamp=datetime.now(),
|
|
104
|
+
source=self.source_name,
|
|
105
|
+
data={
|
|
106
|
+
"service": service_name,
|
|
107
|
+
"version": version,
|
|
108
|
+
"config": config or {},
|
|
109
|
+
},
|
|
110
|
+
priority=EventPriority.HIGH,
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
return await self.publish(event)
|
|
114
|
+
|
|
115
|
+
async def publish_shutdown(
|
|
116
|
+
self,
|
|
117
|
+
service_name: str,
|
|
118
|
+
reason: str = "normal",
|
|
119
|
+
details: Optional[Dict[str, Any]] = None,
|
|
120
|
+
) -> bool:
|
|
121
|
+
"""
|
|
122
|
+
Publish a service shutdown event.
|
|
123
|
+
|
|
124
|
+
Args:
|
|
125
|
+
service_name: Name of the service
|
|
126
|
+
reason: Shutdown reason
|
|
127
|
+
details: Optional additional details
|
|
128
|
+
|
|
129
|
+
Returns:
|
|
130
|
+
True if published successfully
|
|
131
|
+
"""
|
|
132
|
+
event = Event(
|
|
133
|
+
id=str(uuid.uuid4()),
|
|
134
|
+
topic="system.lifecycle.shutdown",
|
|
135
|
+
type="ServiceShutdown",
|
|
136
|
+
timestamp=datetime.now(),
|
|
137
|
+
source=self.source_name,
|
|
138
|
+
data={
|
|
139
|
+
"service": service_name,
|
|
140
|
+
"reason": reason,
|
|
141
|
+
"details": details or {},
|
|
142
|
+
},
|
|
143
|
+
priority=EventPriority.HIGH,
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
return await self.publish(event)
|
|
147
|
+
|
|
148
|
+
async def publish_health_status(
|
|
149
|
+
self,
|
|
150
|
+
service_name: str,
|
|
151
|
+
status: str,
|
|
152
|
+
checks: Dict[str, bool],
|
|
153
|
+
details: Optional[Dict[str, Any]] = None,
|
|
154
|
+
) -> bool:
|
|
155
|
+
"""
|
|
156
|
+
Publish a health status event.
|
|
157
|
+
|
|
158
|
+
Args:
|
|
159
|
+
service_name: Name of the service
|
|
160
|
+
status: Health status (healthy, degraded, unhealthy)
|
|
161
|
+
checks: Individual health checks
|
|
162
|
+
details: Optional additional details
|
|
163
|
+
|
|
164
|
+
Returns:
|
|
165
|
+
True if published successfully
|
|
166
|
+
"""
|
|
167
|
+
event = Event(
|
|
168
|
+
id=str(uuid.uuid4()),
|
|
169
|
+
topic="system.health",
|
|
170
|
+
type="HealthStatus",
|
|
171
|
+
timestamp=datetime.now(),
|
|
172
|
+
source=self.source_name,
|
|
173
|
+
data={
|
|
174
|
+
"service": service_name,
|
|
175
|
+
"status": status,
|
|
176
|
+
"checks": checks,
|
|
177
|
+
"details": details or {},
|
|
178
|
+
},
|
|
179
|
+
priority=EventPriority.NORMAL if status == "healthy" else EventPriority.HIGH,
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
return await self.publish(event)
|
|
183
|
+
|
|
184
|
+
async def publish_config_change(
|
|
185
|
+
self,
|
|
186
|
+
service_name: str,
|
|
187
|
+
config_key: str,
|
|
188
|
+
old_value: Any,
|
|
189
|
+
new_value: Any,
|
|
190
|
+
) -> bool:
|
|
191
|
+
"""
|
|
192
|
+
Publish a configuration change event.
|
|
193
|
+
|
|
194
|
+
Args:
|
|
195
|
+
service_name: Name of the service
|
|
196
|
+
config_key: Configuration key that changed
|
|
197
|
+
old_value: Previous value
|
|
198
|
+
new_value: New value
|
|
199
|
+
|
|
200
|
+
Returns:
|
|
201
|
+
True if published successfully
|
|
202
|
+
"""
|
|
203
|
+
event = Event(
|
|
204
|
+
id=str(uuid.uuid4()),
|
|
205
|
+
topic="system.config",
|
|
206
|
+
type="ConfigChange",
|
|
207
|
+
timestamp=datetime.now(),
|
|
208
|
+
source=self.source_name,
|
|
209
|
+
data={
|
|
210
|
+
"service": service_name,
|
|
211
|
+
"key": config_key,
|
|
212
|
+
"old_value": old_value,
|
|
213
|
+
"new_value": new_value,
|
|
214
|
+
},
|
|
215
|
+
priority=EventPriority.NORMAL,
|
|
216
|
+
)
|
|
217
|
+
|
|
218
|
+
return await self.publish(event)
|
|
219
|
+
|
|
220
|
+
async def publish_performance_metrics(
|
|
221
|
+
self,
|
|
222
|
+
service_name: str,
|
|
223
|
+
metrics: Dict[str, Any],
|
|
224
|
+
) -> bool:
|
|
225
|
+
"""
|
|
226
|
+
Publish performance metrics.
|
|
227
|
+
|
|
228
|
+
Args:
|
|
229
|
+
service_name: Name of the service
|
|
230
|
+
metrics: Performance metrics data
|
|
231
|
+
|
|
232
|
+
Returns:
|
|
233
|
+
True if published successfully
|
|
234
|
+
"""
|
|
235
|
+
event = Event(
|
|
236
|
+
id=str(uuid.uuid4()),
|
|
237
|
+
topic="system.performance",
|
|
238
|
+
type="PerformanceMetrics",
|
|
239
|
+
timestamp=datetime.now(),
|
|
240
|
+
source=self.source_name,
|
|
241
|
+
data={
|
|
242
|
+
"service": service_name,
|
|
243
|
+
"metrics": metrics,
|
|
244
|
+
},
|
|
245
|
+
priority=EventPriority.LOW,
|
|
246
|
+
)
|
|
247
|
+
|
|
248
|
+
return await self.publish(event)
|
|
249
|
+
|
|
250
|
+
async def publish_error(
|
|
251
|
+
self,
|
|
252
|
+
service_name: str,
|
|
253
|
+
error_type: str,
|
|
254
|
+
error_message: str,
|
|
255
|
+
stacktrace: Optional[str] = None,
|
|
256
|
+
context: Optional[Dict[str, Any]] = None,
|
|
257
|
+
) -> bool:
|
|
258
|
+
"""
|
|
259
|
+
Publish a system error event.
|
|
260
|
+
|
|
261
|
+
Args:
|
|
262
|
+
service_name: Name of the service
|
|
263
|
+
error_type: Type of error
|
|
264
|
+
error_message: Error message
|
|
265
|
+
stacktrace: Optional stack trace
|
|
266
|
+
context: Optional error context
|
|
267
|
+
|
|
268
|
+
Returns:
|
|
269
|
+
True if published successfully
|
|
270
|
+
"""
|
|
271
|
+
event = Event(
|
|
272
|
+
id=str(uuid.uuid4()),
|
|
273
|
+
topic="system.error",
|
|
274
|
+
type="SystemError",
|
|
275
|
+
timestamp=datetime.now(),
|
|
276
|
+
source=self.source_name,
|
|
277
|
+
data={
|
|
278
|
+
"service": service_name,
|
|
279
|
+
"error_type": error_type,
|
|
280
|
+
"message": error_message,
|
|
281
|
+
"stacktrace": stacktrace,
|
|
282
|
+
"context": context or {},
|
|
283
|
+
},
|
|
284
|
+
priority=EventPriority.CRITICAL,
|
|
285
|
+
)
|
|
286
|
+
|
|
287
|
+
return await self.publish(event)
|
|
288
|
+
|
|
289
|
+
async def publish_warning(
|
|
290
|
+
self,
|
|
291
|
+
service_name: str,
|
|
292
|
+
warning_type: str,
|
|
293
|
+
message: str,
|
|
294
|
+
details: Optional[Dict[str, Any]] = None,
|
|
295
|
+
) -> bool:
|
|
296
|
+
"""
|
|
297
|
+
Publish a system warning event.
|
|
298
|
+
|
|
299
|
+
Args:
|
|
300
|
+
service_name: Name of the service
|
|
301
|
+
warning_type: Type of warning
|
|
302
|
+
message: Warning message
|
|
303
|
+
details: Optional additional details
|
|
304
|
+
|
|
305
|
+
Returns:
|
|
306
|
+
True if published successfully
|
|
307
|
+
"""
|
|
308
|
+
event = Event(
|
|
309
|
+
id=str(uuid.uuid4()),
|
|
310
|
+
topic="system.warning",
|
|
311
|
+
type="SystemWarning",
|
|
312
|
+
timestamp=datetime.now(),
|
|
313
|
+
source=self.source_name,
|
|
314
|
+
data={
|
|
315
|
+
"service": service_name,
|
|
316
|
+
"warning_type": warning_type,
|
|
317
|
+
"message": message,
|
|
318
|
+
"details": details or {},
|
|
319
|
+
},
|
|
320
|
+
priority=EventPriority.HIGH,
|
|
321
|
+
)
|
|
322
|
+
|
|
323
|
+
return await self.publish(event)
|
|
324
|
+
|
|
325
|
+
def get_metrics(self) -> Dict[str, Any]:
|
|
326
|
+
"""Get producer metrics."""
|
|
327
|
+
return self._metrics
|