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
agent_os/supervisor.py ADDED
@@ -0,0 +1,148 @@
1
+ # Copyright (c) Microsoft Corporation.
2
+ # Licensed under the MIT License.
3
+ """
4
+ Supervisor Hierarchy — Enforces layered supervision with a deterministic trust root.
5
+
6
+ Level 0 (root) MUST be a deterministic (non-LLM) trust root.
7
+ Middle levels (1–N) may be agent-based supervisors.
8
+ Escalation always terminates at the trust root.
9
+
10
+ Example:
11
+ >>> from agent_os.trust_root import TrustRoot
12
+ >>> from agent_os.supervisor import SupervisorHierarchy
13
+ >>> from agent_os.integrations.base import GovernancePolicy
14
+ >>>
15
+ >>> root = TrustRoot(policies=[GovernancePolicy()])
16
+ >>> hierarchy = SupervisorHierarchy(trust_root=root)
17
+ >>> hierarchy.register_supervisor("trust-root", level=0, is_agent=False)
18
+ >>> hierarchy.register_supervisor("safety-agent", level=1, is_agent=True)
19
+ >>> hierarchy.validate_hierarchy()
20
+ []
21
+ """
22
+
23
+ from __future__ import annotations
24
+
25
+ from dataclasses import dataclass
26
+ from typing import Any
27
+
28
+ from agent_os.trust_root import TrustDecision, TrustRoot
29
+
30
+
31
+ @dataclass
32
+ class _Supervisor:
33
+ """Internal record for a registered supervisor."""
34
+
35
+ name: str
36
+ level: int
37
+ is_agent: bool = True
38
+
39
+
40
+ class SupervisorHierarchy:
41
+ """Manages the layered supervisor chain with a deterministic trust root.
42
+
43
+ Args:
44
+ trust_root: The deterministic TrustRoot that serves as level-0 authority.
45
+ """
46
+
47
+ def __init__(self, trust_root: TrustRoot) -> None:
48
+ self.trust_root = trust_root
49
+ self._supervisors: list[_Supervisor] = []
50
+
51
+ # ------------------------------------------------------------------
52
+ # Registration
53
+ # ------------------------------------------------------------------
54
+
55
+ def register_supervisor(
56
+ self,
57
+ name: str,
58
+ level: int,
59
+ is_agent: bool = True,
60
+ ) -> None:
61
+ """Register a supervisor at a given level.
62
+
63
+ Args:
64
+ name: Unique supervisor name.
65
+ level: Hierarchy level (0 = root, higher = closer to workers).
66
+ is_agent: Whether this supervisor is an LLM-based agent.
67
+ """
68
+ self._supervisors.append(_Supervisor(name=name, level=level, is_agent=is_agent))
69
+
70
+ # ------------------------------------------------------------------
71
+ # Validation
72
+ # ------------------------------------------------------------------
73
+
74
+ def validate_hierarchy(self) -> list[str]:
75
+ """Check hierarchy rules and return a list of violations (empty = valid).
76
+
77
+ Rules:
78
+ - Level 0 MUST exist and MUST be deterministic (not an LLM agent).
79
+ - Middle levels (1–N) may be agent-based.
80
+ - Each level present must have at least one supervisor.
81
+ """
82
+ violations: list[str] = []
83
+
84
+ level_0 = [s for s in self._supervisors if s.level == 0]
85
+ if not level_0:
86
+ violations.append("Level 0 (root) has no registered supervisor")
87
+ else:
88
+ for s in level_0:
89
+ if s.is_agent:
90
+ violations.append(
91
+ f"Level 0 supervisor '{s.name}' must be deterministic, not an LLM agent"
92
+ )
93
+
94
+ # Ensure no gaps in levels (every level between 0 and max has a supervisor)
95
+ if self._supervisors:
96
+ max_level = max(s.level for s in self._supervisors)
97
+ for lvl in range(1, max_level + 1):
98
+ if not any(s.level == lvl for s in self._supervisors):
99
+ violations.append(f"Level {lvl} has no registered supervisor")
100
+
101
+ return violations
102
+
103
+ # ------------------------------------------------------------------
104
+ # Authority chain & escalation
105
+ # ------------------------------------------------------------------
106
+
107
+ def get_authority_chain(self, action: dict[str, Any]) -> list[str]:
108
+ """Return the ordered chain of supervisor names that would evaluate *action*.
109
+
110
+ The chain goes from the lowest (closest to workers) up to the trust root.
111
+ """
112
+ sorted_supervisors = sorted(self._supervisors, key=lambda s: s.level, reverse=True)
113
+ return [s.name for s in sorted_supervisors]
114
+
115
+ def escalate(
116
+ self,
117
+ action: dict[str, Any],
118
+ from_level: int,
119
+ ) -> TrustDecision:
120
+ """Escalate *action* up the hierarchy starting above *from_level*.
121
+
122
+ Each level is consulted in descending order. If the action reaches
123
+ level 0 the trust root makes the **final, non-overridable** decision.
124
+
125
+ Args:
126
+ action: Dict with ``tool`` and ``arguments``.
127
+ from_level: The level that initiated escalation.
128
+
129
+ Returns:
130
+ TrustDecision from the trust root (always deterministic).
131
+ """
132
+ levels_above = sorted(
133
+ {s.level for s in self._supervisors if s.level < from_level},
134
+ reverse=True,
135
+ )
136
+
137
+ depth = 0
138
+ for _level in levels_above:
139
+ depth += 1
140
+ if depth > self.trust_root.max_escalation_depth:
141
+ return TrustDecision(
142
+ allowed=False,
143
+ reason="Max escalation depth exceeded",
144
+ policy_name="escalation_limit",
145
+ )
146
+
147
+ # Final decision always comes from the deterministic trust root
148
+ return self.trust_root.validate_action(action)
@@ -0,0 +1,148 @@
1
+ # Copyright (c) Microsoft Corporation.
2
+ # Licensed under the MIT License.
3
+ """Task outcome recording for RewardEngine trust scoring.
4
+
5
+ Provides severity-based scoring with diminishing returns and
6
+ time-based recovery for agent trust management.
7
+
8
+ Example::
9
+
10
+ recorder = TaskOutcomeRecorder()
11
+ recorder.record(agent_id="a1", outcome="success")
12
+ recorder.record(agent_id="a1", outcome="failure", severity=0.8)
13
+ score = recorder.get_score("a1")
14
+ """
15
+
16
+ from __future__ import annotations
17
+
18
+ import time
19
+ from dataclasses import dataclass, field
20
+ from typing import Any
21
+
22
+
23
+ @dataclass
24
+ class TaskOutcome:
25
+ """A recorded task outcome."""
26
+
27
+ agent_id: str
28
+ outcome: str # "success" | "failure"
29
+ severity: float = 0.5
30
+ timestamp: float = field(default_factory=time.time)
31
+ metadata: dict[str, Any] = field(default_factory=dict)
32
+
33
+
34
+ @dataclass
35
+ class AgentScoreState:
36
+ """Running score state for an agent."""
37
+
38
+ score: float = 0.7 # Start at neutral-positive
39
+ total_tasks: int = 0
40
+ successes: int = 0
41
+ failures: int = 0
42
+ last_updated: float = field(default_factory=time.time)
43
+
44
+
45
+ class TaskOutcomeRecorder:
46
+ """Records task outcomes and computes trust scores.
47
+
48
+ Features:
49
+ - Success boost with diminishing returns
50
+ - Severity-based failure penalties
51
+ - Time-based recovery (scores drift toward neutral over time)
52
+ - Per-agent score tracking
53
+ """
54
+
55
+ def __init__(
56
+ self,
57
+ success_boost: float = 0.05,
58
+ failure_base_penalty: float = 0.1,
59
+ recovery_rate: float = 0.01,
60
+ recovery_interval_seconds: float = 3600.0,
61
+ min_score: float = 0.0,
62
+ max_score: float = 1.0,
63
+ ) -> None:
64
+ self.success_boost = success_boost
65
+ self.failure_base_penalty = failure_base_penalty
66
+ self.recovery_rate = recovery_rate
67
+ self.recovery_interval = recovery_interval_seconds
68
+ self.min_score = min_score
69
+ self.max_score = max_score
70
+ self._agents: dict[str, AgentScoreState] = {}
71
+ self._history: list[TaskOutcome] = []
72
+
73
+ def record(
74
+ self,
75
+ agent_id: str,
76
+ outcome: str,
77
+ severity: float = 0.5,
78
+ **metadata: Any,
79
+ ) -> float:
80
+ """Record a task outcome and return updated score.
81
+
82
+ Args:
83
+ agent_id: The agent identifier.
84
+ outcome: "success" or "failure".
85
+ severity: 0.0-1.0, how severe (for failures) or impactful (for successes).
86
+ **metadata: Additional context.
87
+
88
+ Returns:
89
+ Updated trust score for the agent.
90
+ """
91
+ state = self._agents.setdefault(agent_id, AgentScoreState())
92
+
93
+ # Apply time-based recovery first
94
+ self._apply_recovery(state)
95
+
96
+ state.total_tasks += 1
97
+ entry = TaskOutcome(
98
+ agent_id=agent_id,
99
+ outcome=outcome,
100
+ severity=severity,
101
+ metadata=metadata,
102
+ )
103
+ self._history.append(entry)
104
+
105
+ if outcome == "success":
106
+ state.successes += 1
107
+ # Diminishing returns: boost decreases as score approaches max
108
+ headroom = self.max_score - state.score
109
+ boost = self.success_boost * severity * (headroom / self.max_score)
110
+ state.score = min(self.max_score, state.score + boost)
111
+ elif outcome == "failure":
112
+ state.failures += 1
113
+ penalty = self.failure_base_penalty * severity
114
+ state.score = max(self.min_score, state.score - penalty)
115
+
116
+ state.last_updated = time.time()
117
+ return state.score
118
+
119
+ def get_score(self, agent_id: str) -> float:
120
+ """Get current trust score for an agent."""
121
+ state = self._agents.get(agent_id)
122
+ if state is None:
123
+ return 0.7 # Default for unknown agents
124
+ self._apply_recovery(state)
125
+ return round(state.score, 4)
126
+
127
+ def get_stats(self, agent_id: str) -> dict[str, Any]:
128
+ """Get detailed stats for an agent."""
129
+ state = self._agents.get(agent_id)
130
+ if state is None:
131
+ return {"agent_id": agent_id, "score": 0.7, "total_tasks": 0}
132
+ return {
133
+ "agent_id": agent_id,
134
+ "score": round(state.score, 4),
135
+ "total_tasks": state.total_tasks,
136
+ "successes": state.successes,
137
+ "failures": state.failures,
138
+ "success_rate": round(state.successes / max(1, state.total_tasks), 3),
139
+ }
140
+
141
+ def _apply_recovery(self, state: AgentScoreState) -> None:
142
+ """Apply time-based score recovery toward neutral (0.7)."""
143
+ elapsed = time.time() - state.last_updated
144
+ intervals = elapsed / self.recovery_interval
145
+ if intervals > 0 and state.score < 0.7:
146
+ recovery = self.recovery_rate * intervals
147
+ state.score = min(0.7, state.score + recovery)
148
+ state.last_updated = time.time()
@@ -0,0 +1,181 @@
1
+ # Copyright (c) Microsoft Corporation.
2
+ # Licensed under the MIT License.
3
+ """EU AI Act Art. 13/50 transparency enforcement interceptor.
4
+
5
+ Ensures AI disclosure is delivered to users before tool execution,
6
+ supporting Art. 50(1) (AI interaction notice), Art. 50(3) (emotion
7
+ recognition notice), and Art. 13 (interpretable output documentation).
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ import logging
13
+ import time
14
+ from dataclasses import dataclass, field
15
+ from enum import Enum
16
+ from typing import Any
17
+
18
+ logger = logging.getLogger(__name__)
19
+
20
+
21
+ class TransparencyLevel(str, Enum):
22
+ """Disclosure level per EU AI Act risk classification."""
23
+
24
+ NONE = "none"
25
+ BASIC = "basic"
26
+ ENHANCED = "enhanced"
27
+ FULL = "full"
28
+
29
+
30
+ @dataclass
31
+ class ToolCallRequest:
32
+ """Minimal shim — real class imported from integrations.base at runtime."""
33
+
34
+ tool_name: str
35
+ arguments: dict[str, Any] = field(default_factory=dict)
36
+ call_id: str = ""
37
+ agent_id: str = ""
38
+ metadata: dict[str, Any] = field(default_factory=dict)
39
+
40
+
41
+ @dataclass
42
+ class ToolCallResult:
43
+ """Minimal shim — real class imported from integrations.base at runtime."""
44
+
45
+ allowed: bool
46
+ reason: str | None = None
47
+ modified_arguments: dict[str, Any] | None = None
48
+ audit_entry: dict[str, Any] | None = None
49
+
50
+
51
+ DISCLOSURE_TEXTS = {
52
+ TransparencyLevel.BASIC: (
53
+ "You are interacting with an AI system. Outputs are machine-generated "
54
+ "and may contain errors. (EU AI Act Art. 50(1))"
55
+ ),
56
+ TransparencyLevel.ENHANCED: (
57
+ "You are interacting with a high-risk AI system. Outputs are "
58
+ "machine-generated, subject to governance policy enforcement, and "
59
+ "logged for regulatory audit. Interpretability documentation is "
60
+ "available on request. (EU AI Act Art. 13, Art. 50(1))"
61
+ ),
62
+ TransparencyLevel.FULL: (
63
+ "You are interacting with a high-risk AI system under full "
64
+ "transparency obligations. All tool calls are policy-governed, "
65
+ "audited, and subject to human oversight. System accuracy "
66
+ "declarations and technical documentation are available. "
67
+ "(EU AI Act Art. 13, Art. 14, Art. 50)"
68
+ ),
69
+ }
70
+
71
+ EMOTION_RECOGNITION_NOTICE = (
72
+ "This system uses emotion recognition technology. You have the right "
73
+ "to be informed when such processing takes place. (EU AI Act Art. 50(3))"
74
+ )
75
+
76
+
77
+ class TransparencyInterceptor:
78
+ """EU AI Act Art. 13/50 transparency enforcement interceptor.
79
+
80
+ Blocks tool execution when required AI disclosure has not been
81
+ confirmed, and injects disclosure metadata into allowed results.
82
+
83
+ Args:
84
+ default_level: Transparency level applied when none is specified
85
+ in the request context.
86
+ require_disclosure_confirmation: If ``True``, tool calls are
87
+ blocked until ``confirm_disclosure`` is called for the session.
88
+ emotion_recognition_notice: If ``True``, requires emotion
89
+ recognition acknowledgement per Art. 50(3).
90
+ """
91
+
92
+ def __init__(
93
+ self,
94
+ default_level: TransparencyLevel = TransparencyLevel.BASIC,
95
+ require_disclosure_confirmation: bool = True,
96
+ emotion_recognition_notice: bool = False,
97
+ ) -> None:
98
+ self.default_level = default_level
99
+ self.require_disclosure_confirmation = require_disclosure_confirmation
100
+ self.emotion_recognition_notice = emotion_recognition_notice
101
+ self._confirmed_sessions: dict[str, float] = {}
102
+ self._emotion_acknowledged: dict[str, float] = {}
103
+
104
+ def intercept(self, request: ToolCallRequest) -> ToolCallResult:
105
+ """Check transparency requirements before allowing a tool call."""
106
+ session_id = request.metadata.get("session_id", request.agent_id or "default")
107
+ level = request.metadata.get("transparency_level", self.default_level)
108
+ if isinstance(level, str):
109
+ try:
110
+ level = TransparencyLevel(level)
111
+ except ValueError:
112
+ level = self.default_level
113
+
114
+ if level == TransparencyLevel.NONE:
115
+ return ToolCallResult(allowed=True)
116
+
117
+ # Check disclosure confirmation
118
+ if self.require_disclosure_confirmation:
119
+ if session_id not in self._confirmed_sessions:
120
+ logger.warning(
121
+ "Blocked %s: AI disclosure not confirmed for session %s",
122
+ request.tool_name,
123
+ session_id,
124
+ )
125
+ return ToolCallResult(
126
+ allowed=False,
127
+ reason=(
128
+ f"AI disclosure must be confirmed before tool execution. "
129
+ f"Required level: {level.value}. "
130
+ f"Call confirm_disclosure(session_id) first."
131
+ ),
132
+ )
133
+
134
+ # Check emotion recognition acknowledgement
135
+ if self.emotion_recognition_notice:
136
+ if session_id not in self._emotion_acknowledged:
137
+ logger.warning(
138
+ "Blocked %s: emotion recognition notice not acknowledged for %s",
139
+ request.tool_name,
140
+ session_id,
141
+ )
142
+ return ToolCallResult(
143
+ allowed=False,
144
+ reason=(
145
+ "Emotion recognition notice must be acknowledged "
146
+ "before tool execution. (Art. 50(3))"
147
+ ),
148
+ )
149
+
150
+ # Inject disclosure metadata
151
+ disclosure = {
152
+ "_ai_disclosure": {
153
+ "level": level.value,
154
+ "text": self.get_disclosure_text(level),
155
+ "confirmed_at": self._confirmed_sessions.get(session_id),
156
+ "emotion_recognition": self.emotion_recognition_notice,
157
+ }
158
+ }
159
+
160
+ return ToolCallResult(
161
+ allowed=True,
162
+ audit_entry=disclosure,
163
+ )
164
+
165
+ def confirm_disclosure(self, session_id: str) -> None:
166
+ """Mark AI disclosure as confirmed for a session."""
167
+ self._confirmed_sessions[session_id] = time.time()
168
+ logger.info("AI disclosure confirmed for session %s", session_id)
169
+
170
+ def acknowledge_emotion_recognition(self, session_id: str) -> None:
171
+ """Mark emotion recognition notice as acknowledged for a session."""
172
+ self._emotion_acknowledged[session_id] = time.time()
173
+ logger.info("Emotion recognition notice acknowledged for session %s", session_id)
174
+
175
+ def get_disclosure_text(self, level: TransparencyLevel) -> str:
176
+ """Get standard disclosure text for the given transparency level."""
177
+ return DISCLOSURE_TEXTS.get(level, DISCLOSURE_TEXTS[TransparencyLevel.BASIC])
178
+
179
+ def is_disclosure_confirmed(self, session_id: str) -> bool:
180
+ """Check if disclosure has been confirmed for a session."""
181
+ return session_id in self._confirmed_sessions
agent_os/trust_root.py ADDED
@@ -0,0 +1,128 @@
1
+ # Copyright (c) Microsoft Corporation.
2
+ # Licensed under the MIT License.
3
+ """
4
+ Deterministic Trust Root — Final authority for the supervisor hierarchy.
5
+
6
+ The trust root is a pure-code (non-LLM) policy checkpoint that sits at
7
+ the top of the supervisor chain. It evaluates actions using
8
+ GovernancePolicy rules and cannot be overridden by any agent.
9
+
10
+ Example:
11
+ >>> from agent_os.trust_root import TrustRoot, TrustDecision
12
+ >>> from agent_os.integrations.base import GovernancePolicy
13
+ >>>
14
+ >>> policy = GovernancePolicy(allowed_tools=["read_file"])
15
+ >>> root = TrustRoot(policies=[policy])
16
+ >>> decision = root.validate_action({"tool": "delete_file", "arguments": {}})
17
+ >>> decision.allowed # False
18
+ """
19
+
20
+ from __future__ import annotations
21
+
22
+ from dataclasses import dataclass
23
+ from typing import Any
24
+
25
+ from agent_os.integrations.base import GovernancePolicy
26
+
27
+
28
+ @dataclass
29
+ class TrustDecision:
30
+ """Result of a deterministic trust-root evaluation."""
31
+
32
+ allowed: bool
33
+ reason: str
34
+ policy_name: str
35
+ deterministic: bool = True
36
+
37
+
38
+ class TrustRoot:
39
+ """Deterministic (non-LLM) policy authority at the top of the supervisor hierarchy.
40
+
41
+ The trust root is the FINAL authority — it cannot be overridden by any agent.
42
+ All evaluations use pure code logic; no model inference is involved.
43
+
44
+ Args:
45
+ policies: List of GovernancePolicy instances to enforce.
46
+ max_escalation_depth: Maximum supervisor levels before forced rejection.
47
+ """
48
+
49
+ def __init__(
50
+ self,
51
+ policies: list[GovernancePolicy],
52
+ max_escalation_depth: int = 3,
53
+ ) -> None:
54
+ if not policies:
55
+ raise ValueError("TrustRoot requires at least one policy")
56
+ self.policies = policies
57
+ self.max_escalation_depth = max_escalation_depth
58
+
59
+ # ------------------------------------------------------------------
60
+ # Public API
61
+ # ------------------------------------------------------------------
62
+
63
+ def validate_action(self, action: dict[str, Any]) -> TrustDecision:
64
+ """Deterministic policy check against all registered policies.
65
+
66
+ Args:
67
+ action: Dict with at least ``tool`` (str) and ``arguments`` (dict).
68
+
69
+ Returns:
70
+ TrustDecision indicating whether the action is allowed.
71
+ """
72
+ tool = action.get("tool", "")
73
+ arguments = action.get("arguments", {})
74
+ args_str = str(arguments)
75
+
76
+ for policy in self.policies:
77
+ # Check allowed tools
78
+ if policy.allowed_tools and tool not in policy.allowed_tools:
79
+ return TrustDecision(
80
+ allowed=False,
81
+ reason=(
82
+ f"Tool '{tool}' not in allowed list: {policy.allowed_tools}"
83
+ ),
84
+ policy_name=policy.name,
85
+ )
86
+
87
+ # Check blocked patterns
88
+ matched = policy.matches_pattern(args_str)
89
+ if matched:
90
+ return TrustDecision(
91
+ allowed=False,
92
+ reason=f"Blocked pattern '{matched[0]}' detected in arguments",
93
+ policy_name=policy.name,
94
+ )
95
+
96
+ return TrustDecision(
97
+ allowed=True,
98
+ reason="All policies passed",
99
+ policy_name="aggregate",
100
+ )
101
+
102
+ def validate_supervisor(self, supervisor_config: dict[str, Any]) -> bool:
103
+ """Verify a supervisor agent meets trust requirements.
104
+
105
+ A supervisor at any level must declare a ``name`` and ``level``.
106
+ Level-0 supervisors **must not** be agent-based (``is_agent`` must be False).
107
+
108
+ Args:
109
+ supervisor_config: Dict with ``name``, ``level``, and optionally ``is_agent``.
110
+
111
+ Returns:
112
+ True if the supervisor configuration is acceptable.
113
+ """
114
+ level = supervisor_config.get("level")
115
+ is_agent = supervisor_config.get("is_agent", True)
116
+
117
+ if level is None or not supervisor_config.get("name"):
118
+ return False
119
+
120
+ # Root level must be deterministic — not an LLM agent
121
+ if level == 0 and is_agent:
122
+ return False
123
+
124
+ return True
125
+
126
+ def is_deterministic(self) -> bool:
127
+ """Guarantee that this trust root uses only deterministic logic."""
128
+ return True