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/providers.py ADDED
@@ -0,0 +1,182 @@
1
+ # Copyright (c) Microsoft Corporation.
2
+ # Licensed under the MIT License.
3
+ """
4
+ Provider Discovery System
5
+
6
+ Enables plug-and-play upgrades from Public Preview to Advanced implementations.
7
+ When an advanced provider package is installed (e.g., agent-governance-providers),
8
+ factory functions automatically return the advanced implementation. Otherwise,
9
+ they return the built-in Public Preview.
10
+
11
+ Usage:
12
+ from agent_os.providers import get_verification_engine, get_self_correction_kernel
13
+
14
+ engine = get_verification_engine() # Advanced if available, else CE
15
+ kernel = get_self_correction_kernel() # Advanced if available, else CE
16
+
17
+ Advanced: pip install agent-governance-providers (from PyPI)
18
+ Community: pip install agent-os-kernel (from PyPI) — works out of the box
19
+ """
20
+
21
+ from __future__ import annotations
22
+
23
+ import logging
24
+ from importlib.metadata import entry_points
25
+ from typing import Any
26
+
27
+ logger = logging.getLogger(__name__)
28
+
29
+ # Entry point group names — internal packages register under these
30
+ PROVIDER_GROUPS = {
31
+ "verification": "agent_os.providers.verification",
32
+ "self_correction": "agent_os.providers.self_correction",
33
+ "policy_engine": "agent_os.providers.policy_engine",
34
+ "context_service": "agent_os.providers.context_service",
35
+ "memory": "agent_os.providers.memory",
36
+ "trust_protocol": "agent_os.providers.trust_protocol",
37
+ "mute_agent": "agent_os.providers.mute_agent",
38
+ }
39
+
40
+ # Cache loaded providers to avoid repeated discovery
41
+ _provider_cache: dict[str, Any] = {}
42
+
43
+
44
+ def _discover_provider(group: str) -> type | None:
45
+ """Discover an advanced provider via entry_points.
46
+
47
+ Returns the provider class if found, None otherwise.
48
+ """
49
+ if group in _provider_cache:
50
+ return _provider_cache[group]
51
+
52
+ try:
53
+ eps = entry_points(group=group)
54
+ if eps:
55
+ # Use the first registered provider (highest priority)
56
+ ep = next(iter(eps))
57
+ provider_cls = ep.load()
58
+ _provider_cache[group] = provider_cls
59
+ logger.info(
60
+ "Advanced provider loaded: %s from %s", ep.name, ep.value
61
+ )
62
+ return provider_cls
63
+ except Exception:
64
+ logger.debug("Provider discovery failed for %s", group, exc_info=True)
65
+
66
+ _provider_cache[group] = None
67
+ return None
68
+
69
+
70
+ def get_verification_engine(**kwargs: Any):
71
+ """Get the best available verification engine.
72
+
73
+ Advanced: Cross-model adversarial verification with strategy banning.
74
+ Community: Single-model self-check using difflib comparison.
75
+ """
76
+ provider = _discover_provider(PROVIDER_GROUPS["verification"])
77
+ if provider is not None:
78
+ return provider(**kwargs)
79
+
80
+ from cmvk.verification import VerificationEngine
81
+ return VerificationEngine(**kwargs)
82
+
83
+
84
+ def get_self_correction_kernel(**kwargs: Any):
85
+ """Get the best available self-correction kernel.
86
+
87
+ Advanced: Dual-loop OODA with differential auditing and semantic purge.
88
+ Community: Simple retry with exponential backoff.
89
+ """
90
+ provider = _discover_provider(PROVIDER_GROUPS["self_correction"])
91
+ if provider is not None:
92
+ return provider(**kwargs)
93
+
94
+ from agent_kernel.kernel import SelfCorrectingAgentKernel
95
+ return SelfCorrectingAgentKernel(**kwargs)
96
+
97
+
98
+ def get_policy_engine(**kwargs: Any):
99
+ """Get the best available policy engine.
100
+
101
+ Advanced: ABAC with attribute evaluation, constraint graphs, shadow mode.
102
+ Community: YAML-driven allow/deny rules with first-match semantics.
103
+ """
104
+ provider = _discover_provider(PROVIDER_GROUPS["policy_engine"])
105
+ if provider is not None:
106
+ return provider(**kwargs)
107
+
108
+ from agent_os.integrations.base import GovernancePolicy
109
+ return GovernancePolicy(**kwargs)
110
+
111
+
112
+ def get_context_service(**kwargs: Any):
113
+ """Get the best available context service.
114
+
115
+ Advanced: Hot/Warm/Cold tiers with heuristic routing and pragmatic truth.
116
+ Community: Single-tier context with TTL-based expiry.
117
+ """
118
+ provider = _discover_provider(PROVIDER_GROUPS["context_service"])
119
+ if provider is not None:
120
+ return provider(**kwargs)
121
+
122
+ from caas.triad import ContextTriadManager
123
+ return ContextTriadManager(**kwargs)
124
+
125
+
126
+ def get_memory_store(**kwargs: Any):
127
+ """Get the best available episodic memory store.
128
+
129
+ Advanced: Immutable append-only store with hash chaining (GARR).
130
+ Community: Mutable JSON file-based episode store.
131
+ """
132
+ provider = _discover_provider(PROVIDER_GROUPS["memory"])
133
+ if provider is not None:
134
+ return provider(**kwargs)
135
+
136
+ from emk.store import EpisodicMemoryStore
137
+ return EpisodicMemoryStore(**kwargs)
138
+
139
+
140
+ def get_trust_protocol(**kwargs: Any):
141
+ """Get the best available trust protocol engine.
142
+
143
+ Advanced: Full IATP with sidecar attestation and capability handshake.
144
+ Community: Basic policy engine with nonce-based verification.
145
+ """
146
+ provider = _discover_provider(PROVIDER_GROUPS["trust_protocol"])
147
+ if provider is not None:
148
+ return provider(**kwargs)
149
+
150
+ from iatp.policy_engine import IATPPolicyEngine
151
+ return IATPPolicyEngine(**kwargs)
152
+
153
+
154
+ def get_mute_agent(**kwargs: Any):
155
+ """Get the best available mute agent implementation.
156
+
157
+ Advanced: NULL response pattern with zero information leakage.
158
+ Community: Simple empty-string response on policy block.
159
+ """
160
+ provider = _discover_provider(PROVIDER_GROUPS["mute_agent"])
161
+ if provider is not None:
162
+ return provider(**kwargs)
163
+
164
+ from agent_os.mute_agent import MuteAgent
165
+ return MuteAgent(**kwargs)
166
+
167
+
168
+ def list_providers() -> dict[str, str]:
169
+ """List all provider slots and their current implementations.
170
+
171
+ Returns a dict of {slot_name: "advanced" | "community"}.
172
+ """
173
+ result = {}
174
+ for name, group in PROVIDER_GROUPS.items():
175
+ provider = _discover_provider(group)
176
+ result[name] = "advanced" if provider is not None else "community"
177
+ return result
178
+
179
+
180
+ def clear_cache() -> None:
181
+ """Clear the provider cache. Useful for testing."""
182
+ _provider_cache.clear()
agent_os/py.typed ADDED
File without changes
agent_os/retry.py ADDED
@@ -0,0 +1,81 @@
1
+ # Copyright (c) Microsoft Corporation.
2
+ # Licensed under the MIT License.
3
+ """Shared retry utilities for governance toolkit components."""
4
+ from __future__ import annotations
5
+
6
+ import asyncio
7
+ import functools
8
+ import logging
9
+ import time
10
+ from typing import Any, Callable, Sequence, TypeVar
11
+
12
+ logger = logging.getLogger(__name__)
13
+
14
+ T = TypeVar("T")
15
+
16
+
17
+ def retry(
18
+ max_attempts: int = 3,
19
+ backoff_base: float = 1.0,
20
+ exceptions: Sequence[type[BaseException]] = (Exception,),
21
+ on_retry: Callable[[int, BaseException], None] | None = None,
22
+ ) -> Callable:
23
+ """Decorator for retrying functions with exponential backoff.
24
+
25
+ Works with both sync and async functions.
26
+
27
+ Args:
28
+ max_attempts: Maximum number of attempts (including first try).
29
+ backoff_base: Base delay in seconds (doubled each retry).
30
+ exceptions: Tuple of exception types to catch and retry.
31
+ on_retry: Optional callback(attempt, exception) called before each retry.
32
+
33
+ Example:
34
+ @retry(max_attempts=3, exceptions=(ConnectionError, TimeoutError))
35
+ async def fetch_data(url: str) -> dict:
36
+ ...
37
+ """
38
+ def decorator(func: Callable) -> Callable:
39
+ if asyncio.iscoroutinefunction(func):
40
+ @functools.wraps(func)
41
+ async def async_wrapper(*args: Any, **kwargs: Any) -> Any:
42
+ last_exc: BaseException | None = None
43
+ for attempt in range(1, max_attempts + 1):
44
+ try:
45
+ return await func(*args, **kwargs)
46
+ except tuple(exceptions) as exc:
47
+ last_exc = exc
48
+ if attempt == max_attempts:
49
+ raise
50
+ delay = backoff_base * (2 ** (attempt - 1))
51
+ if on_retry:
52
+ on_retry(attempt, exc)
53
+ logger.warning(
54
+ "Retry %d/%d for %s after %s: %s",
55
+ attempt, max_attempts, func.__name__, type(exc).__name__, exc,
56
+ )
57
+ await asyncio.sleep(delay)
58
+ raise last_exc # unreachable but satisfies type checker
59
+ return async_wrapper
60
+ else:
61
+ @functools.wraps(func)
62
+ def sync_wrapper(*args: Any, **kwargs: Any) -> Any:
63
+ last_exc: BaseException | None = None
64
+ for attempt in range(1, max_attempts + 1):
65
+ try:
66
+ return func(*args, **kwargs)
67
+ except tuple(exceptions) as exc:
68
+ last_exc = exc
69
+ if attempt == max_attempts:
70
+ raise
71
+ delay = backoff_base * (2 ** (attempt - 1))
72
+ if on_retry:
73
+ on_retry(attempt, exc)
74
+ logger.warning(
75
+ "Retry %d/%d for %s after %s: %s",
76
+ attempt, max_attempts, func.__name__, type(exc).__name__, exc,
77
+ )
78
+ time.sleep(delay)
79
+ raise last_exc # unreachable but satisfies type checker
80
+ return sync_wrapper
81
+ return decorator
@@ -0,0 +1,251 @@
1
+ # Copyright (c) Microsoft Corporation.
2
+ # Licensed under the MIT License.
3
+ """Action reversibility assessment and compensation primitives.
4
+
5
+ Pre-execution check: is this action reversible? If not, require
6
+ additional approval or block entirely. Post-execution: provide
7
+ compensation actions to undo effects.
8
+
9
+ Addresses the criticism that AGT has no "rollback/reversibility
10
+ guarantees." Now every action can be assessed for reversibility
11
+ before execution, and compensation plans are generated for
12
+ irreversible operations.
13
+ """
14
+
15
+ from __future__ import annotations
16
+
17
+ from datetime import datetime, timezone
18
+ from enum import Enum
19
+ from typing import Any
20
+
21
+ from pydantic import BaseModel, Field
22
+
23
+
24
+ class ReversibilityLevel(str, Enum):
25
+ """How reversible an action is."""
26
+ FULLY_REVERSIBLE = "fully_reversible" # Can be undone completely (e.g., write a file)
27
+ PARTIALLY_REVERSIBLE = "partially_reversible" # Can be partially undone (e.g., send email — recall possible)
28
+ IRREVERSIBLE = "irreversible" # Cannot be undone (e.g., delete, deploy, send to external)
29
+ UNKNOWN = "unknown" # Reversibility cannot be determined
30
+
31
+
32
+ class CompensatingAction(BaseModel):
33
+ """An action that can undo or mitigate a previous action."""
34
+ description: str
35
+ action: str
36
+ parameters: dict[str, Any] = Field(default_factory=dict)
37
+ effectiveness: str = Field(
38
+ default="full",
39
+ description="full, partial, or mitigation-only",
40
+ )
41
+ time_window: str = Field(
42
+ default="",
43
+ description="Time window in which compensation is possible (e.g., '30 minutes')",
44
+ )
45
+
46
+
47
+ class ReversibilityAssessment(BaseModel):
48
+ """Pre-execution assessment of an action's reversibility."""
49
+ action: str
50
+ level: ReversibilityLevel
51
+ reason: str
52
+ compensating_actions: list[CompensatingAction] = Field(default_factory=list)
53
+ requires_extra_approval: bool = False
54
+ assessed_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
55
+
56
+
57
+ # Default reversibility classifications
58
+ _REVERSIBILITY_MAP: dict[str, dict[str, Any]] = {
59
+ # Fully reversible
60
+ "write_file": {
61
+ "level": ReversibilityLevel.FULLY_REVERSIBLE,
62
+ "reason": "File writes can be reverted by restoring previous version",
63
+ "compensating": [
64
+ CompensatingAction(
65
+ description="Restore previous file version",
66
+ action="restore_file_backup",
67
+ effectiveness="full",
68
+ )
69
+ ],
70
+ },
71
+ "create_file": {
72
+ "level": ReversibilityLevel.FULLY_REVERSIBLE,
73
+ "reason": "Created files can be deleted",
74
+ "compensating": [
75
+ CompensatingAction(
76
+ description="Delete the created file",
77
+ action="delete_file",
78
+ effectiveness="full",
79
+ )
80
+ ],
81
+ },
82
+ "database_write": {
83
+ "level": ReversibilityLevel.FULLY_REVERSIBLE,
84
+ "reason": "Database writes can be rolled back within transaction",
85
+ "compensating": [
86
+ CompensatingAction(
87
+ description="Rollback transaction",
88
+ action="rollback_transaction",
89
+ effectiveness="full",
90
+ time_window="within transaction scope",
91
+ )
92
+ ],
93
+ },
94
+ "create_pr": {
95
+ "level": ReversibilityLevel.FULLY_REVERSIBLE,
96
+ "reason": "Pull requests can be closed",
97
+ "compensating": [
98
+ CompensatingAction(
99
+ description="Close the pull request",
100
+ action="close_pr",
101
+ effectiveness="full",
102
+ )
103
+ ],
104
+ },
105
+
106
+ # Partially reversible
107
+ "send_email": {
108
+ "level": ReversibilityLevel.PARTIALLY_REVERSIBLE,
109
+ "reason": "Email recall may work within org, but external delivery cannot be undone",
110
+ "compensating": [
111
+ CompensatingAction(
112
+ description="Recall email (internal only)",
113
+ action="recall_email",
114
+ effectiveness="partial",
115
+ time_window="30 minutes",
116
+ ),
117
+ CompensatingAction(
118
+ description="Send correction/retraction",
119
+ action="send_correction",
120
+ effectiveness="mitigation-only",
121
+ ),
122
+ ],
123
+ },
124
+ "update_record": {
125
+ "level": ReversibilityLevel.PARTIALLY_REVERSIBLE,
126
+ "reason": "Previous value may be recoverable from audit log",
127
+ "compensating": [
128
+ CompensatingAction(
129
+ description="Restore from audit trail",
130
+ action="restore_from_audit",
131
+ effectiveness="partial",
132
+ )
133
+ ],
134
+ },
135
+
136
+ # Irreversible
137
+ "deploy": {
138
+ "level": ReversibilityLevel.IRREVERSIBLE,
139
+ "reason": "Production deployments affect live users immediately",
140
+ "compensating": [
141
+ CompensatingAction(
142
+ description="Rollback deployment",
143
+ action="rollback_deploy",
144
+ effectiveness="partial",
145
+ time_window="depends on deployment pipeline",
146
+ )
147
+ ],
148
+ "requires_extra_approval": True,
149
+ },
150
+ "delete_file": {
151
+ "level": ReversibilityLevel.IRREVERSIBLE,
152
+ "reason": "Deleted files may not be recoverable without backups",
153
+ "compensating": [
154
+ CompensatingAction(
155
+ description="Restore from backup if available",
156
+ action="restore_from_backup",
157
+ effectiveness="partial",
158
+ )
159
+ ],
160
+ "requires_extra_approval": True,
161
+ },
162
+ "delete_record": {
163
+ "level": ReversibilityLevel.IRREVERSIBLE,
164
+ "reason": "Deleted records may not be recoverable",
165
+ "compensating": [],
166
+ "requires_extra_approval": True,
167
+ },
168
+ "execute_trade": {
169
+ "level": ReversibilityLevel.IRREVERSIBLE,
170
+ "reason": "Executed trades are settled and cannot be undone",
171
+ "compensating": [
172
+ CompensatingAction(
173
+ description="Execute offsetting trade",
174
+ action="offsetting_trade",
175
+ effectiveness="mitigation-only",
176
+ )
177
+ ],
178
+ "requires_extra_approval": True,
179
+ },
180
+ "ssh_connect": {
181
+ "level": ReversibilityLevel.IRREVERSIBLE,
182
+ "reason": "Remote commands may have irreversible effects",
183
+ "compensating": [],
184
+ "requires_extra_approval": True,
185
+ },
186
+ "execute_code": {
187
+ "level": ReversibilityLevel.IRREVERSIBLE,
188
+ "reason": "Arbitrary code execution effects are unpredictable",
189
+ "compensating": [],
190
+ "requires_extra_approval": True,
191
+ },
192
+ }
193
+
194
+
195
+ class ReversibilityChecker:
196
+ """Assess action reversibility before execution.
197
+
198
+ Usage:
199
+ checker = ReversibilityChecker()
200
+ assessment = checker.assess("deploy")
201
+ if assessment.level == ReversibilityLevel.IRREVERSIBLE:
202
+ # require extra approval
203
+ ...
204
+ """
205
+
206
+ def __init__(
207
+ self,
208
+ custom_rules: dict[str, dict[str, Any]] | None = None,
209
+ block_irreversible: bool = False,
210
+ ) -> None:
211
+ self._rules = dict(_REVERSIBILITY_MAP)
212
+ if custom_rules:
213
+ self._rules.update(custom_rules)
214
+ self._block_irreversible = block_irreversible
215
+
216
+ def assess(self, action: str) -> ReversibilityAssessment:
217
+ """Assess the reversibility of an action before execution."""
218
+ rule = self._rules.get(action)
219
+
220
+ if not rule:
221
+ return ReversibilityAssessment(
222
+ action=action,
223
+ level=ReversibilityLevel.UNKNOWN,
224
+ reason=f"No reversibility data for action '{action}'",
225
+ requires_extra_approval=True,
226
+ )
227
+
228
+ return ReversibilityAssessment(
229
+ action=action,
230
+ level=rule["level"],
231
+ reason=rule["reason"],
232
+ compensating_actions=rule.get("compensating", []),
233
+ requires_extra_approval=rule.get("requires_extra_approval", False),
234
+ )
235
+
236
+ def is_safe(self, action: str) -> bool:
237
+ """Quick check: is this action safely reversible?"""
238
+ assessment = self.assess(action)
239
+ return assessment.level == ReversibilityLevel.FULLY_REVERSIBLE
240
+
241
+ def should_block(self, action: str) -> bool:
242
+ """Check if action should be blocked per policy."""
243
+ if not self._block_irreversible:
244
+ return False
245
+ assessment = self.assess(action)
246
+ return assessment.level == ReversibilityLevel.IRREVERSIBLE
247
+
248
+ def get_compensation_plan(self, action: str) -> list[CompensatingAction]:
249
+ """Get the compensation plan for an action."""
250
+ assessment = self.assess(action)
251
+ return assessment.compensating_actions