agent_os_kernel 3.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.
Files changed (337) hide show
  1. agent_control_plane/__init__.py +662 -0
  2. agent_control_plane/a2a_adapter.py +543 -0
  3. agent_control_plane/adapter.py +417 -0
  4. agent_control_plane/agent_hibernation.py +394 -0
  5. agent_control_plane/agent_kernel.py +470 -0
  6. agent_control_plane/compliance.py +720 -0
  7. agent_control_plane/constraint_graphs.py +478 -0
  8. agent_control_plane/control_plane.py +854 -0
  9. agent_control_plane/example_executors.py +195 -0
  10. agent_control_plane/execution_engine.py +231 -0
  11. agent_control_plane/flight_recorder.py +846 -0
  12. agent_control_plane/governance_layer.py +435 -0
  13. agent_control_plane/hf_utils.py +563 -0
  14. agent_control_plane/interfaces/__init__.py +55 -0
  15. agent_control_plane/interfaces/kernel_interface.py +361 -0
  16. agent_control_plane/interfaces/plugin_interface.py +497 -0
  17. agent_control_plane/interfaces/protocol_interfaces.py +387 -0
  18. agent_control_plane/kernel_space.py +1009 -0
  19. agent_control_plane/langchain_adapter.py +424 -0
  20. agent_control_plane/lifecycle.py +3113 -0
  21. agent_control_plane/mcp_adapter.py +653 -0
  22. agent_control_plane/ml_safety.py +563 -0
  23. agent_control_plane/multimodal.py +727 -0
  24. agent_control_plane/mute_agent.py +422 -0
  25. agent_control_plane/observability.py +787 -0
  26. agent_control_plane/orchestrator.py +482 -0
  27. agent_control_plane/plugin_registry.py +750 -0
  28. agent_control_plane/policy_engine.py +954 -0
  29. agent_control_plane/process_isolation.py +777 -0
  30. agent_control_plane/shadow_mode.py +310 -0
  31. agent_control_plane/signals.py +493 -0
  32. agent_control_plane/supervisor_agents.py +430 -0
  33. agent_control_plane/time_travel_debugger.py +557 -0
  34. agent_control_plane/tool_registry.py +452 -0
  35. agent_control_plane/vfs.py +697 -0
  36. agent_kernel/__init__.py +69 -0
  37. agent_kernel/analyzer.py +435 -0
  38. agent_kernel/auditor.py +36 -0
  39. agent_kernel/completeness_auditor.py +237 -0
  40. agent_kernel/detector.py +203 -0
  41. agent_kernel/kernel.py +744 -0
  42. agent_kernel/memory_manager.py +85 -0
  43. agent_kernel/models.py +374 -0
  44. agent_kernel/nudge_mechanism.py +263 -0
  45. agent_kernel/outcome_analyzer.py +338 -0
  46. agent_kernel/patcher.py +582 -0
  47. agent_kernel/semantic_analyzer.py +316 -0
  48. agent_kernel/semantic_purge.py +349 -0
  49. agent_kernel/simulator.py +449 -0
  50. agent_kernel/teacher.py +85 -0
  51. agent_kernel/triage.py +152 -0
  52. agent_os/__init__.py +409 -0
  53. agent_os/_adversarial_impl.py +200 -0
  54. agent_os/_circuit_breaker_impl.py +232 -0
  55. agent_os/_mcp_metrics.py +193 -0
  56. agent_os/adversarial.py +20 -0
  57. agent_os/agents_compat.py +490 -0
  58. agent_os/audit_logger.py +135 -0
  59. agent_os/base_agent.py +651 -0
  60. agent_os/circuit_breaker.py +34 -0
  61. agent_os/cli/__init__.py +659 -0
  62. agent_os/cli/cmd_audit.py +128 -0
  63. agent_os/cli/cmd_init.py +152 -0
  64. agent_os/cli/cmd_policy.py +41 -0
  65. agent_os/cli/cmd_policy_gen.py +180 -0
  66. agent_os/cli/cmd_validate.py +258 -0
  67. agent_os/cli/mcp_scan.py +265 -0
  68. agent_os/cli/output.py +192 -0
  69. agent_os/cli/policy_checker.py +330 -0
  70. agent_os/compat.py +74 -0
  71. agent_os/constraint_graph.py +234 -0
  72. agent_os/content_governance.py +140 -0
  73. agent_os/context_budget.py +305 -0
  74. agent_os/credential_redactor.py +224 -0
  75. agent_os/diff_policy.py +89 -0
  76. agent_os/egress_policy.py +159 -0
  77. agent_os/escalation.py +276 -0
  78. agent_os/event_bus.py +124 -0
  79. agent_os/exceptions.py +180 -0
  80. agent_os/execution_context_policy.py +141 -0
  81. agent_os/github_enterprise.py +96 -0
  82. agent_os/health.py +20 -0
  83. agent_os/integrations/__init__.py +279 -0
  84. agent_os/integrations/a2a_adapter.py +279 -0
  85. agent_os/integrations/agent_lightning/__init__.py +30 -0
  86. agent_os/integrations/anthropic_adapter.py +420 -0
  87. agent_os/integrations/autogen_adapter.py +620 -0
  88. agent_os/integrations/base.py +1137 -0
  89. agent_os/integrations/compat.py +229 -0
  90. agent_os/integrations/config.py +98 -0
  91. agent_os/integrations/conversation_guardian.py +957 -0
  92. agent_os/integrations/crewai_adapter.py +467 -0
  93. agent_os/integrations/drift_detector.py +425 -0
  94. agent_os/integrations/dry_run.py +124 -0
  95. agent_os/integrations/escalation.py +582 -0
  96. agent_os/integrations/gemini_adapter.py +364 -0
  97. agent_os/integrations/google_adk_adapter.py +633 -0
  98. agent_os/integrations/guardrails_adapter.py +394 -0
  99. agent_os/integrations/health.py +197 -0
  100. agent_os/integrations/langchain_adapter.py +654 -0
  101. agent_os/integrations/llamafirewall.py +343 -0
  102. agent_os/integrations/llamaindex_adapter.py +188 -0
  103. agent_os/integrations/logging.py +191 -0
  104. agent_os/integrations/maf_adapter.py +631 -0
  105. agent_os/integrations/mistral_adapter.py +365 -0
  106. agent_os/integrations/openai_adapter.py +816 -0
  107. agent_os/integrations/openai_agents_sdk.py +406 -0
  108. agent_os/integrations/policy_compose.py +171 -0
  109. agent_os/integrations/profiling.py +144 -0
  110. agent_os/integrations/pydantic_ai_adapter.py +420 -0
  111. agent_os/integrations/rate_limiter.py +130 -0
  112. agent_os/integrations/rbac.py +143 -0
  113. agent_os/integrations/registry.py +113 -0
  114. agent_os/integrations/scope_guard.py +303 -0
  115. agent_os/integrations/semantic_kernel_adapter.py +769 -0
  116. agent_os/integrations/smolagents_adapter.py +629 -0
  117. agent_os/integrations/templates.py +178 -0
  118. agent_os/integrations/token_budget.py +134 -0
  119. agent_os/integrations/tool_aliases.py +190 -0
  120. agent_os/integrations/webhooks.py +177 -0
  121. agent_os/lite.py +208 -0
  122. agent_os/mcp_gateway.py +385 -0
  123. agent_os/mcp_message_signer.py +273 -0
  124. agent_os/mcp_protocols.py +161 -0
  125. agent_os/mcp_response_scanner.py +232 -0
  126. agent_os/mcp_security.py +924 -0
  127. agent_os/mcp_session_auth.py +231 -0
  128. agent_os/mcp_sliding_rate_limiter.py +184 -0
  129. agent_os/memory_guard.py +409 -0
  130. agent_os/metrics.py +134 -0
  131. agent_os/mute.py +428 -0
  132. agent_os/mute_agent.py +209 -0
  133. agent_os/policies/__init__.py +77 -0
  134. agent_os/policies/async_evaluator.py +275 -0
  135. agent_os/policies/backends.py +670 -0
  136. agent_os/policies/bridge.py +169 -0
  137. agent_os/policies/budget.py +85 -0
  138. agent_os/policies/cli.py +294 -0
  139. agent_os/policies/conflict_resolution.py +270 -0
  140. agent_os/policies/data_classification.py +252 -0
  141. agent_os/policies/evaluator.py +239 -0
  142. agent_os/policies/policy_schema.json +228 -0
  143. agent_os/policies/rate_limiting.py +145 -0
  144. agent_os/policies/schema.py +115 -0
  145. agent_os/policies/shared.py +331 -0
  146. agent_os/prompt_injection.py +694 -0
  147. agent_os/providers.py +182 -0
  148. agent_os/py.typed +0 -0
  149. agent_os/retry.py +81 -0
  150. agent_os/reversibility.py +251 -0
  151. agent_os/sandbox.py +432 -0
  152. agent_os/sandbox_provider.py +140 -0
  153. agent_os/secure_codegen.py +525 -0
  154. agent_os/security_skills.py +538 -0
  155. agent_os/semantic_policy.py +422 -0
  156. agent_os/server/__init__.py +15 -0
  157. agent_os/server/__main__.py +25 -0
  158. agent_os/server/app.py +277 -0
  159. agent_os/server/models.py +104 -0
  160. agent_os/shift_left_metrics.py +130 -0
  161. agent_os/stateless.py +742 -0
  162. agent_os/supervisor.py +148 -0
  163. agent_os/task_outcome.py +148 -0
  164. agent_os/transparency.py +181 -0
  165. agent_os/trust_root.py +128 -0
  166. agent_os_kernel-3.1.0.dist-info/METADATA +1269 -0
  167. agent_os_kernel-3.1.0.dist-info/RECORD +337 -0
  168. agent_os_kernel-3.1.0.dist-info/WHEEL +4 -0
  169. agent_os_kernel-3.1.0.dist-info/entry_points.txt +2 -0
  170. agent_os_kernel-3.1.0.dist-info/licenses/LICENSE +21 -0
  171. agent_os_observability/__init__.py +27 -0
  172. agent_os_observability/dashboards.py +898 -0
  173. agent_os_observability/metrics.py +398 -0
  174. agent_os_observability/server.py +223 -0
  175. agent_os_observability/tracer.py +232 -0
  176. agent_primitives/__init__.py +24 -0
  177. agent_primitives/failures.py +84 -0
  178. agent_primitives/py.typed +0 -0
  179. amb_core/__init__.py +177 -0
  180. amb_core/adapters/__init__.py +57 -0
  181. amb_core/adapters/aws_sqs_broker.py +376 -0
  182. amb_core/adapters/azure_servicebus_broker.py +340 -0
  183. amb_core/adapters/kafka_broker.py +260 -0
  184. amb_core/adapters/nats_broker.py +285 -0
  185. amb_core/adapters/rabbitmq_broker.py +235 -0
  186. amb_core/adapters/redis_broker.py +262 -0
  187. amb_core/broker.py +145 -0
  188. amb_core/bus.py +481 -0
  189. amb_core/cloudevents.py +509 -0
  190. amb_core/dlq.py +345 -0
  191. amb_core/hf_utils.py +536 -0
  192. amb_core/memory_broker.py +410 -0
  193. amb_core/models.py +141 -0
  194. amb_core/persistence.py +529 -0
  195. amb_core/schema.py +294 -0
  196. amb_core/tracing.py +358 -0
  197. atr/__init__.py +640 -0
  198. atr/access.py +348 -0
  199. atr/composition.py +645 -0
  200. atr/decorator.py +357 -0
  201. atr/executor.py +384 -0
  202. atr/health.py +557 -0
  203. atr/hf_utils.py +449 -0
  204. atr/injection.py +422 -0
  205. atr/metrics.py +440 -0
  206. atr/policies.py +403 -0
  207. atr/py.typed +2 -0
  208. atr/registry.py +452 -0
  209. atr/schema.py +480 -0
  210. atr/tools/safe/__init__.py +75 -0
  211. atr/tools/safe/calculator.py +467 -0
  212. atr/tools/safe/datetime_tool.py +443 -0
  213. atr/tools/safe/file_reader.py +402 -0
  214. atr/tools/safe/http_client.py +316 -0
  215. atr/tools/safe/json_parser.py +374 -0
  216. atr/tools/safe/text_tool.py +537 -0
  217. atr/tools/safe/toolkit.py +175 -0
  218. caas/__init__.py +162 -0
  219. caas/api/__init__.py +7 -0
  220. caas/api/server.py +1328 -0
  221. caas/caching.py +834 -0
  222. caas/cli.py +210 -0
  223. caas/conversation.py +223 -0
  224. caas/decay.py +72 -0
  225. caas/detection/__init__.py +9 -0
  226. caas/detection/detector.py +238 -0
  227. caas/enrichment.py +130 -0
  228. caas/gateway/__init__.py +27 -0
  229. caas/gateway/trust_gateway.py +474 -0
  230. caas/hf_utils.py +479 -0
  231. caas/ingestion/__init__.py +23 -0
  232. caas/ingestion/processors.py +253 -0
  233. caas/ingestion/structure_parser.py +188 -0
  234. caas/models.py +356 -0
  235. caas/pragmatic_truth.py +444 -0
  236. caas/routing/__init__.py +10 -0
  237. caas/routing/heuristic_router.py +58 -0
  238. caas/storage/__init__.py +9 -0
  239. caas/storage/store.py +389 -0
  240. caas/triad.py +213 -0
  241. caas/tuning/__init__.py +9 -0
  242. caas/tuning/tuner.py +329 -0
  243. caas/vfs/__init__.py +14 -0
  244. caas/vfs/filesystem.py +452 -0
  245. cmvk/__init__.py +218 -0
  246. cmvk/audit.py +402 -0
  247. cmvk/benchmarks.py +478 -0
  248. cmvk/constitutional.py +904 -0
  249. cmvk/hf_utils.py +301 -0
  250. cmvk/metrics.py +473 -0
  251. cmvk/profiles.py +300 -0
  252. cmvk/py.typed +0 -0
  253. cmvk/types.py +12 -0
  254. cmvk/verification.py +956 -0
  255. emk/__init__.py +89 -0
  256. emk/causal.py +352 -0
  257. emk/hf_utils.py +421 -0
  258. emk/indexer.py +83 -0
  259. emk/py.typed +0 -0
  260. emk/schema.py +204 -0
  261. emk/sleep_cycle.py +347 -0
  262. emk/store.py +281 -0
  263. iatp/__init__.py +166 -0
  264. iatp/attestation.py +461 -0
  265. iatp/cli.py +317 -0
  266. iatp/hf_utils.py +472 -0
  267. iatp/ipc_pipes.py +580 -0
  268. iatp/main.py +412 -0
  269. iatp/models/__init__.py +447 -0
  270. iatp/policy_engine.py +337 -0
  271. iatp/py.typed +2 -0
  272. iatp/recovery.py +321 -0
  273. iatp/security/__init__.py +270 -0
  274. iatp/sidecar/__init__.py +519 -0
  275. iatp/telemetry/__init__.py +164 -0
  276. iatp/tests/__init__.py +1 -0
  277. iatp/tests/test_attestation.py +370 -0
  278. iatp/tests/test_cli.py +131 -0
  279. iatp/tests/test_ed25519_attestation.py +211 -0
  280. iatp/tests/test_models.py +130 -0
  281. iatp/tests/test_policy_engine.py +347 -0
  282. iatp/tests/test_recovery.py +281 -0
  283. iatp/tests/test_security.py +222 -0
  284. iatp/tests/test_sidecar.py +167 -0
  285. iatp/tests/test_telemetry.py +175 -0
  286. mcp_kernel_server/__init__.py +28 -0
  287. mcp_kernel_server/cli.py +274 -0
  288. mcp_kernel_server/resources.py +217 -0
  289. mcp_kernel_server/server.py +564 -0
  290. mcp_kernel_server/tools.py +1174 -0
  291. mute_agent/__init__.py +68 -0
  292. mute_agent/core/__init__.py +1 -0
  293. mute_agent/core/execution_agent.py +166 -0
  294. mute_agent/core/handshake_protocol.py +201 -0
  295. mute_agent/core/reasoning_agent.py +238 -0
  296. mute_agent/knowledge_graph/__init__.py +1 -0
  297. mute_agent/knowledge_graph/graph_elements.py +65 -0
  298. mute_agent/knowledge_graph/multidimensional_graph.py +170 -0
  299. mute_agent/knowledge_graph/subgraph.py +224 -0
  300. mute_agent/listener/__init__.py +43 -0
  301. mute_agent/listener/adapters/__init__.py +31 -0
  302. mute_agent/listener/adapters/base_adapter.py +189 -0
  303. mute_agent/listener/adapters/caas_adapter.py +344 -0
  304. mute_agent/listener/adapters/control_plane_adapter.py +436 -0
  305. mute_agent/listener/adapters/iatp_adapter.py +332 -0
  306. mute_agent/listener/adapters/scak_adapter.py +251 -0
  307. mute_agent/listener/listener.py +610 -0
  308. mute_agent/listener/state_observer.py +436 -0
  309. mute_agent/listener/threshold_config.py +313 -0
  310. mute_agent/super_system/__init__.py +1 -0
  311. mute_agent/super_system/router.py +204 -0
  312. mute_agent/visualization/__init__.py +10 -0
  313. mute_agent/visualization/graph_debugger.py +502 -0
  314. nexus/README.md +60 -0
  315. nexus/__init__.py +51 -0
  316. nexus/arbiter.py +359 -0
  317. nexus/client.py +466 -0
  318. nexus/dmz.py +444 -0
  319. nexus/escrow.py +430 -0
  320. nexus/exceptions.py +286 -0
  321. nexus/pyproject.toml +36 -0
  322. nexus/registry.py +393 -0
  323. nexus/reputation.py +425 -0
  324. nexus/schemas/__init__.py +51 -0
  325. nexus/schemas/compliance.py +276 -0
  326. nexus/schemas/escrow.py +251 -0
  327. nexus/schemas/manifest.py +225 -0
  328. nexus/schemas/receipt.py +208 -0
  329. nexus/tests/__init__.py +0 -0
  330. nexus/tests/conftest.py +146 -0
  331. nexus/tests/test_arbiter.py +192 -0
  332. nexus/tests/test_dmz.py +194 -0
  333. nexus/tests/test_escrow.py +276 -0
  334. nexus/tests/test_exceptions.py +225 -0
  335. nexus/tests/test_registry.py +232 -0
  336. nexus/tests/test_reputation.py +328 -0
  337. nexus/tests/test_schemas.py +295 -0
