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,422 @@
1
+ # Copyright (c) Microsoft Corporation.
2
+ # Licensed under the MIT License.
3
+
4
+ """
5
+ The Mute Agent - Scale by Subtraction
6
+
7
+ The Mute Agent represents the philosophy of "Scale by Subtraction" - removing
8
+ creativity and ensuring agents fail fast with NULL responses when requests
9
+ are out of scope, rather than hallucinating or being conversational.
10
+
11
+ This module provides capabilities for agents to strictly operate within
12
+ their defined constraints and return NULL/silence for out-of-scope requests.
13
+
14
+ Research Foundations:
15
+ - Capability-based security model (principle of least privilege)
16
+ - "If a system can't do something, it can't be tricked into doing it"
17
+ - Fail-safe defaults from secure system design
18
+ - Inspired by NULL semantics in type systems and databases
19
+
20
+ See docs/RESEARCH_FOUNDATION.md for complete references.
21
+
22
+ DEPRECATION NOTICE:
23
+ This module is being refactored to use the plugin interface pattern.
24
+ New code should use CapabilityValidatorInterface from
25
+ agent_control_plane.interfaces instead of directly importing this module.
26
+
27
+ The MuteAgentValidator class now implements CapabilityValidatorInterface
28
+ and can be registered with the PluginRegistry for dependency injection.
29
+ """
30
+
31
+ import warnings
32
+ from typing import Any, Dict, Optional, List, Callable, Tuple
33
+ from dataclasses import dataclass, field
34
+ from datetime import datetime
35
+ from .agent_kernel import ActionType, ExecutionRequest
36
+ from .interfaces.plugin_interface import (
37
+ CapabilityValidatorInterface,
38
+ ValidationResult,
39
+ PluginMetadata,
40
+ PluginCapability,
41
+ )
42
+
43
+
44
+ @dataclass
45
+ class AgentCapability:
46
+ """Defines a specific capability an agent has"""
47
+ name: str
48
+ description: str
49
+ action_types: List[ActionType]
50
+ parameter_schema: Dict[str, Any] # JSON schema for parameters
51
+ validator: Optional[Callable[[ExecutionRequest], bool]] = None
52
+
53
+
54
+ @dataclass
55
+ class MuteAgentConfig:
56
+ """Configuration for a Mute Agent"""
57
+ agent_id: str
58
+ capabilities: List[AgentCapability] = field(default_factory=list)
59
+ strict_mode: bool = True # If True, reject anything outside capabilities
60
+ null_response_message: str = "NULL" # Response for out-of-scope requests
61
+ enable_explanation: bool = False # If True, explain why request was rejected
62
+
63
+
64
+ class MuteAgentValidator(CapabilityValidatorInterface):
65
+ """
66
+ Validates requests against agent capabilities.
67
+
68
+ The Mute Agent knows when to shut up. If a request doesn't map to a
69
+ defined capability, it returns NULL instead of hallucinating or trying
70
+ to be helpful in creative ways.
71
+
72
+ This class implements CapabilityValidatorInterface for use with the
73
+ PluginRegistry and dependency injection pattern.
74
+
75
+ DEPRECATION NOTICE:
76
+ Direct instantiation of MuteAgentValidator is deprecated.
77
+ Instead, use the PluginRegistry to register validators:
78
+
79
+ ```python
80
+ from agent_control_plane import PluginRegistry
81
+
82
+ registry = PluginRegistry()
83
+ validator = MuteAgentValidator(config)
84
+ registry.register_validator(validator)
85
+ ```
86
+ """
87
+
88
+ def __init__(self, config: MuteAgentConfig):
89
+ self.config = config
90
+ self.rejection_log: List[Dict[str, Any]] = []
91
+ self._agent_capabilities: Dict[str, List[AgentCapability]] = {
92
+ config.agent_id: config.capabilities
93
+ }
94
+
95
+ @property
96
+ def metadata(self) -> PluginMetadata:
97
+ """Return metadata about this validator plugin"""
98
+ return PluginMetadata(
99
+ name=f"mute_agent_validator_{self.config.agent_id}",
100
+ version="1.1.0",
101
+ description="Capability-based validator implementing Scale by Subtraction philosophy",
102
+ plugin_type="validator",
103
+ capabilities=[
104
+ PluginCapability.REQUEST_VALIDATION,
105
+ PluginCapability.CAPABILITY_CHECKING,
106
+ PluginCapability.PARAMETER_VALIDATION,
107
+ ]
108
+ )
109
+
110
+ def validate_request(
111
+ self,
112
+ request: Any,
113
+ context: Optional[Dict[str, Any]] = None
114
+ ) -> ValidationResult:
115
+ """
116
+ Validate if request maps to a defined capability.
117
+
118
+ Implements CapabilityValidatorInterface.validate_request()
119
+
120
+ Args:
121
+ request: ExecutionRequest to validate
122
+ context: Optional additional context
123
+
124
+ Returns:
125
+ ValidationResult with approval/denial and details
126
+ """
127
+ # Support both ExecutionRequest and dict-based requests
128
+ if hasattr(request, 'action_type'):
129
+ action_type = request.action_type
130
+ request_id = getattr(request, 'request_id', 'unknown')
131
+ timestamp = getattr(request, 'timestamp', datetime.now())
132
+ else:
133
+ action_type = request.get('action_type')
134
+ request_id = request.get('request_id', 'unknown')
135
+ timestamp = request.get('timestamp', datetime.now())
136
+
137
+ # Check if action type is within any capability
138
+ matching_capabilities = [
139
+ cap for cap in self.config.capabilities
140
+ if action_type in cap.action_types
141
+ ]
142
+
143
+ if not matching_capabilities:
144
+ reason = self._format_rejection_reason(
145
+ action_type,
146
+ "Action type not in agent capabilities"
147
+ )
148
+ self._log_rejection(request_id, action_type, reason, timestamp)
149
+ return ValidationResult(
150
+ is_valid=False,
151
+ reason=reason,
152
+ details={"action_type": str(action_type), "available_capabilities": [c.name for c in self.config.capabilities]}
153
+ )
154
+
155
+ # Validate parameters against capability schema
156
+ for capability in matching_capabilities:
157
+ if capability.validator and hasattr(request, 'action_type'):
158
+ if not capability.validator(request):
159
+ reason = self._format_rejection_reason(
160
+ action_type,
161
+ f"Parameters do not match capability: {capability.name}"
162
+ )
163
+ self._log_rejection(request_id, action_type, reason, timestamp)
164
+ return ValidationResult(
165
+ is_valid=False,
166
+ reason=reason,
167
+ details={"capability": capability.name}
168
+ )
169
+
170
+ return ValidationResult(is_valid=True)
171
+
172
+ # Legacy method for backward compatibility
173
+ def validate_request_legacy(self, request: ExecutionRequest) -> Tuple[bool, Optional[str]]:
174
+ """
175
+ Legacy validation method for backward compatibility.
176
+
177
+ DEPRECATED: Use validate_request() instead which returns ValidationResult.
178
+
179
+ Returns:
180
+ (is_valid, reason_if_invalid)
181
+ """
182
+ warnings.warn(
183
+ "validate_request_legacy is deprecated, use validate_request() instead",
184
+ DeprecationWarning,
185
+ stacklevel=2
186
+ )
187
+ result = self.validate_request(request)
188
+ return result.is_valid, result.reason
189
+
190
+ def validate_action(
191
+ self,
192
+ action_type: ActionType,
193
+ parameters: Dict[str, Any]
194
+ ) -> Tuple[bool, Optional[str]]:
195
+ """
196
+ Lightweight validation without creating an ExecutionRequest.
197
+
198
+ Returns:
199
+ (is_valid, reason_if_invalid)
200
+ """
201
+ # Check if action type is within any capability
202
+ matching_capabilities = [
203
+ cap for cap in self.config.capabilities
204
+ if action_type in cap.action_types
205
+ ]
206
+
207
+ if not matching_capabilities:
208
+ reason = self._format_rejection_reason(
209
+ action_type,
210
+ "Action type not in agent capabilities"
211
+ )
212
+ return False, reason
213
+
214
+ # Note: Cannot validate with validator since it expects ExecutionRequest
215
+ # This is a tradeoff for performance - full validation requires ExecutionRequest
216
+ return True, None
217
+
218
+ # =========================================================================
219
+ # CapabilityValidatorInterface implementation
220
+ # =========================================================================
221
+
222
+ def define_capability(
223
+ self,
224
+ agent_id: str,
225
+ capability_name: str,
226
+ allowed_actions: List[str],
227
+ parameter_schema: Dict[str, Any],
228
+ validator: Optional[Callable[[Any], bool]] = None
229
+ ) -> None:
230
+ """
231
+ Define a capability for an agent.
232
+
233
+ Implements CapabilityValidatorInterface.define_capability()
234
+ """
235
+ # Convert string action types to ActionType enums
236
+ action_types = []
237
+ for action in allowed_actions:
238
+ try:
239
+ action_types.append(ActionType(action))
240
+ except ValueError:
241
+ # Skip unknown action types
242
+ pass
243
+
244
+ capability = AgentCapability(
245
+ name=capability_name,
246
+ description=f"Capability {capability_name} for agent {agent_id}",
247
+ action_types=action_types,
248
+ parameter_schema=parameter_schema,
249
+ validator=validator
250
+ )
251
+
252
+ if agent_id not in self._agent_capabilities:
253
+ self._agent_capabilities[agent_id] = []
254
+ self._agent_capabilities[agent_id].append(capability)
255
+
256
+ # Also add to config if this is for the configured agent
257
+ if agent_id == self.config.agent_id:
258
+ self.config.capabilities.append(capability)
259
+
260
+ def get_agent_capabilities(self, agent_id: str) -> List[Dict[str, Any]]:
261
+ """Get all capabilities defined for an agent"""
262
+ capabilities = self._agent_capabilities.get(agent_id, [])
263
+ return [
264
+ {
265
+ "name": cap.name,
266
+ "description": cap.description,
267
+ "action_types": [at.value for at in cap.action_types],
268
+ "parameter_schema": cap.parameter_schema,
269
+ "has_validator": cap.validator is not None
270
+ }
271
+ for cap in capabilities
272
+ ]
273
+
274
+ def get_null_response(self) -> str:
275
+ """Get the NULL response message for out-of-scope requests"""
276
+ return self.config.null_response_message
277
+
278
+ def get_rejection_log(self, agent_id: Optional[str] = None) -> List[Dict[str, Any]]:
279
+ """Get log of rejected (out-of-scope) requests"""
280
+ if agent_id:
281
+ return [r for r in self.rejection_log if r.get("agent_id") == agent_id]
282
+ return self.rejection_log.copy()
283
+
284
+ # =========================================================================
285
+ # Internal methods
286
+ # =========================================================================
287
+
288
+ def _format_rejection_reason(self, action_type: ActionType, reason: str) -> str:
289
+ """Format rejection reason based on agent configuration"""
290
+ if self.config.enable_explanation:
291
+ return f"Request rejected: {reason}. Available capabilities: {[c.name for c in self.config.capabilities]}"
292
+ else:
293
+ return self.config.null_response_message
294
+
295
+ def _log_rejection(self, request_id: str, action_type: ActionType, reason: str, timestamp: datetime):
296
+ """Log rejected requests for analysis"""
297
+ self.rejection_log.append({
298
+ "request_id": request_id,
299
+ "agent_id": self.config.agent_id,
300
+ "action_type": action_type.value if hasattr(action_type, 'value') else str(action_type),
301
+ "reason": reason,
302
+ "timestamp": timestamp.isoformat() if hasattr(timestamp, 'isoformat') else str(timestamp)
303
+ })
304
+
305
+
306
+ def create_sql_agent_capabilities() -> List[AgentCapability]:
307
+ """
308
+ Example: Create capabilities for a SQL-generating agent
309
+
310
+ This agent can only query databases, not modify them.
311
+ If asked to "build a rocket ship", it returns NULL instead of hallucinating.
312
+ """
313
+
314
+ def validate_sql_query(request: ExecutionRequest) -> bool:
315
+ """Validate that SQL query is read-only"""
316
+ import re
317
+ query = request.parameters.get('query', '').upper()
318
+ # Only SELECT queries allowed
319
+ if not query.strip().startswith('SELECT'):
320
+ return False
321
+ # No destructive operations (use word boundaries to avoid false matches)
322
+ destructive = ['DROP', 'DELETE', 'INSERT', 'UPDATE', 'ALTER', 'CREATE', 'TRUNCATE']
323
+ for op in destructive:
324
+ # Use word boundary matching to avoid matching "CREATED_AT" with "CREATE"
325
+ if re.search(r'\b' + op + r'\b', query):
326
+ return False
327
+ return True
328
+
329
+ return [
330
+ AgentCapability(
331
+ name="query_database",
332
+ description="Execute read-only SQL queries",
333
+ action_types=[ActionType.DATABASE_QUERY],
334
+ parameter_schema={
335
+ "type": "object",
336
+ "properties": {
337
+ "query": {"type": "string"},
338
+ "database": {"type": "string"}
339
+ },
340
+ "required": ["query"]
341
+ },
342
+ validator=validate_sql_query
343
+ )
344
+ ]
345
+
346
+
347
+ def create_data_analyst_capabilities() -> List[AgentCapability]:
348
+ """
349
+ Example: Create capabilities for a data analyst agent
350
+
351
+ This agent can read files and query databases, but cannot modify anything.
352
+ """
353
+
354
+ def validate_safe_file_path(request: ExecutionRequest) -> bool:
355
+ """Only allow access to /data directory"""
356
+ path = request.parameters.get('path', '')
357
+ return path.startswith('/data/') or path.startswith('./data/')
358
+
359
+ return [
360
+ AgentCapability(
361
+ name="read_data_file",
362
+ description="Read data files from /data directory",
363
+ action_types=[ActionType.FILE_READ],
364
+ parameter_schema={
365
+ "type": "object",
366
+ "properties": {
367
+ "path": {"type": "string", "pattern": "^(/data/|\\./data/).*"}
368
+ },
369
+ "required": ["path"]
370
+ },
371
+ validator=validate_safe_file_path
372
+ ),
373
+ AgentCapability(
374
+ name="query_analytics",
375
+ description="Execute analytics queries",
376
+ action_types=[ActionType.DATABASE_QUERY],
377
+ parameter_schema={
378
+ "type": "object",
379
+ "properties": {
380
+ "query": {"type": "string"},
381
+ "database": {"type": "string"}
382
+ },
383
+ "required": ["query"]
384
+ }
385
+ )
386
+ ]
387
+
388
+
389
+ def create_mute_sql_agent(agent_id: str) -> MuteAgentConfig:
390
+ """
391
+ Create a Mute SQL Agent configuration
392
+
393
+ This agent:
394
+ - Only executes SELECT queries
395
+ - Returns NULL for anything outside this capability
396
+ - Does not try to be conversational or creative
397
+ """
398
+ return MuteAgentConfig(
399
+ agent_id=agent_id,
400
+ capabilities=create_sql_agent_capabilities(),
401
+ strict_mode=True,
402
+ null_response_message="NULL",
403
+ enable_explanation=False
404
+ )
405
+
406
+
407
+ def create_mute_data_analyst(agent_id: str, enable_explanation: bool = False) -> MuteAgentConfig:
408
+ """
409
+ Create a Mute Data Analyst configuration
410
+
411
+ This agent:
412
+ - Can read data files from /data directory
413
+ - Can execute analytics queries
414
+ - Returns NULL for out-of-scope requests
415
+ """
416
+ return MuteAgentConfig(
417
+ agent_id=agent_id,
418
+ capabilities=create_data_analyst_capabilities(),
419
+ strict_mode=True,
420
+ null_response_message="NULL",
421
+ enable_explanation=enable_explanation
422
+ )