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
@@ -0,0 +1,65 @@
1
+ # Copyright (c) Microsoft Corporation.
2
+ # Licensed under the MIT License.
3
+ """
4
+ Knowledge Graph Node and Edge definitions.
5
+ """
6
+
7
+ from typing import Any, Dict, List, Optional
8
+ from dataclasses import dataclass, field
9
+ from enum import Enum
10
+
11
+
12
+ class NodeType(Enum):
13
+ """Types of nodes in the knowledge graph."""
14
+ ACTION = "action"
15
+ CONSTRAINT = "constraint"
16
+ PRECONDITION = "precondition"
17
+ POSTCONDITION = "postcondition"
18
+ CONTEXT = "context"
19
+ RESOURCE = "resource"
20
+
21
+
22
+ class EdgeType(Enum):
23
+ """Types of edges in the knowledge graph."""
24
+ REQUIRES = "requires"
25
+ ENABLES = "enables"
26
+ CONFLICTS_WITH = "conflicts_with"
27
+ DEPENDS_ON = "depends_on"
28
+ PRODUCES = "produces"
29
+ CONSUMES = "consumes"
30
+
31
+
32
+ @dataclass
33
+ class Node:
34
+ """A node in the knowledge graph."""
35
+ id: str
36
+ node_type: NodeType
37
+ attributes: Dict[str, Any] = field(default_factory=dict)
38
+ metadata: Dict[str, Any] = field(default_factory=dict)
39
+
40
+ def matches_constraint(self, constraint: Dict[str, Any]) -> bool:
41
+ """Check if node matches given constraints."""
42
+ for key, value in constraint.items():
43
+ if key in self.attributes:
44
+ if self.attributes[key] != value:
45
+ return False
46
+ elif key in self.metadata:
47
+ if self.metadata[key] != value:
48
+ return False
49
+ else:
50
+ return False
51
+ return True
52
+
53
+
54
+ @dataclass
55
+ class Edge:
56
+ """An edge in the knowledge graph."""
57
+ source_id: str
58
+ target_id: str
59
+ edge_type: EdgeType
60
+ weight: float = 1.0
61
+ attributes: Dict[str, Any] = field(default_factory=dict)
62
+
63
+ def is_valid(self) -> bool:
64
+ """Check if edge is valid."""
65
+ return self.weight > 0 and self.source_id and self.target_id
@@ -0,0 +1,170 @@
1
+ # Copyright (c) Microsoft Corporation.
2
+ # Licensed under the MIT License.
3
+ """
4
+ Multidimensional Knowledge Graph implementation.
5
+ """
6
+
7
+ from typing import Dict, List, Optional, Any, Set
8
+ from .graph_elements import Node, Edge, NodeType, EdgeType
9
+ from .subgraph import Subgraph, Dimension
10
+
11
+
12
+ class MultidimensionalKnowledgeGraph:
13
+ """
14
+ A multidimensional knowledge graph that manages multiple dimensional subgraphs.
15
+ This implements the "Forest of Trees" approach where each dimension represents
16
+ a different view or constraint layer on the action space.
17
+ """
18
+
19
+ def __init__(self):
20
+ self.dimensions: Dict[str, Dimension] = {}
21
+ self.subgraphs: Dict[str, Subgraph] = {}
22
+ self._global_nodes: Dict[str, Node] = {}
23
+ self._global_edges: List[Edge] = []
24
+
25
+ def add_dimension(self, dimension: Dimension) -> None:
26
+ """Add a new dimension to the knowledge graph."""
27
+ self.dimensions[dimension.name] = dimension
28
+ self.subgraphs[dimension.name] = Subgraph(dimension)
29
+
30
+ def add_node_to_dimension(self, dimension_name: str, node: Node) -> None:
31
+ """Add a node to a specific dimensional subgraph."""
32
+ if dimension_name in self.subgraphs:
33
+ self.subgraphs[dimension_name].add_node(node)
34
+ self._global_nodes[node.id] = node
35
+
36
+ def add_edge_to_dimension(self, dimension_name: str, edge: Edge) -> None:
37
+ """Add an edge to a specific dimensional subgraph."""
38
+ if dimension_name in self.subgraphs:
39
+ self.subgraphs[dimension_name].add_edge(edge)
40
+ self._global_edges.append(edge)
41
+
42
+ def get_dimension(self, dimension_name: str) -> Optional[Dimension]:
43
+ """Get a dimension by name."""
44
+ return self.dimensions.get(dimension_name)
45
+
46
+ def get_subgraph(self, dimension_name: str) -> Optional[Subgraph]:
47
+ """Get a subgraph for a specific dimension."""
48
+ return self.subgraphs.get(dimension_name)
49
+
50
+ def get_all_dimensions(self) -> List[Dimension]:
51
+ """Get all dimensions, sorted by priority."""
52
+ return sorted(self.dimensions.values(), key=lambda d: d.priority, reverse=True)
53
+
54
+ def find_relevant_dimensions(self, context: Dict[str, Any]) -> List[str]:
55
+ """
56
+ Find dimensions that are relevant to the given context.
57
+ Returns dimension names sorted by priority.
58
+ """
59
+ relevant_dimensions = []
60
+
61
+ for dim_name, dimension in self.dimensions.items():
62
+ # Check if context matches dimension metadata
63
+ if self._dimension_matches_context(dimension, context):
64
+ relevant_dimensions.append(dim_name)
65
+
66
+ # Sort by priority
67
+ relevant_dimensions.sort(
68
+ key=lambda d: self.dimensions[d].priority,
69
+ reverse=True
70
+ )
71
+
72
+ return relevant_dimensions
73
+
74
+ def _dimension_matches_context(self, dimension: Dimension, context: Dict[str, Any]) -> bool:
75
+ """Check if a dimension is relevant to the given context."""
76
+ if not context:
77
+ return True
78
+
79
+ # Check if any context keys match dimension metadata
80
+ for key in context.keys():
81
+ if key in dimension.metadata:
82
+ return True
83
+
84
+ # If no specific metadata match, dimension is potentially relevant
85
+ return True
86
+
87
+ def get_pruned_action_space(
88
+ self,
89
+ dimension_name: str,
90
+ context: Dict[str, Any]
91
+ ) -> List[Node]:
92
+ """
93
+ Get the pruned action space for a specific dimension and context.
94
+ This is the core of the action space pruning mechanism.
95
+ """
96
+ subgraph = self.subgraphs.get(dimension_name)
97
+ if not subgraph:
98
+ return []
99
+
100
+ # Prune the subgraph based on context
101
+ pruned_subgraph = subgraph.prune_by_context(context)
102
+
103
+ # Return available actions
104
+ return pruned_subgraph.get_action_space()
105
+
106
+ def validate_action_across_dimensions(
107
+ self,
108
+ action_id: str,
109
+ dimension_names: List[str],
110
+ context: Optional[Dict[str, Any]] = None
111
+ ) -> bool:
112
+ """
113
+ Validate an action across multiple dimensions.
114
+ The action must be valid in all specified dimensions.
115
+ """
116
+ for dim_name in dimension_names:
117
+ subgraph = self.subgraphs.get(dim_name)
118
+ if not subgraph:
119
+ continue
120
+
121
+ if not subgraph.validate_action(action_id, context):
122
+ return False
123
+
124
+ return True
125
+
126
+ def find_all_missing_dependencies(
127
+ self,
128
+ action_id: str,
129
+ dimension_names: List[str],
130
+ context: Dict[str, Any]
131
+ ) -> Dict[str, List[str]]:
132
+ """
133
+ Find all missing dependencies for an action across all dimensions.
134
+ Returns a dictionary mapping dimension names to lists of missing dependencies.
135
+ """
136
+ all_missing = {}
137
+
138
+ for dim_name in dimension_names:
139
+ subgraph = self.subgraphs.get(dim_name)
140
+ if not subgraph:
141
+ continue
142
+
143
+ missing = subgraph.find_missing_dependencies(action_id, context)
144
+ if missing:
145
+ all_missing[dim_name] = missing
146
+
147
+ return all_missing
148
+
149
+ def get_action_constraints(
150
+ self,
151
+ action_id: str,
152
+ dimension_name: str
153
+ ) -> List[Node]:
154
+ """Get all constraints associated with an action in a dimension."""
155
+ subgraph = self.subgraphs.get(dimension_name)
156
+ if not subgraph:
157
+ return []
158
+
159
+ action_node = subgraph.get_node(action_id)
160
+ if not action_node:
161
+ return []
162
+
163
+ constraints = []
164
+ for edge in subgraph._adjacency_list.get(action_id, []):
165
+ if edge.edge_type == EdgeType.REQUIRES:
166
+ target_node = subgraph.get_node(edge.target_id)
167
+ if target_node and target_node.node_type == NodeType.CONSTRAINT:
168
+ constraints.append(target_node)
169
+
170
+ return constraints
@@ -0,0 +1,224 @@
1
+ # Copyright (c) Microsoft Corporation.
2
+ # Licensed under the MIT License.
3
+ """
4
+ Dimensional subgraph implementation.
5
+ """
6
+
7
+ from typing import Dict, List, Set, Optional, Any
8
+ from dataclasses import dataclass, field
9
+ from .graph_elements import Node, Edge, NodeType, EdgeType
10
+
11
+
12
+ # Wildcard constant for matching any value in context
13
+ WILDCARD_VALUE = "*"
14
+
15
+
16
+ @dataclass
17
+ class Dimension:
18
+ """A dimension in the multidimensional knowledge graph."""
19
+ name: str
20
+ description: str
21
+ priority: int = 0
22
+ metadata: Dict[str, Any] = field(default_factory=dict)
23
+
24
+
25
+ class Subgraph:
26
+ """A subgraph representing a specific dimensional view of the knowledge graph."""
27
+
28
+ def __init__(self, dimension: Dimension):
29
+ self.dimension = dimension
30
+ self.nodes: Dict[str, Node] = {}
31
+ self.edges: List[Edge] = []
32
+ self._adjacency_list: Dict[str, List[Edge]] = {}
33
+
34
+ def add_node(self, node: Node) -> None:
35
+ """Add a node to the subgraph."""
36
+ self.nodes[node.id] = node
37
+ if node.id not in self._adjacency_list:
38
+ self._adjacency_list[node.id] = []
39
+
40
+ def add_edge(self, edge: Edge) -> None:
41
+ """Add an edge to the subgraph."""
42
+ if edge.is_valid():
43
+ self.edges.append(edge)
44
+ if edge.source_id not in self._adjacency_list:
45
+ self._adjacency_list[edge.source_id] = []
46
+ self._adjacency_list[edge.source_id].append(edge)
47
+
48
+ def get_node(self, node_id: str) -> Optional[Node]:
49
+ """Get a node by ID."""
50
+ return self.nodes.get(node_id)
51
+
52
+ def get_neighbors(self, node_id: str) -> List[Node]:
53
+ """Get neighboring nodes."""
54
+ neighbors = []
55
+ for edge in self._adjacency_list.get(node_id, []):
56
+ if edge.target_id in self.nodes:
57
+ neighbors.append(self.nodes[edge.target_id])
58
+ return neighbors
59
+
60
+ def find_nodes_by_type(self, node_type: NodeType) -> List[Node]:
61
+ """Find all nodes of a specific type."""
62
+ return [node for node in self.nodes.values() if node.node_type == node_type]
63
+
64
+ def find_nodes_by_constraint(self, constraint: Dict[str, Any]) -> List[Node]:
65
+ """Find nodes matching specific constraints."""
66
+ return [node for node in self.nodes.values() if node.matches_constraint(constraint)]
67
+
68
+ def get_action_space(self) -> List[Node]:
69
+ """Get all available actions in this subgraph."""
70
+ return self.find_nodes_by_type(NodeType.ACTION)
71
+
72
+ def validate_action(self, action_id: str, context: Optional[Dict[str, Any]] = None) -> bool:
73
+ """Validate if an action can be executed based on graph constraints."""
74
+ if action_id not in self.nodes:
75
+ return False
76
+
77
+ action_node = self.nodes[action_id]
78
+ if action_node.node_type != NodeType.ACTION:
79
+ return False
80
+
81
+ # Check preconditions
82
+ for edge in self._adjacency_list.get(action_id, []):
83
+ if edge.edge_type == EdgeType.REQUIRES:
84
+ target_node = self.nodes.get(edge.target_id)
85
+ if not target_node:
86
+ return False
87
+ # If context provided, check if requirement is satisfied
88
+ if context:
89
+ if not self._is_requirement_satisfied(target_node, context):
90
+ return False
91
+
92
+ return True
93
+
94
+ def _is_requirement_satisfied(self, requirement_node: Node, context: Dict[str, Any]) -> bool:
95
+ """Check if a requirement node is satisfied by the context."""
96
+ # Check if the requirement exists in context
97
+ req_id = requirement_node.id
98
+
99
+ # Check if context explicitly marks this requirement as satisfied
100
+ if f"{req_id}_satisfied" in context:
101
+ return context[f"{req_id}_satisfied"]
102
+
103
+ # Check if requirement attributes are present in context
104
+ for key, expected_value in requirement_node.attributes.items():
105
+ if key in context:
106
+ if context[key] == expected_value:
107
+ return True
108
+
109
+ return False
110
+
111
+ def find_missing_dependencies(self, action_id: str, context: Dict[str, Any]) -> List[str]:
112
+ """
113
+ Find all missing dependencies for an action (deep traversal).
114
+ Returns a list of missing dependency IDs in order from root to leaf.
115
+ Handles circular dependencies gracefully.
116
+ """
117
+ if action_id not in self.nodes:
118
+ return [f"Action '{action_id}' not found"]
119
+
120
+ visited = set()
121
+ in_progress = set() # Track nodes currently being processed for cycle detection
122
+ missing_deps = []
123
+
124
+ def traverse_dependencies(node_id: str, path: List[str]) -> None:
125
+ """Recursively traverse dependencies to find missing ones."""
126
+ if node_id in visited:
127
+ return
128
+
129
+ # Cycle detection: if we're currently processing this node, we have a cycle
130
+ if node_id in in_progress:
131
+ return # Skip circular dependency
132
+
133
+ in_progress.add(node_id)
134
+
135
+ # Get all requirements for this node
136
+ for edge in self._adjacency_list.get(node_id, []):
137
+ if edge.edge_type == EdgeType.REQUIRES:
138
+ target_node = self.nodes.get(edge.target_id)
139
+ if target_node:
140
+ # Check if this requirement is satisfied
141
+ if not self._is_requirement_satisfied(target_node, context):
142
+ # This dependency is missing, check its dependencies first
143
+ traverse_dependencies(edge.target_id, path + [node_id])
144
+ # Add to missing list if not already there
145
+ if edge.target_id not in missing_deps:
146
+ missing_deps.append(edge.target_id)
147
+
148
+ in_progress.remove(node_id)
149
+ visited.add(node_id)
150
+
151
+ traverse_dependencies(action_id, [])
152
+ return missing_deps
153
+
154
+ def get_dependency_chain(self, action_id: str) -> List[List[str]]:
155
+ """
156
+ Get all dependency chains for an action.
157
+ Returns a list of chains, where each chain is a list of node IDs.
158
+ Handles circular dependencies by detecting and skipping cycles.
159
+ """
160
+ if action_id not in self.nodes:
161
+ return []
162
+
163
+ chains = []
164
+ visited_in_chain = set() # Track nodes in current chain for cycle detection
165
+
166
+ def traverse_chain(node_id: str, current_chain: List[str]) -> None:
167
+ """Recursively build dependency chains with cycle detection."""
168
+ # Cycle detection: if node is already in current chain, we have a cycle
169
+ if node_id in visited_in_chain:
170
+ return
171
+
172
+ visited_in_chain.add(node_id)
173
+
174
+ # Get all requirements for this node
175
+ requirements = []
176
+ for edge in self._adjacency_list.get(node_id, []):
177
+ if edge.edge_type == EdgeType.REQUIRES:
178
+ requirements.append(edge.target_id)
179
+
180
+ if not requirements:
181
+ # End of chain
182
+ chains.append(current_chain[:])
183
+ else:
184
+ # Continue traversing
185
+ for req_id in requirements:
186
+ if req_id in self.nodes:
187
+ traverse_chain(req_id, current_chain + [req_id])
188
+
189
+ visited_in_chain.remove(node_id)
190
+
191
+ traverse_chain(action_id, [action_id])
192
+ return chains
193
+
194
+ def prune_by_context(self, context: Dict[str, Any]) -> "Subgraph":
195
+ """Create a pruned version of this subgraph based on context."""
196
+ pruned = Subgraph(self.dimension)
197
+
198
+ # Add nodes that match the context
199
+ for node in self.nodes.values():
200
+ if self._node_matches_context(node, context):
201
+ pruned.add_node(node)
202
+
203
+ # Add edges between matching nodes
204
+ for edge in self.edges:
205
+ if edge.source_id in pruned.nodes and edge.target_id in pruned.nodes:
206
+ pruned.add_edge(edge)
207
+
208
+ return pruned
209
+
210
+ def _node_matches_context(self, node: Node, context: Dict[str, Any]) -> bool:
211
+ """Check if a node is relevant to the given context."""
212
+ if not context:
213
+ return True
214
+
215
+ # Check if any context attributes match node attributes
216
+ for key, value in context.items():
217
+ if key in node.attributes:
218
+ if node.attributes[key] == value or value == WILDCARD_VALUE:
219
+ return True
220
+ if key in node.metadata:
221
+ if node.metadata[key] == value or value == WILDCARD_VALUE:
222
+ return True
223
+
224
+ return False
@@ -0,0 +1,43 @@
1
+ # Copyright (c) Microsoft Corporation.
2
+ # Licensed under the MIT License.
3
+ """
4
+ Layer 5: Listener Agent - Reference Implementation
5
+
6
+ This module provides the Listener Agent, a passive observer that monitors
7
+ graph states and only intervenes when configured thresholds are exceeded.
8
+
9
+ The Listener consolidates the full stack:
10
+ - agent-control-plane (base orchestration)
11
+ - scak (intelligence/knowledge)
12
+ - iatp (security/trust)
13
+ - caas (context awareness)
14
+
15
+ This is pure wiring - no logic that belongs in lower layers is redefined here.
16
+ """
17
+
18
+ from .listener import ListenerAgent, ListenerState, InterventionEvent, ListenerConfig
19
+ from .threshold_config import (
20
+ ThresholdConfig,
21
+ ThresholdType,
22
+ InterventionLevel,
23
+ ThresholdRule,
24
+ DEFAULT_THRESHOLDS,
25
+ )
26
+ from .state_observer import StateObserver, ObservationResult
27
+
28
+ __all__ = [
29
+ # Core Listener
30
+ "ListenerAgent",
31
+ "ListenerState",
32
+ "InterventionEvent",
33
+ "ListenerConfig",
34
+ # Configuration
35
+ "ThresholdConfig",
36
+ "ThresholdType",
37
+ "InterventionLevel",
38
+ "ThresholdRule",
39
+ "DEFAULT_THRESHOLDS",
40
+ # Observer
41
+ "StateObserver",
42
+ "ObservationResult",
43
+ ]
@@ -0,0 +1,31 @@
1
+ # Copyright (c) Microsoft Corporation.
2
+ # Licensed under the MIT License.
3
+ """
4
+ Adapters for Layer 5 Integration
5
+
6
+ These adapters provide clean interfaces to the lower-layer dependencies:
7
+ - agent-control-plane: Base orchestration
8
+ - scak: Intelligence/Knowledge layer
9
+ - iatp: Security/Trust layer
10
+ - caas: Context-as-a-Service layer
11
+
12
+ The Listener Agent uses these adapters to wire together the full stack
13
+ without reimplementing any lower-layer logic.
14
+ """
15
+
16
+ from .base_adapter import BaseLayerAdapter, AdapterProtocol
17
+ from .scak_adapter import IntelligenceAdapter
18
+ from .iatp_adapter import SecurityAdapter
19
+ from .caas_adapter import ContextAdapter
20
+ from .control_plane_adapter import ControlPlaneAdapter
21
+
22
+ __all__ = [
23
+ # Base
24
+ "BaseLayerAdapter",
25
+ "AdapterProtocol",
26
+ # Layer adapters
27
+ "IntelligenceAdapter",
28
+ "SecurityAdapter",
29
+ "ContextAdapter",
30
+ "ControlPlaneAdapter",
31
+ ]