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
mute_agent/__init__.py ADDED
@@ -0,0 +1,68 @@
1
+ # Copyright (c) Microsoft Corporation.
2
+ # Licensed under the MIT License.
3
+ """
4
+ Mute Agent - Decoupling Reasoning from Execution
5
+
6
+ Layer 5 Reference Implementation: A Listener agent that monitors graph states
7
+ without interfering until configured thresholds are exceeded.
8
+
9
+ Consolidated Stack:
10
+ - agent-control-plane: Base orchestration
11
+ - scak: Intelligence/Knowledge layer
12
+ - iatp: Security/Trust layer
13
+ - caas: Context-as-a-Service layer
14
+ """
15
+
16
+ __version__ = "3.1.0"
17
+
18
+ # Core components
19
+ from .core.reasoning_agent import ReasoningAgent
20
+ from .core.execution_agent import ExecutionAgent
21
+ from .core.handshake_protocol import HandshakeProtocol
22
+ from .knowledge_graph.multidimensional_graph import MultidimensionalKnowledgeGraph
23
+ from .super_system.router import SuperSystemRouter
24
+
25
+ # Layer 5: Listener Agent
26
+ from .listener import (
27
+ ListenerAgent,
28
+ ListenerState,
29
+ InterventionEvent,
30
+ ThresholdConfig,
31
+ ThresholdType,
32
+ InterventionLevel,
33
+ DEFAULT_THRESHOLDS,
34
+ StateObserver,
35
+ ObservationResult,
36
+ )
37
+
38
+ # Layer adapters
39
+ from .listener.adapters import (
40
+ ControlPlaneAdapter,
41
+ IntelligenceAdapter,
42
+ SecurityAdapter,
43
+ ContextAdapter,
44
+ )
45
+
46
+ __all__ = [
47
+ # Core
48
+ "ReasoningAgent",
49
+ "ExecutionAgent",
50
+ "HandshakeProtocol",
51
+ "MultidimensionalKnowledgeGraph",
52
+ "SuperSystemRouter",
53
+ # Layer 5: Listener
54
+ "ListenerAgent",
55
+ "ListenerState",
56
+ "InterventionEvent",
57
+ "ThresholdConfig",
58
+ "ThresholdType",
59
+ "InterventionLevel",
60
+ "DEFAULT_THRESHOLDS",
61
+ "StateObserver",
62
+ "ObservationResult",
63
+ # Adapters
64
+ "ControlPlaneAdapter",
65
+ "IntelligenceAdapter",
66
+ "SecurityAdapter",
67
+ "ContextAdapter",
68
+ ]
@@ -0,0 +1 @@
1
+ """Core components of the Mute Agent system."""
@@ -0,0 +1,166 @@
1
+ # Copyright (c) Microsoft Corporation.
2
+ # Licensed under the MIT License.
3
+ """
4
+ The Hands - The Execution Agent
5
+ """
6
+
7
+ from typing import Dict, List, Optional, Any, Callable
8
+ from .handshake_protocol import HandshakeProtocol, HandshakeSession, HandshakeState
9
+
10
+
11
+ class ExecutionAgent:
12
+ """
13
+ The Hands - The Execution Agent
14
+
15
+ This agent is responsible for executing actions that have been negotiated
16
+ and validated through the Handshake Protocol. It does not reason about
17
+ actions but simply executes them when properly authorized.
18
+ """
19
+
20
+ def __init__(self, protocol: HandshakeProtocol):
21
+ self.protocol = protocol
22
+ self.execution_handlers: Dict[str, Callable] = {}
23
+ self.execution_history: List[Dict[str, Any]] = []
24
+
25
+ def register_action_handler(
26
+ self,
27
+ action_id: str,
28
+ handler: Callable[[Dict[str, Any]], Dict[str, Any]]
29
+ ) -> None:
30
+ """
31
+ Register a handler function for a specific action.
32
+ The handler receives parameters and returns results.
33
+ """
34
+ self.execution_handlers[action_id] = handler
35
+
36
+ def execute(self, session_id: str) -> HandshakeSession:
37
+ """
38
+ Execute an action from an accepted handshake session.
39
+ This is the main execution entry point.
40
+ """
41
+ session = self.protocol.get_session(session_id)
42
+
43
+ if not session:
44
+ raise ValueError(f"Session {session_id} not found")
45
+
46
+ if session.state != HandshakeState.ACCEPTED:
47
+ raise ValueError(
48
+ f"Cannot execute session in state {session.state}. "
49
+ f"Session must be in ACCEPTED state."
50
+ )
51
+
52
+ if not session.proposal:
53
+ raise ValueError("Session has no proposal")
54
+
55
+ # Mark as executing
56
+ self.protocol.start_execution(session_id)
57
+
58
+ try:
59
+ # Execute the action
60
+ result = self._execute_action(
61
+ session.proposal.action_id,
62
+ session.proposal.parameters,
63
+ session.proposal.context
64
+ )
65
+
66
+ # Mark as completed
67
+ self.protocol.complete_execution(session_id, result)
68
+
69
+ # Store in history
70
+ self.execution_history.append({
71
+ "session_id": session_id,
72
+ "action_id": session.proposal.action_id,
73
+ "result": result,
74
+ "success": True
75
+ })
76
+
77
+ except Exception as e:
78
+ # Mark as failed
79
+ self.protocol.fail_execution(session_id, str(e))
80
+
81
+ # Store in history
82
+ self.execution_history.append({
83
+ "session_id": session_id,
84
+ "action_id": session.proposal.action_id,
85
+ "error": str(e),
86
+ "success": False
87
+ })
88
+
89
+ raise
90
+
91
+ return self.protocol.get_session(session_id)
92
+
93
+ def _execute_action(
94
+ self,
95
+ action_id: str,
96
+ parameters: Dict[str, Any],
97
+ context: Dict[str, Any]
98
+ ) -> Dict[str, Any]:
99
+ """
100
+ Execute a specific action using its registered handler.
101
+ """
102
+ handler = self.execution_handlers.get(action_id)
103
+
104
+ if not handler:
105
+ # If no handler registered, return a default result
106
+ return {
107
+ "status": "no_handler",
108
+ "message": f"No handler registered for action {action_id}",
109
+ "action_id": action_id,
110
+ "parameters": parameters
111
+ }
112
+
113
+ # Call the handler
114
+ result = handler(parameters)
115
+
116
+ return {
117
+ "status": "success",
118
+ "action_id": action_id,
119
+ "result": result
120
+ }
121
+
122
+ def can_execute(self, session_id: str) -> bool:
123
+ """Check if a session can be executed."""
124
+ session = self.protocol.get_session(session_id)
125
+
126
+ if not session:
127
+ return False
128
+
129
+ if session.state != HandshakeState.ACCEPTED:
130
+ return False
131
+
132
+ if not session.proposal:
133
+ return False
134
+
135
+ # Check if handler is registered (optional)
136
+ return True
137
+
138
+ def get_execution_statistics(self) -> Dict[str, Any]:
139
+ """Get statistics about execution operations."""
140
+ if not self.execution_history:
141
+ return {
142
+ "total_executions": 0,
143
+ "successful_executions": 0,
144
+ "failed_executions": 0,
145
+ "success_rate": 0.0
146
+ }
147
+
148
+ total = len(self.execution_history)
149
+ successful = sum(1 for exec in self.execution_history if exec["success"])
150
+ failed = total - successful
151
+
152
+ return {
153
+ "total_executions": total,
154
+ "successful_executions": successful,
155
+ "failed_executions": failed,
156
+ "success_rate": successful / total if total > 0 else 0.0,
157
+ "actions_executed": self._get_action_counts()
158
+ }
159
+
160
+ def _get_action_counts(self) -> Dict[str, int]:
161
+ """Get counts of how many times each action was executed."""
162
+ counts = {}
163
+ for exec in self.execution_history:
164
+ action_id = exec["action_id"]
165
+ counts[action_id] = counts.get(action_id, 0) + 1
166
+ return counts
@@ -0,0 +1,201 @@
1
+ # Copyright (c) Microsoft Corporation.
2
+ # Licensed under the MIT License.
3
+ """
4
+ Dynamic Semantic Handshake Protocol - The negotiation mechanism between
5
+ The Face (Reasoning) and The Hands (Execution).
6
+ """
7
+
8
+ from typing import Dict, List, Optional, Any
9
+ from dataclasses import dataclass, field
10
+ from enum import Enum
11
+ from datetime import datetime
12
+
13
+
14
+ class HandshakeState(Enum):
15
+ """States in the handshake protocol."""
16
+ INITIATED = "initiated"
17
+ NEGOTIATING = "negotiating"
18
+ VALIDATED = "validated"
19
+ ACCEPTED = "accepted"
20
+ REJECTED = "rejected"
21
+ EXECUTING = "executing"
22
+ COMPLETED = "completed"
23
+ FAILED = "failed"
24
+
25
+
26
+ @dataclass
27
+ class ActionProposal:
28
+ """A proposed action from the Reasoning Agent."""
29
+ action_id: str
30
+ parameters: Dict[str, Any]
31
+ context: Dict[str, Any]
32
+ justification: str
33
+ priority: float = 1.0
34
+ timestamp: datetime = field(default_factory=datetime.now)
35
+
36
+
37
+ @dataclass
38
+ class ValidationResult:
39
+ """Result of validating an action proposal."""
40
+ is_valid: bool
41
+ errors: List[str] = field(default_factory=list)
42
+ warnings: List[str] = field(default_factory=list)
43
+ constraints_met: List[str] = field(default_factory=list)
44
+ constraints_violated: List[str] = field(default_factory=list)
45
+
46
+
47
+ @dataclass
48
+ class HandshakeSession:
49
+ """A session tracking the handshake process."""
50
+ session_id: str
51
+ state: HandshakeState
52
+ proposal: Optional[ActionProposal] = None
53
+ validation_result: Optional[ValidationResult] = None
54
+ execution_result: Optional[Dict[str, Any]] = None
55
+ created_at: datetime = field(default_factory=datetime.now)
56
+ updated_at: datetime = field(default_factory=datetime.now)
57
+ metadata: Dict[str, Any] = field(default_factory=dict)
58
+
59
+
60
+ class HandshakeProtocol:
61
+ """
62
+ The Dynamic Semantic Handshake Protocol manages the negotiation
63
+ between the Reasoning Agent (The Face) and the Execution Agent (The Hands).
64
+
65
+ Instead of free-text tool invocation, actions must be negotiated against
66
+ the knowledge graph constraints.
67
+ """
68
+
69
+ def __init__(self):
70
+ self.sessions: Dict[str, HandshakeSession] = {}
71
+ self._session_counter = 0
72
+
73
+ def initiate_handshake(
74
+ self,
75
+ proposal: ActionProposal
76
+ ) -> HandshakeSession:
77
+ """
78
+ Initiate a new handshake session with an action proposal.
79
+ This is called by the Reasoning Agent.
80
+ """
81
+ session_id = self._generate_session_id()
82
+ session = HandshakeSession(
83
+ session_id=session_id,
84
+ state=HandshakeState.INITIATED,
85
+ proposal=proposal
86
+ )
87
+ self.sessions[session_id] = session
88
+ return session
89
+
90
+ def validate_proposal(
91
+ self,
92
+ session_id: str,
93
+ validation_result: ValidationResult
94
+ ) -> HandshakeSession:
95
+ """
96
+ Validate the proposal in a session.
97
+ This is typically called after checking against the knowledge graph.
98
+ """
99
+ session = self.sessions.get(session_id)
100
+ if not session:
101
+ raise ValueError(f"Session {session_id} not found")
102
+
103
+ session.validation_result = validation_result
104
+ session.state = HandshakeState.VALIDATED if validation_result.is_valid else HandshakeState.REJECTED
105
+ session.updated_at = datetime.now()
106
+
107
+ return session
108
+
109
+ def accept_proposal(self, session_id: str) -> HandshakeSession:
110
+ """
111
+ Accept a validated proposal for execution.
112
+ This transitions from validation to acceptance.
113
+ """
114
+ session = self.sessions.get(session_id)
115
+ if not session:
116
+ raise ValueError(f"Session {session_id} not found")
117
+
118
+ if session.state != HandshakeState.VALIDATED:
119
+ raise ValueError(f"Cannot accept proposal in state {session.state}")
120
+
121
+ if not session.validation_result or not session.validation_result.is_valid:
122
+ raise ValueError("Cannot accept invalid proposal")
123
+
124
+ session.state = HandshakeState.ACCEPTED
125
+ session.updated_at = datetime.now()
126
+
127
+ return session
128
+
129
+ def reject_proposal(
130
+ self,
131
+ session_id: str,
132
+ reason: str
133
+ ) -> HandshakeSession:
134
+ """Reject a proposal with a reason."""
135
+ session = self.sessions.get(session_id)
136
+ if not session:
137
+ raise ValueError(f"Session {session_id} not found")
138
+
139
+ session.state = HandshakeState.REJECTED
140
+ session.metadata["rejection_reason"] = reason
141
+ session.updated_at = datetime.now()
142
+
143
+ return session
144
+
145
+ def start_execution(self, session_id: str) -> HandshakeSession:
146
+ """
147
+ Start executing an accepted proposal.
148
+ This is called by the Execution Agent.
149
+ """
150
+ session = self.sessions.get(session_id)
151
+ if not session:
152
+ raise ValueError(f"Session {session_id} not found")
153
+
154
+ if session.state != HandshakeState.ACCEPTED:
155
+ raise ValueError(f"Cannot execute proposal in state {session.state}")
156
+
157
+ session.state = HandshakeState.EXECUTING
158
+ session.updated_at = datetime.now()
159
+
160
+ return session
161
+
162
+ def complete_execution(
163
+ self,
164
+ session_id: str,
165
+ result: Dict[str, Any]
166
+ ) -> HandshakeSession:
167
+ """Complete execution with results."""
168
+ session = self.sessions.get(session_id)
169
+ if not session:
170
+ raise ValueError(f"Session {session_id} not found")
171
+
172
+ session.execution_result = result
173
+ session.state = HandshakeState.COMPLETED
174
+ session.updated_at = datetime.now()
175
+
176
+ return session
177
+
178
+ def fail_execution(
179
+ self,
180
+ session_id: str,
181
+ error: str
182
+ ) -> HandshakeSession:
183
+ """Mark execution as failed."""
184
+ session = self.sessions.get(session_id)
185
+ if not session:
186
+ raise ValueError(f"Session {session_id} not found")
187
+
188
+ session.state = HandshakeState.FAILED
189
+ session.metadata["error"] = error
190
+ session.updated_at = datetime.now()
191
+
192
+ return session
193
+
194
+ def get_session(self, session_id: str) -> Optional[HandshakeSession]:
195
+ """Get a session by ID."""
196
+ return self.sessions.get(session_id)
197
+
198
+ def _generate_session_id(self) -> str:
199
+ """Generate a unique session ID."""
200
+ self._session_counter += 1
201
+ return f"session_{self._session_counter}_{datetime.now().timestamp()}"
@@ -0,0 +1,238 @@
1
+ # Copyright (c) Microsoft Corporation.
2
+ # Licensed under the MIT License.
3
+ """
4
+ The Face - The Reasoning Agent
5
+ """
6
+
7
+ from typing import Dict, List, Optional, Any
8
+ from ..knowledge_graph.multidimensional_graph import MultidimensionalKnowledgeGraph
9
+ from ..knowledge_graph.graph_elements import Node, NodeType
10
+ from ..super_system.router import SuperSystemRouter, RoutingResult
11
+ from .handshake_protocol import (
12
+ HandshakeProtocol,
13
+ ActionProposal,
14
+ ValidationResult,
15
+ HandshakeSession,
16
+ HandshakeState
17
+ )
18
+
19
+
20
+ class ReasoningAgent:
21
+ """
22
+ The Face - The Reasoning Agent
23
+
24
+ This agent is responsible for reasoning about actions and negotiating
25
+ with the Execution Agent through the Handshake Protocol. It does not
26
+ execute actions directly but proposes them based on graph constraints.
27
+ """
28
+
29
+ # Maximum size for reasoning history to prevent memory bloat
30
+ MAX_HISTORY_SIZE = 1000
31
+
32
+ def __init__(
33
+ self,
34
+ knowledge_graph: MultidimensionalKnowledgeGraph,
35
+ router: SuperSystemRouter,
36
+ protocol: HandshakeProtocol
37
+ ):
38
+ self.knowledge_graph = knowledge_graph
39
+ self.router = router
40
+ self.protocol = protocol
41
+ self.reasoning_history: List[Dict[str, Any]] = []
42
+
43
+ def reason(self, context: Dict[str, Any]) -> RoutingResult:
44
+ """
45
+ Reason about the context and determine available actions.
46
+ This uses the Super System Router to prune the action space.
47
+ """
48
+ routing_result = self.router.route(context)
49
+
50
+ # Store reasoning step (with size limit to prevent memory bloat)
51
+ self.reasoning_history.append({
52
+ "context": context,
53
+ "selected_dimensions": routing_result.selected_dimensions,
54
+ "available_actions": len(routing_result.pruned_action_space)
55
+ })
56
+
57
+ # Trim history if it exceeds maximum size
58
+ if len(self.reasoning_history) > self.MAX_HISTORY_SIZE:
59
+ self.reasoning_history = self.reasoning_history[-self.MAX_HISTORY_SIZE:]
60
+
61
+ return routing_result
62
+
63
+ def propose_action(
64
+ self,
65
+ action_id: str,
66
+ parameters: Dict[str, Any],
67
+ context: Dict[str, Any],
68
+ justification: str
69
+ ) -> HandshakeSession:
70
+ """
71
+ Propose an action for execution.
72
+ This initiates the handshake protocol.
73
+ """
74
+ # Create proposal
75
+ proposal = ActionProposal(
76
+ action_id=action_id,
77
+ parameters=parameters,
78
+ context=context,
79
+ justification=justification
80
+ )
81
+
82
+ # Initiate handshake
83
+ session = self.protocol.initiate_handshake(proposal)
84
+
85
+ # Validate the proposal against the knowledge graph
86
+ validation_result = self._validate_proposal(proposal)
87
+
88
+ # Update session with validation
89
+ self.protocol.validate_proposal(session.session_id, validation_result)
90
+
91
+ return self.protocol.get_session(session.session_id)
92
+
93
+ def _validate_proposal(self, proposal: ActionProposal) -> ValidationResult:
94
+ """
95
+ Validate a proposal against the knowledge graph constraints.
96
+ This is the core constraint checking mechanism with deep dependency resolution.
97
+ """
98
+ errors = []
99
+ warnings = []
100
+ constraints_met = []
101
+ constraints_violated = []
102
+
103
+ # Get routing result for the context
104
+ routing_result = self.router.route(proposal.context)
105
+
106
+ # Check if action exists in pruned action space
107
+ action_available = any(
108
+ node.id == proposal.action_id
109
+ for node in routing_result.pruned_action_space
110
+ )
111
+
112
+ if not action_available:
113
+ errors.append(
114
+ f"Action {proposal.action_id} not available in pruned action space"
115
+ )
116
+ return ValidationResult(
117
+ is_valid=False,
118
+ errors=errors,
119
+ warnings=warnings,
120
+ constraints_met=constraints_met,
121
+ constraints_violated=constraints_violated
122
+ )
123
+
124
+ # Deep dependency checking - find all missing dependencies across dimensions
125
+ all_missing_deps = self.knowledge_graph.find_all_missing_dependencies(
126
+ proposal.action_id,
127
+ routing_result.selected_dimensions,
128
+ proposal.context
129
+ )
130
+
131
+ # If there are missing dependencies, provide detailed error messages
132
+ if all_missing_deps:
133
+ for dim_name, missing_deps in all_missing_deps.items():
134
+ for dep_id in missing_deps:
135
+ errors.append(
136
+ f"Missing dependency '{dep_id}' in dimension '{dim_name}'. "
137
+ f"Please satisfy this requirement first."
138
+ )
139
+ constraints_violated.append(dim_name)
140
+
141
+ # Early return if dependencies are missing - no need for further validation
142
+ is_valid = False
143
+ else:
144
+ # Only validate constraints if no missing dependencies
145
+ for dim_name in routing_result.selected_dimensions:
146
+ # Check if action is valid in this dimension
147
+ subgraph = self.knowledge_graph.get_subgraph(dim_name)
148
+ if not subgraph:
149
+ continue
150
+
151
+ if not subgraph.validate_action(proposal.action_id, proposal.context):
152
+ if dim_name not in constraints_violated:
153
+ errors.append(
154
+ f"Action {proposal.action_id} fails validation in dimension {dim_name}"
155
+ )
156
+ constraints_violated.append(dim_name)
157
+ else:
158
+ if dim_name not in constraints_violated:
159
+ constraints_met.append(dim_name)
160
+
161
+ # Check specific constraints
162
+ constraints = self.knowledge_graph.get_action_constraints(
163
+ proposal.action_id,
164
+ dim_name
165
+ )
166
+
167
+ for constraint in constraints:
168
+ if not self._check_constraint(constraint, proposal):
169
+ warnings.append(
170
+ f"Constraint {constraint.id} may not be fully satisfied"
171
+ )
172
+
173
+ is_valid = len(errors) == 0
174
+
175
+ return ValidationResult(
176
+ is_valid=is_valid,
177
+ errors=errors,
178
+ warnings=warnings,
179
+ constraints_met=constraints_met,
180
+ constraints_violated=constraints_violated
181
+ )
182
+
183
+ def _check_constraint(
184
+ self,
185
+ constraint: Node,
186
+ proposal: ActionProposal
187
+ ) -> bool:
188
+ """Check if a specific constraint is satisfied."""
189
+ # Check if proposal parameters satisfy constraint attributes
190
+ for key, value in constraint.attributes.items():
191
+ if key in proposal.parameters:
192
+ if proposal.parameters[key] != value:
193
+ return False
194
+ return True
195
+
196
+ def select_best_action(
197
+ self,
198
+ context: Dict[str, Any],
199
+ selection_criteria: Optional[Dict[str, Any]] = None
200
+ ) -> Optional[Node]:
201
+ """
202
+ Select the best action from the available action space.
203
+ This can use various selection criteria.
204
+ """
205
+ routing_result = self.router.route(context)
206
+
207
+ if not routing_result.pruned_action_space:
208
+ return None
209
+
210
+ # If no criteria specified, return first action
211
+ if not selection_criteria:
212
+ return routing_result.pruned_action_space[0]
213
+
214
+ # Apply selection criteria
215
+ scored_actions = []
216
+ for action in routing_result.pruned_action_space:
217
+ score = self._score_action(action, selection_criteria)
218
+ scored_actions.append((score, action))
219
+
220
+ # Sort by score and return best
221
+ scored_actions.sort(reverse=True, key=lambda x: x[0])
222
+ return scored_actions[0][1] if scored_actions else None
223
+
224
+ def _score_action(
225
+ self,
226
+ action: Node,
227
+ criteria: Dict[str, Any]
228
+ ) -> float:
229
+ """Score an action based on selection criteria."""
230
+ score = 0.0
231
+
232
+ # Match attributes
233
+ for key, value in criteria.items():
234
+ if key in action.attributes:
235
+ if action.attributes[key] == value:
236
+ score += 1.0
237
+
238
+ return score
@@ -0,0 +1 @@
1
+ """Knowledge Graph components."""