amb_core/bus.py ADDED
@@ -0,0 +1,481 @@
1
+ # Copyright (c) Microsoft Corporation.
2
+ # Licensed under the MIT License.
3
+ """Main MessageBus implementation."""
4
+
5
+ import uuid
6
+ import traceback
7
+ from typing import Optional, Dict, Any, Union
8
+ from amb_core.broker import BrokerAdapter, MessageHandler
9
+ from amb_core.models import Message, MessagePriority, Priority
10
+ from amb_core.memory_broker import InMemoryBroker
11
+ from amb_core.schema import SchemaRegistry, SchemaValidationError
12
+ from amb_core.dlq import DeadLetterQueue, DLQEntry, DLQReason
13
+ from amb_core.persistence import MessageStore, InMemoryMessageStore, MessageStatus
14
+ from amb_core.tracing import TraceContext, get_current_trace
15
+
16
+
17
+ class MessageBus:
18
+ """
19
+ Main message bus interface for AI Agents.
20
+
21
+ This class provides a simple API for publishing and subscribing to messages
22
+ with support for both "fire and forget" and "wait for verification" patterns.
23
+
24
+ New in v0.2.0:
25
+ - persistence: Enable durable message storage for replay capability
26
+ - schema_registry: Validate messages against schemas
27
+ - dlq_enabled: Route failed messages to dead letter queue
28
+ - Distributed tracing support via trace_id
29
+
30
+ Example:
31
+ # Basic usage (backward compatible)
32
+ bus = MessageBus(adapter=InMemoryAdapter())
33
+ await bus.publish("topic", Message(payload=data))
34
+
35
+ # With new features
36
+ bus = MessageBus(
37
+ adapter=InMemoryAdapter(),
38
+ persistence=True, # Durable messages
39
+ schema_registry=schemas, # Validation
40
+ dlq_enabled=True # Dead letter queue
41
+ )
42
+
43
+ await bus.publish(
44
+ "topic",
45
+ Message(
46
+ payload=data,
47
+ priority=Priority.HIGH, # Prioritization
48
+ ttl_seconds=300, # Expiration
49
+ trace_id=uuid4() # Distributed tracing
50
+ )
51
+ )
52
+ """
53
+
54
+ def __init__(
55
+ self,
56
+ adapter: Optional[BrokerAdapter] = None,
57
+ *,
58
+ persistence: Union[bool, MessageStore] = False,
59
+ schema_registry: Optional[SchemaRegistry] = None,
60
+ dlq_enabled: Union[bool, DeadLetterQueue] = False,
61
+ auto_inject_trace: bool = True
62
+ ):
63
+ """
64
+ Initialize the message bus.
65
+
66
+ Args:
67
+ adapter: Broker adapter to use. If None, uses InMemoryBroker.
68
+ persistence: Enable message persistence. Can be True for default
69
+ InMemoryMessageStore, or a MessageStore instance.
70
+ schema_registry: SchemaRegistry for message validation.
71
+ dlq_enabled: Enable dead letter queue. Can be True for default
72
+ DeadLetterQueue, or a DeadLetterQueue instance.
73
+ auto_inject_trace: Automatically inject trace context into messages.
74
+ """
75
+ self._adapter = adapter or InMemoryBroker()
76
+ self._connected = False
77
+
78
+ # Persistence (AMB-001)
79
+ if persistence is True:
80
+ self._persistence: Optional[MessageStore] = InMemoryMessageStore()
81
+ elif persistence is False:
82
+ self._persistence = None
83
+ else:
84
+ self._persistence = persistence
85
+
86
+ # Schema validation (AMB-003)
87
+ self._schema_registry = schema_registry
88
+
89
+ # Dead letter queue (AMB-002)
90
+ if dlq_enabled is True:
91
+ self._dlq: Optional[DeadLetterQueue] = DeadLetterQueue()
92
+ elif dlq_enabled is False:
93
+ self._dlq = None
94
+ else:
95
+ self._dlq = dlq_enabled
96
+
97
+ # Tracing (AMB-004)
98
+ self._auto_inject_trace = auto_inject_trace
99
+
100
+ @property
101
+ def dlq(self) -> Optional[DeadLetterQueue]:
102
+ """Get the dead letter queue."""
103
+ return self._dlq
104
+
105
+ @property
106
+ def persistence(self) -> Optional[MessageStore]:
107
+ """Get the message store."""
108
+ return self._persistence
109
+
110
+ @property
111
+ def schema_registry(self) -> Optional[SchemaRegistry]:
112
+ """Get the schema registry."""
113
+ return self._schema_registry
114
+
115
+ async def connect(self) -> None:
116
+ """Connect to the broker."""
117
+ await self._adapter.connect()
118
+ self._connected = True
119
+
120
+ async def disconnect(self) -> None:
121
+ """Disconnect from the broker."""
122
+ await self._adapter.disconnect()
123
+ self._connected = False
124
+
125
+ async def __aenter__(self):
126
+ """Async context manager entry."""
127
+ await self.connect()
128
+ return self
129
+
130
+ async def __aexit__(self, exc_type, exc_val, exc_tb):
131
+ """Async context manager exit."""
132
+ await self.disconnect()
133
+
134
+ async def publish(
135
+ self,
136
+ topic: str,
137
+ payload: Dict[str, Any],
138
+ *,
139
+ priority: MessagePriority = MessagePriority.NORMAL,
140
+ sender: Optional[str] = None,
141
+ wait_for_confirmation: bool = False,
142
+ ttl_seconds: Optional[int] = None,
143
+ trace_id: Optional[str] = None,
144
+ **kwargs
145
+ ) -> str:
146
+ """
147
+ Publish a message to a topic.
148
+
149
+ This method supports both "fire and forget" (default) and
150
+ "wait for verification" patterns via the wait_for_confirmation parameter.
151
+
152
+ Args:
153
+ topic: Topic to publish to
154
+ payload: Message payload
155
+ priority: Message priority level (use Priority.HIGH, Priority.URGENT, etc.)
156
+ sender: Optional sender identifier
157
+ wait_for_confirmation: If True, wait for broker confirmation
158
+ ttl_seconds: Time-to-live in seconds (message expires after this)
159
+ trace_id: Distributed trace ID for tracking message flow
160
+ **kwargs: Additional message attributes
161
+
162
+ Returns:
163
+ Message ID
164
+
165
+ Raises:
166
+ ConnectionError: If not connected to the bus
167
+ SchemaValidationError: If schema validation fails (when registry configured)
168
+
169
+ Example:
170
+ # Fire and forget (fast, no guarantee)
171
+ await bus.publish("agent.thoughts", {"thought": "Hello"})
172
+
173
+ # Wait for verification (slower, with guarantee)
174
+ msg_id = await bus.publish(
175
+ "agent.action",
176
+ {"action": "execute"},
177
+ wait_for_confirmation=True
178
+ )
179
+
180
+ # With new features
181
+ await bus.publish(
182
+ "fraud.alerts",
183
+ {"transaction_id": "tx123", "risk_score": 0.95},
184
+ priority=Priority.CRITICAL,
185
+ ttl_seconds=300,
186
+ trace_id=str(uuid4())
187
+ )
188
+ """
189
+ if not self._connected:
190
+ raise ConnectionError("Message bus not connected")
191
+
192
+ # Schema validation (AMB-003)
193
+ if self._schema_registry and self._schema_registry.has_schema(topic):
194
+ payload = self._schema_registry.validate(topic, payload)
195
+
196
+ # Auto-inject trace context (AMB-004)
197
+ if self._auto_inject_trace and trace_id is None:
198
+ current_trace = get_current_trace()
199
+ if current_trace:
200
+ trace_id = current_trace.trace_id
201
+ kwargs.setdefault('span_id', current_trace.span_id)
202
+ kwargs.setdefault('parent_span_id', current_trace.parent_span_id)
203
+
204
+ message = Message(
205
+ id=str(uuid.uuid4()),
206
+ topic=topic,
207
+ payload=payload,
208
+ priority=priority,
209
+ sender=sender,
210
+ ttl=ttl_seconds,
211
+ trace_id=trace_id,
212
+ **kwargs
213
+ )
214
+
215
+ # Persist message if enabled (AMB-001)
216
+ if self._persistence:
217
+ await self._persistence.store(message)
218
+
219
+ await self._adapter.publish(message, wait_for_confirmation=wait_for_confirmation)
220
+
221
+ # Update persistence status
222
+ if self._persistence:
223
+ await self._persistence.update_status(message.id, MessageStatus.DELIVERED)
224
+
225
+ return message.id
226
+
227
+ async def subscribe(
228
+ self,
229
+ topic: str,
230
+ handler: MessageHandler,
231
+ *,
232
+ with_dlq: bool = True
233
+ ) -> str:
234
+ """
235
+ Subscribe to a topic with a message handler.
236
+
237
+ Args:
238
+ topic: Topic to subscribe to
239
+ handler: Async function to handle messages
240
+ with_dlq: If True and DLQ is enabled, route failed messages to DLQ
241
+
242
+ Returns:
243
+ Subscription ID
244
+
245
+ Example:
246
+ async def handle_message(msg: Message):
247
+ print(f"Received: {msg.payload}")
248
+
249
+ sub_id = await bus.subscribe("agent.thoughts", handle_message)
250
+ """
251
+ if not self._connected:
252
+ raise ConnectionError("Message bus not connected")
253
+
254
+ # Wrap handler with DLQ support if enabled
255
+ if self._dlq and with_dlq:
256
+ wrapped_handler = self._wrap_handler_with_dlq(handler, topic)
257
+ else:
258
+ wrapped_handler = handler
259
+
260
+ return await self._adapter.subscribe(topic, wrapped_handler)
261
+
262
+ def _wrap_handler_with_dlq(self, handler: MessageHandler, topic: str) -> MessageHandler:
263
+ """Wrap a message handler with DLQ error handling."""
264
+ async def dlq_handler(message: Message) -> None:
265
+ # Check if message is expired (AMB-007)
266
+ if message.is_expired:
267
+ if self._dlq:
268
+ entry = DLQEntry(
269
+ message=message,
270
+ reason=DLQReason.EXPIRED,
271
+ error_message=f"Message expired (TTL: {message.ttl}s, age: {message.age_seconds:.1f}s)",
272
+ original_topic=topic
273
+ )
274
+ await self._dlq.add(entry)
275
+ return # Don't process expired messages
276
+
277
+ try:
278
+ await handler(message)
279
+ # Update persistence status if enabled
280
+ if self._persistence:
281
+ await self._persistence.update_status(message.id, MessageStatus.ACKNOWLEDGED)
282
+ except Exception as e:
283
+ # Route to DLQ on failure (AMB-002)
284
+ if self._dlq:
285
+ entry = DLQEntry(
286
+ message=message,
287
+ reason=DLQReason.HANDLER_ERROR,
288
+ error_message=str(e),
289
+ original_topic=topic,
290
+ stack_trace=traceback.format_exc()
291
+ )
292
+ await self._dlq.add(entry)
293
+
294
+ # Update persistence status
295
+ if self._persistence:
296
+ await self._persistence.update_status(
297
+ message.id, MessageStatus.FAILED, error=str(e)
298
+ )
299
+
300
+ # Re-raise if no DLQ to maintain original behavior
301
+ if not self._dlq:
302
+ raise
303
+
304
+ return dlq_handler
305
+
306
+ async def unsubscribe(self, subscription_id: str) -> None:
307
+ """
308
+ Unsubscribe from a topic.
309
+
310
+ Args:
311
+ subscription_id: Subscription ID to unsubscribe
312
+ """
313
+ if not self._connected:
314
+ raise ConnectionError("Message bus not connected")
315
+
316
+ await self._adapter.unsubscribe(subscription_id)
317
+
318
+ async def request(
319
+ self,
320
+ topic: str,
321
+ payload: Dict[str, Any],
322
+ *,
323
+ timeout: float = 30.0,
324
+ sender: Optional[str] = None,
325
+ **kwargs
326
+ ) -> Message:
327
+ """
328
+ Send a request and wait for a response.
329
+
330
+ This implements the request-response pattern for cases where
331
+ you need to wait for a reply from another agent.
332
+
333
+ Args:
334
+ topic: Topic to send request to
335
+ payload: Request payload
336
+ timeout: Maximum time to wait for response
337
+ sender: Optional sender identifier
338
+ **kwargs: Additional message attributes
339
+
340
+ Returns:
341
+ Response message
342
+
343
+ Raises:
344
+ TimeoutError: If no response within timeout
345
+
346
+ Example:
347
+ response = await bus.request(
348
+ "agent.query",
349
+ {"query": "What is the status?"},
350
+ timeout=10.0
351
+ )
352
+ print(response.payload)
353
+ """
354
+ if not self._connected:
355
+ raise ConnectionError("Message bus not connected")
356
+
357
+ # Auto-inject trace context
358
+ trace_id = kwargs.pop('trace_id', None)
359
+ if self._auto_inject_trace and trace_id is None:
360
+ current_trace = get_current_trace()
361
+ if current_trace:
362
+ trace_id = current_trace.trace_id
363
+
364
+ message = Message(
365
+ id=str(uuid.uuid4()),
366
+ topic=topic,
367
+ payload=payload,
368
+ sender=sender,
369
+ correlation_id=str(uuid.uuid4()),
370
+ trace_id=trace_id,
371
+ **kwargs
372
+ )
373
+
374
+ return await self._adapter.request(message, timeout=timeout)
375
+
376
+ async def reply(self, original_message: Message, payload: Dict[str, Any]) -> str:
377
+ """
378
+ Reply to a request message.
379
+
380
+ Args:
381
+ original_message: The original request message
382
+ payload: Reply payload
383
+
384
+ Returns:
385
+ Reply message ID
386
+
387
+ Example:
388
+ async def handle_request(msg: Message):
389
+ result = process_request(msg.payload)
390
+ await bus.reply(msg, {"result": result})
391
+ """
392
+ if not self._connected:
393
+ raise ConnectionError("Message bus not connected")
394
+
395
+ if not original_message.correlation_id:
396
+ raise ValueError("Original message has no correlation_id")
397
+
398
+ reply_topic = original_message.reply_to or original_message.topic
399
+
400
+ reply_message = Message(
401
+ id=str(uuid.uuid4()),
402
+ topic=reply_topic,
403
+ payload=payload,
404
+ correlation_id=original_message.correlation_id,
405
+ sender=None,
406
+ trace_id=original_message.trace_id, # Propagate trace_id
407
+ )
408
+
409
+ await self._adapter.publish(reply_message, wait_for_confirmation=False)
410
+ return reply_message.id
411
+
412
+ async def replay(
413
+ self,
414
+ topic: str,
415
+ handler: MessageHandler,
416
+ *,
417
+ from_timestamp: Optional["datetime"] = None,
418
+ to_timestamp: Optional["datetime"] = None
419
+ ) -> int:
420
+ """
421
+ Replay persisted messages from a topic (AMB-001).
422
+
423
+ Args:
424
+ topic: Topic to replay messages from
425
+ handler: Handler to process replayed messages
426
+ from_timestamp: Start timestamp (inclusive)
427
+ to_timestamp: End timestamp (inclusive)
428
+
429
+ Returns:
430
+ Number of messages replayed
431
+
432
+ Raises:
433
+ ValueError: If persistence is not enabled
434
+
435
+ Example:
436
+ # Replay all messages from the last hour
437
+ from datetime import datetime, timedelta, timezone
438
+
439
+ one_hour_ago = datetime.now(timezone.utc) - timedelta(hours=1)
440
+ count = await bus.replay(
441
+ "fraud.alerts",
442
+ handle_alert,
443
+ from_timestamp=one_hour_ago
444
+ )
445
+ print(f"Replayed {count} messages")
446
+ """
447
+ if not self._persistence:
448
+ raise ValueError("Message persistence is not enabled")
449
+
450
+ count = 0
451
+ async for message in self._persistence.replay(topic, from_timestamp, to_timestamp):
452
+ await handler(message)
453
+ count += 1
454
+
455
+ return count
456
+
457
+ async def get_dlq_stats(self) -> Optional[Dict[str, Any]]:
458
+ """
459
+ Get DLQ statistics.
460
+
461
+ Returns:
462
+ DLQ stats dict or None if DLQ not enabled
463
+ """
464
+ if self._dlq is None:
465
+ return None
466
+ return await self._dlq.get_stats()
467
+
468
+ async def get_persistence_stats(self) -> Optional[Dict[str, Any]]:
469
+ """
470
+ Get persistence statistics.
471
+
472
+ Returns:
473
+ Persistence stats dict or None if persistence not enabled
474
+ """
475
+ if not self._persistence:
476
+ return None
477
+ return await self._persistence.get_stats()
478
+
479
+
480
+ # Import datetime for type hints
481
+ from datetime import datetime