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,1174 @@
1
+ # Copyright (c) Microsoft Corporation.
2
+ # Licensed under the MIT License.
3
+ """
4
+ MCP Tools for Agent OS Kernel.
5
+
6
+ Exposes CMVK, IATP, code safety, and governed execution as MCP-compatible tools.
7
+ """
8
+
9
+ from dataclasses import dataclass, field
10
+ from typing import Any, Optional, List
11
+ from datetime import datetime, timezone
12
+ import hashlib
13
+ import json
14
+ import re
15
+
16
+
17
+ @dataclass
18
+ class ToolResult:
19
+ """Standard result from MCP tool execution."""
20
+ success: bool
21
+ data: Any
22
+ error: Optional[str] = None
23
+ metadata: dict = field(default_factory=dict)
24
+
25
+
26
+ class VerifyCodeSafetyTool:
27
+ """
28
+ Code Safety Verification as MCP Tool.
29
+
30
+ Checks if code is safe to execute by running it through
31
+ the Agent OS policy engine. This is the primary integration
32
+ point for Claude Desktop to verify generated code.
33
+ """
34
+
35
+ name = "verify_code_safety"
36
+ description = "Check if code is safe to execute before running it"
37
+
38
+ input_schema = {
39
+ "type": "object",
40
+ "properties": {
41
+ "code": {
42
+ "type": "string",
43
+ "description": "The code to verify"
44
+ },
45
+ "language": {
46
+ "type": "string",
47
+ "description": "Programming language (e.g., 'python', 'javascript', 'sql')"
48
+ },
49
+ "context": {
50
+ "type": "object",
51
+ "description": "Additional context (file path, project type, etc.)"
52
+ }
53
+ },
54
+ "required": ["code", "language"]
55
+ }
56
+
57
+ # Policy rules for code safety
58
+ SAFETY_RULES = [
59
+ # SQL Destructive Operations
60
+ {
61
+ "name": "drop_table",
62
+ "pattern": r"DROP\s+(TABLE|DATABASE|SCHEMA|INDEX)\s+",
63
+ "severity": "critical",
64
+ "message": "Destructive SQL: DROP operation detected",
65
+ "alternative": "Consider using soft delete or archiving instead of DROP"
66
+ },
67
+ {
68
+ "name": "delete_all",
69
+ "pattern": r"DELETE\s+FROM\s+\w+\s*(;|$|WHERE\s+1\s*=\s*1)",
70
+ "severity": "critical",
71
+ "message": "Destructive SQL: DELETE without proper WHERE clause",
72
+ "alternative": "Add a specific WHERE clause to limit deletion"
73
+ },
74
+ {
75
+ "name": "truncate_table",
76
+ "pattern": r"TRUNCATE\s+TABLE\s+",
77
+ "severity": "critical",
78
+ "message": "Destructive SQL: TRUNCATE operation detected",
79
+ "alternative": "Consider archiving data before truncating"
80
+ },
81
+ # File Operations
82
+ {
83
+ "name": "rm_rf",
84
+ "pattern": r"rm\s+(-rf|-fr|--recursive\s+--force)\s+",
85
+ "severity": "critical",
86
+ "message": "Destructive operation: rm -rf detected",
87
+ "alternative": "Use safer alternatives like trash-cli or move to backup first"
88
+ },
89
+ {
90
+ "name": "rm_root",
91
+ "pattern": r"rm\s+.*\s+(\/|~|\$HOME)",
92
+ "severity": "critical",
93
+ "message": "Destructive operation: Deleting from root or home directory"
94
+ },
95
+ {
96
+ "name": "shutil_rmtree",
97
+ "pattern": r"shutil\s*\.\s*rmtree\s*\(",
98
+ "severity": "high",
99
+ "message": "Recursive directory deletion (shutil.rmtree)",
100
+ "alternative": "Consider using send2trash for safer deletion"
101
+ },
102
+ # Secrets
103
+ {
104
+ "name": "hardcoded_api_key",
105
+ "pattern": r"(api[_-]?key|apikey|api[_-]?secret)\s*[=:]\s*[\"'][a-zA-Z0-9_-]{20,}[\"']",
106
+ "severity": "critical",
107
+ "message": "Hardcoded API key detected",
108
+ "alternative": "Use environment variables: os.environ['API_KEY'] or process.env.API_KEY"
109
+ },
110
+ {
111
+ "name": "hardcoded_password",
112
+ "pattern": r"(password|passwd|pwd)\s*[=:]\s*[\"'][^\"']+[\"']",
113
+ "severity": "critical",
114
+ "message": "Hardcoded password detected",
115
+ "alternative": "Use environment variables or a secrets manager"
116
+ },
117
+ {
118
+ "name": "aws_key",
119
+ "pattern": r"AKIA[0-9A-Z]{16}",
120
+ "severity": "critical",
121
+ "message": "AWS Access Key ID detected in code"
122
+ },
123
+ {
124
+ "name": "private_key",
125
+ "pattern": r"-----BEGIN\s+(RSA|DSA|EC|OPENSSH)\s+PRIVATE\s+KEY-----",
126
+ "severity": "critical",
127
+ "message": "Private key detected in code"
128
+ },
129
+ {
130
+ "name": "github_token",
131
+ "pattern": r"gh[pousr]_[A-Za-z0-9_]{36,}",
132
+ "severity": "critical",
133
+ "message": "GitHub token detected in code"
134
+ },
135
+ # Privilege Escalation
136
+ {
137
+ "name": "sudo",
138
+ "pattern": r"\bsudo\s+",
139
+ "severity": "high",
140
+ "message": "Privilege escalation: sudo command detected",
141
+ "alternative": "Avoid sudo in scripts - run with appropriate permissions"
142
+ },
143
+ {
144
+ "name": "chmod_777",
145
+ "pattern": r"chmod\s+777\s+",
146
+ "severity": "high",
147
+ "message": "Insecure permissions: chmod 777 detected",
148
+ "alternative": "Use more restrictive permissions: chmod 755 or chmod 644"
149
+ },
150
+ {
151
+ "name": "setuid_root",
152
+ "pattern": r"os\s*\.\s*set(e)?uid\s*\(\s*0\s*\)",
153
+ "severity": "critical",
154
+ "message": "Setting UID to root (0) detected"
155
+ },
156
+ # Code Execution
157
+ {
158
+ "name": "eval",
159
+ "pattern": r"\beval\s*\(",
160
+ "severity": "high",
161
+ "message": "Dynamic code execution: eval() detected",
162
+ "alternative": "Use JSON.parse() for data or ast.literal_eval() for Python"
163
+ },
164
+ {
165
+ "name": "exec",
166
+ "pattern": r"\bexec\s*\(",
167
+ "severity": "high",
168
+ "message": "Dynamic code execution: exec() detected",
169
+ "alternative": "Consider safer alternatives to dynamic execution"
170
+ },
171
+ # System Destructive
172
+ {
173
+ "name": "fork_bomb",
174
+ "pattern": r":\s*\(\)\s*\{\s*:\s*\|\s*:\s*&\s*\}\s*;",
175
+ "severity": "critical",
176
+ "message": "Fork bomb detected - would crash system"
177
+ },
178
+ {
179
+ "name": "dd_disk",
180
+ "pattern": r"dd\s+if=.*\s+of=\/dev\/(sd[a-z]|nvme|hd[a-z])",
181
+ "severity": "critical",
182
+ "message": "Direct disk write operation (dd) - could corrupt disk"
183
+ },
184
+ {
185
+ "name": "format_drive",
186
+ "pattern": r"format\s+[a-z]:",
187
+ "severity": "critical",
188
+ "message": "Drive format command detected"
189
+ }
190
+ ]
191
+
192
+ def __init__(self, config: Optional[dict] = None):
193
+ self.config = config or {}
194
+ # Compile regex patterns
195
+ self._compiled_rules = [
196
+ {**rule, "compiled": re.compile(rule["pattern"], re.IGNORECASE)}
197
+ for rule in self.SAFETY_RULES
198
+ ]
199
+
200
+ async def execute(self, arguments: dict) -> ToolResult:
201
+ """Verify code safety."""
202
+ code = arguments.get("code", "")
203
+ language = arguments.get("language", "unknown")
204
+ context = arguments.get("context", {})
205
+
206
+ violations = []
207
+ warnings = []
208
+
209
+ # Check each rule
210
+ for rule in self._compiled_rules:
211
+ if rule["compiled"].search(code):
212
+ violation = {
213
+ "rule": rule["name"],
214
+ "severity": rule["severity"],
215
+ "message": rule["message"]
216
+ }
217
+ if "alternative" in rule:
218
+ violation["alternative"] = rule["alternative"]
219
+
220
+ if rule["severity"] in ("critical", "high"):
221
+ violations.append(violation)
222
+ else:
223
+ warnings.append(violation)
224
+
225
+ # Determine overall safety
226
+ is_safe = len(violations) == 0
227
+
228
+ # Build result
229
+ result = {
230
+ "safe": is_safe,
231
+ "violations": violations,
232
+ "warnings": warnings,
233
+ "language": language,
234
+ "code_length": len(code),
235
+ "rules_checked": len(self._compiled_rules)
236
+ }
237
+
238
+ # Add alternative if blocked
239
+ if not is_safe and violations:
240
+ primary_violation = violations[0]
241
+ if "alternative" in primary_violation:
242
+ result["alternative"] = primary_violation["alternative"]
243
+ result["blocked_reason"] = primary_violation["message"]
244
+
245
+ return ToolResult(
246
+ success=True,
247
+ data=result,
248
+ error=None if is_safe else f"BLOCKED: {violations[0]['message']}",
249
+ metadata={
250
+ "tool": self.name,
251
+ "timestamp": datetime.now(timezone.utc).isoformat(),
252
+ "language": language
253
+ }
254
+ )
255
+
256
+
257
+ class CMVKVerifyTool:
258
+ """
259
+ CMVK — Verification Kernel as MCP Tool.
260
+
261
+ Verifies claims across multiple models to detect hallucinations
262
+ and blind spots through structured disagreement.
263
+ """
264
+
265
+ name = "cmvk_verify"
266
+ description = "Verify a claim across multiple AI models to detect hallucinations"
267
+
268
+ input_schema = {
269
+ "type": "object",
270
+ "properties": {
271
+ "claim": {
272
+ "type": "string",
273
+ "description": "The claim or statement to verify"
274
+ },
275
+ "context": {
276
+ "type": "string",
277
+ "description": "Optional context for the claim"
278
+ },
279
+ "models": {
280
+ "type": "array",
281
+ "items": {"type": "string"},
282
+ "description": "Models to use for verification (default: all configured)"
283
+ },
284
+ "threshold": {
285
+ "type": "number",
286
+ "description": "Agreement threshold (0-1, default: 0.85)"
287
+ }
288
+ },
289
+ "required": ["claim"]
290
+ }
291
+
292
+ def __init__(self, config: Optional[dict] = None):
293
+ self.config = config or {}
294
+ self.default_threshold = self.config.get("threshold", 0.85)
295
+
296
+ async def execute(self, arguments: dict) -> ToolResult:
297
+ """Execute verification."""
298
+ claim = arguments.get("claim", "")
299
+ context = arguments.get("context", "")
300
+ threshold = arguments.get("threshold", self.default_threshold)
301
+
302
+ # Simulate CMVK verification (in production, calls actual models)
303
+ # This is a stateless operation - no session state maintained
304
+ verification_result = await self._verify_claim(claim, context, threshold)
305
+
306
+ return ToolResult(
307
+ success=True,
308
+ data=verification_result,
309
+ metadata={
310
+ "tool": self.name,
311
+ "timestamp": datetime.now(timezone.utc).isoformat(),
312
+ "threshold_used": threshold
313
+ }
314
+ )
315
+
316
+ async def _verify_claim(self, claim: str, context: str, threshold: float) -> dict:
317
+ """
318
+ Perform verification using drift-based consensus.
319
+
320
+ Algorithm:
321
+ 1. Query each model with the claim
322
+ 2. Calculate pairwise drift between responses
323
+ 3. If max drift > threshold, flag disagreement
324
+ 4. Return consensus response with confidence score
325
+
326
+ In production, this calls actual LLM APIs.
327
+ This implementation provides the interface and algorithm structure.
328
+ """
329
+ import hashlib
330
+
331
+ # Models to verify against
332
+ models = ["gpt-4", "claude-sonnet-4", "gemini-pro"]
333
+
334
+ # In production: Call each model API
335
+ # responses = [await call_model(m, claim) for m in models]
336
+
337
+ # For demo: Generate deterministic mock responses
338
+ claim_hash = int(hashlib.sha256(claim.encode()).hexdigest()[:8], 16)
339
+
340
+ # Simulate model responses (in production, actual API calls)
341
+ responses = []
342
+ for i, model in enumerate(models):
343
+ response_hash = (claim_hash + i * 12345) % 1000000
344
+ responses.append({
345
+ "model": model,
346
+ "response": f"Response from {model}",
347
+ "latency_ms": 500 + (response_hash % 500)
348
+ })
349
+
350
+ # Calculate pairwise drift scores
351
+ # Drift = 0.0 (identical) to 1.0 (completely different)
352
+ drift_scores = []
353
+ for i in range(len(responses)):
354
+ for j in range(i + 1, len(responses)):
355
+ # In production: Use embedding similarity or semantic comparison
356
+ # drift = cosine_distance(embed(r_i), embed(r_j))
357
+ # For demo: deterministic based on hash
358
+ pair_hash = (claim_hash + i * 100 + j * 10) % 100
359
+ drift = pair_hash / 100 * 0.3 # 0.0 to 0.3 range
360
+ drift_scores.append({
361
+ "pair": (responses[i]["model"], responses[j]["model"]),
362
+ "drift": round(drift, 3)
363
+ })
364
+
365
+ max_drift = max(d["drift"] for d in drift_scores) if drift_scores else 0.0
366
+ avg_drift = sum(d["drift"] for d in drift_scores) / len(drift_scores) if drift_scores else 0.0
367
+
368
+ # Drift-based decision
369
+ # High drift = disagreement = low confidence
370
+ disagreement_threshold = 1.0 - threshold # threshold is agreement, so invert
371
+ disagreement_detected = max_drift > disagreement_threshold
372
+
373
+ confidence = 1.0 - avg_drift
374
+ verified = not disagreement_detected and confidence >= threshold
375
+
376
+ return {
377
+ "verified": verified,
378
+ "confidence": round(confidence, 3),
379
+ "drift_score": round(max_drift, 3),
380
+ "avg_drift": round(avg_drift, 3),
381
+ "models_checked": models,
382
+ "drift_details": drift_scores,
383
+ "disagreement_detected": disagreement_detected,
384
+ "consensus_method": "drift_threshold",
385
+ "threshold_used": threshold,
386
+ "interpretation": self._interpret_result(verified, confidence, max_drift)
387
+ }
388
+
389
+ def _interpret_result(self, verified: bool, confidence: float, max_drift: float) -> str:
390
+ """Generate human-readable interpretation of verification result."""
391
+ if verified and confidence > 0.9:
392
+ return "Strong consensus across all models. High confidence in claim validity."
393
+ elif verified and confidence > 0.7:
394
+ return "Models agree with moderate confidence. Claim appears valid."
395
+ elif not verified and max_drift > 0.25:
396
+ return "Significant disagreement between models. Claim requires manual review."
397
+ else:
398
+ return "Weak consensus. Consider additional verification."
399
+
400
+
401
+ class KernelExecuteTool:
402
+ """
403
+ Governed Execution through Agent OS Kernel.
404
+
405
+ Executes actions with policy enforcement, signal handling,
406
+ and audit logging. Stateless - all context in request.
407
+ """
408
+
409
+ name = "kernel_execute"
410
+ description = "Execute an action through the Agent OS kernel with policy enforcement"
411
+
412
+ input_schema = {
413
+ "type": "object",
414
+ "properties": {
415
+ "action": {
416
+ "type": "string",
417
+ "description": "The action to execute (e.g., 'database_query', 'file_write')"
418
+ },
419
+ "params": {
420
+ "type": "object",
421
+ "description": "Parameters for the action"
422
+ },
423
+ "agent_id": {
424
+ "type": "string",
425
+ "description": "ID of the agent making the request"
426
+ },
427
+ "policies": {
428
+ "type": "array",
429
+ "items": {"type": "string"},
430
+ "description": "Policy names to enforce (e.g., ['read_only', 'no_pii'])"
431
+ },
432
+ "context": {
433
+ "type": "object",
434
+ "description": "Execution context (history, state, etc.)"
435
+ }
436
+ },
437
+ "required": ["action", "agent_id"]
438
+ }
439
+
440
+ # Action policies (in production, loaded from config)
441
+ DEFAULT_POLICIES = {
442
+ "database_query": {"allowed_modes": ["read_only", "read_write"]},
443
+ "file_write": {"requires_approval": True, "allowed_paths": ["/tmp", "/data"]},
444
+ "api_call": {"rate_limit": 100, "allowed_domains": ["*"]},
445
+ "send_email": {"requires_approval": True},
446
+ }
447
+
448
+ def __init__(self, config: Optional[dict] = None):
449
+ self.config = config or {}
450
+ self.policy_mode = self.config.get("policy_mode", "strict")
451
+
452
+ async def execute(self, arguments: dict) -> ToolResult:
453
+ """Execute action with kernel governance."""
454
+ action = arguments.get("action", "")
455
+ params = arguments.get("params", {})
456
+ agent_id = arguments.get("agent_id", "unknown")
457
+ policies = arguments.get("policies", [])
458
+ context = arguments.get("context", {})
459
+
460
+ # Policy check (stateless - all info in request)
461
+ policy_result = self._check_policies(action, params, policies)
462
+
463
+ if not policy_result["allowed"]:
464
+ return ToolResult(
465
+ success=False,
466
+ data=None,
467
+ error=f"SIGKILL: Policy violation - {policy_result['reason']}",
468
+ metadata={
469
+ "tool": self.name,
470
+ "agent_id": agent_id,
471
+ "action": action,
472
+ "signal": "SIGKILL",
473
+ "violation": policy_result["reason"],
474
+ "timestamp": datetime.now(timezone.utc).isoformat()
475
+ }
476
+ )
477
+
478
+ # Execute action (in production, dispatches to actual handlers)
479
+ execution_result = await self._execute_action(action, params, context)
480
+
481
+ return ToolResult(
482
+ success=True,
483
+ data=execution_result,
484
+ metadata={
485
+ "tool": self.name,
486
+ "agent_id": agent_id,
487
+ "action": action,
488
+ "policies_applied": policies,
489
+ "timestamp": datetime.now(timezone.utc).isoformat()
490
+ }
491
+ )
492
+
493
+ def _check_policies(self, action: str, params: dict, policies: list) -> dict:
494
+ """Check if action is allowed under given policies."""
495
+ action_policy = self.DEFAULT_POLICIES.get(action, {})
496
+
497
+ # Check read_only policy
498
+ if "read_only" in policies:
499
+ if action in ["file_write", "send_email"]:
500
+ return {"allowed": False, "reason": f"Action '{action}' blocked by read_only policy"}
501
+ if action == "database_query" and params.get("query", "").upper().startswith(("INSERT", "UPDATE", "DELETE")):
502
+ return {"allowed": False, "reason": "Write query blocked by read_only policy"}
503
+
504
+ # Check requires_approval
505
+ if action_policy.get("requires_approval") and not params.get("approved"):
506
+ return {"allowed": False, "reason": f"Action '{action}' requires approval"}
507
+
508
+ # Check no_pii policy
509
+ if "no_pii" in policies:
510
+ pii_keywords = ["ssn", "social_security", "credit_card", "password"]
511
+ params_str = json.dumps(params).lower()
512
+ for keyword in pii_keywords:
513
+ if keyword in params_str:
514
+ return {"allowed": False, "reason": f"PII detected ({keyword}) - blocked by no_pii policy"}
515
+
516
+ return {"allowed": True, "reason": None}
517
+
518
+ async def _execute_action(self, action: str, params: dict, context: dict) -> dict:
519
+ """Execute the action (stub - real implementation dispatches to handlers)."""
520
+ return {
521
+ "status": "executed",
522
+ "action": action,
523
+ "result": f"Action '{action}' executed successfully",
524
+ "params_received": list(params.keys())
525
+ }
526
+
527
+
528
+ class IATPSignTool:
529
+ """
530
+ Inter-Agent Trust Protocol signing as MCP Tool.
531
+
532
+ Signs agent outputs with cryptographic attestation for
533
+ trust propagation across agent networks.
534
+ """
535
+
536
+ name = "iatp_sign"
537
+ description = "Sign content with cryptographic trust attestation for inter-agent communication"
538
+
539
+ input_schema = {
540
+ "type": "object",
541
+ "properties": {
542
+ "content": {
543
+ "type": "string",
544
+ "description": "Content to sign"
545
+ },
546
+ "agent_id": {
547
+ "type": "string",
548
+ "description": "ID of the signing agent"
549
+ },
550
+ "capabilities": {
551
+ "type": "array",
552
+ "items": {"type": "string"},
553
+ "description": "Capabilities being attested (e.g., ['reversible', 'idempotent'])"
554
+ },
555
+ "metadata": {
556
+ "type": "object",
557
+ "description": "Additional metadata to include in signature"
558
+ }
559
+ },
560
+ "required": ["content", "agent_id"]
561
+ }
562
+
563
+ def __init__(self, config: Optional[dict] = None):
564
+ self.config = config or {}
565
+
566
+ async def execute(self, arguments: dict) -> ToolResult:
567
+ """Sign content with IATP attestation."""
568
+ content = arguments.get("content", "")
569
+ agent_id = arguments.get("agent_id", "")
570
+ capabilities = arguments.get("capabilities", [])
571
+ metadata = arguments.get("metadata", {})
572
+
573
+ # Generate signature
574
+ signature = self._generate_signature(content, agent_id, capabilities)
575
+
576
+ return ToolResult(
577
+ success=True,
578
+ data={
579
+ "signature": signature,
580
+ "agent_id": agent_id,
581
+ "capabilities": capabilities,
582
+ "content_hash": hashlib.sha256(content.encode()).hexdigest()[:16],
583
+ "timestamp": datetime.now(timezone.utc).isoformat(),
584
+ "protocol_version": "iatp-1.0"
585
+ },
586
+ metadata={
587
+ "tool": self.name,
588
+ "timestamp": datetime.now(timezone.utc).isoformat()
589
+ }
590
+ )
591
+
592
+ def _generate_signature(self, content: str, agent_id: str, capabilities: list) -> str:
593
+ """Generate IATP signature (simplified - production uses proper crypto)."""
594
+ payload = f"{content}|{agent_id}|{','.join(sorted(capabilities))}"
595
+ return hashlib.sha256(payload.encode()).hexdigest()
596
+
597
+
598
+ class IATPVerifyTool:
599
+ """
600
+ IATP Trust Verification as MCP Tool.
601
+
602
+ Verifies trust relationship with a remote agent, checking:
603
+ - Capability manifest
604
+ - Attestation signature
605
+ - Trust level requirements
606
+ - Policy compatibility
607
+ """
608
+
609
+ name = "iatp_verify"
610
+ description = "Verify trust relationship with another agent before communication"
611
+
612
+ input_schema = {
613
+ "type": "object",
614
+ "properties": {
615
+ "remote_agent_id": {
616
+ "type": "string",
617
+ "description": "ID of the agent to verify"
618
+ },
619
+ "required_trust_level": {
620
+ "type": "string",
621
+ "enum": ["verified_partner", "trusted", "standard", "any"],
622
+ "description": "Minimum required trust level (default: standard)"
623
+ },
624
+ "required_scopes": {
625
+ "type": "array",
626
+ "items": {"type": "string"},
627
+ "description": "Required capability scopes (e.g., ['repo:read'])"
628
+ },
629
+ "data_classification": {
630
+ "type": "string",
631
+ "enum": ["public", "internal", "confidential", "pii"],
632
+ "description": "Classification of data being shared"
633
+ }
634
+ },
635
+ "required": ["remote_agent_id"]
636
+ }
637
+
638
+ # Trust level scores
639
+ TRUST_SCORES = {
640
+ "verified_partner": 10,
641
+ "trusted": 7,
642
+ "standard": 5,
643
+ "unknown": 2,
644
+ "untrusted": 0
645
+ }
646
+
647
+ # Minimum scores required
648
+ MIN_SCORES = {
649
+ "verified_partner": 10,
650
+ "trusted": 7,
651
+ "standard": 5,
652
+ "any": 0
653
+ }
654
+
655
+ def __init__(self, config: Optional[dict] = None):
656
+ self.config = config or {}
657
+ # Agent registry (in production, fetched from network)
658
+ self.agent_registry = self.config.get("agent_registry", {})
659
+
660
+ async def execute(self, arguments: dict) -> ToolResult:
661
+ """Verify trust with remote agent."""
662
+ remote_agent_id = arguments.get("remote_agent_id", "")
663
+ required_level = arguments.get("required_trust_level", "standard")
664
+ required_scopes = arguments.get("required_scopes", [])
665
+ data_classification = arguments.get("data_classification", "internal")
666
+
667
+ # Fetch manifest (simulated - real impl fetches from /.well-known/agent-manifest)
668
+ manifest = await self._fetch_manifest(remote_agent_id)
669
+
670
+ if manifest is None:
671
+ return ToolResult(
672
+ success=False,
673
+ data=None,
674
+ error=f"Could not fetch manifest for agent '{remote_agent_id}'"
675
+ )
676
+
677
+ # Calculate trust score
678
+ trust_score = self._calculate_trust_score(manifest)
679
+ min_required = self.MIN_SCORES.get(required_level, 5)
680
+
681
+ # Check trust level
682
+ if trust_score < min_required:
683
+ return ToolResult(
684
+ success=False,
685
+ data={
686
+ "verified": False,
687
+ "trust_score": trust_score,
688
+ "required_score": min_required,
689
+ "manifest": manifest
690
+ },
691
+ error=f"Trust score {trust_score} below required {min_required}"
692
+ )
693
+
694
+ # Check required scopes
695
+ agent_scopes = manifest.get("scopes", [])
696
+ missing_scopes = [s for s in required_scopes if s not in agent_scopes]
697
+ if missing_scopes:
698
+ return ToolResult(
699
+ success=False,
700
+ data={
701
+ "verified": False,
702
+ "trust_score": trust_score,
703
+ "missing_scopes": missing_scopes
704
+ },
705
+ error=f"Agent missing required scopes: {missing_scopes}"
706
+ )
707
+
708
+ # Check PII restrictions
709
+ if data_classification == "pii":
710
+ retention = manifest.get("privacy", {}).get("retention_policy", "permanent")
711
+ if retention != "ephemeral":
712
+ return ToolResult(
713
+ success=False,
714
+ data={
715
+ "verified": False,
716
+ "trust_score": trust_score,
717
+ "reason": "PII requires ephemeral retention"
718
+ },
719
+ error="Cannot share PII with non-ephemeral agent"
720
+ )
721
+
722
+ # Verification passed
723
+ return ToolResult(
724
+ success=True,
725
+ data={
726
+ "verified": True,
727
+ "remote_agent_id": remote_agent_id,
728
+ "trust_score": trust_score,
729
+ "trust_level": manifest.get("trust_level", "unknown"),
730
+ "scopes": agent_scopes,
731
+ "attestation_valid": True,
732
+ "policy_compatible": True
733
+ },
734
+ metadata={
735
+ "tool": self.name,
736
+ "timestamp": datetime.now(timezone.utc).isoformat()
737
+ }
738
+ )
739
+
740
+ async def _fetch_manifest(self, agent_id: str) -> Optional[dict]:
741
+ """Fetch manifest from agent (simulated)."""
742
+ # In production, this would HTTP GET /.well-known/agent-manifest
743
+ if agent_id in self.agent_registry:
744
+ return self.agent_registry[agent_id]
745
+
746
+ # Return simulated manifest for demo
747
+ return {
748
+ "agent_id": agent_id,
749
+ "trust_level": "standard",
750
+ "scopes": ["data:read", "data:write"],
751
+ "capabilities": {
752
+ "idempotency": True,
753
+ "max_concurrency": 10
754
+ },
755
+ "reversibility": {
756
+ "level": "full",
757
+ "undo_window_seconds": 3600
758
+ },
759
+ "privacy": {
760
+ "retention_policy": "ephemeral",
761
+ "human_in_loop": False,
762
+ "training_consent": False
763
+ }
764
+ }
765
+
766
+ def _calculate_trust_score(self, manifest: dict) -> int:
767
+ """Calculate trust score from manifest."""
768
+ base = self.TRUST_SCORES.get(manifest.get("trust_level", "unknown"), 2)
769
+
770
+ # Modifiers
771
+ reversibility = manifest.get("reversibility", {}).get("level", "none")
772
+ if reversibility != "none":
773
+ base += 2
774
+
775
+ privacy = manifest.get("privacy", {})
776
+ retention = privacy.get("retention_policy", "permanent")
777
+ if retention == "ephemeral":
778
+ base += 1
779
+ elif retention in ("permanent", "forever"):
780
+ base -= 1
781
+
782
+ if privacy.get("human_in_loop", False):
783
+ base -= 2
784
+
785
+ if privacy.get("training_consent", False):
786
+ base -= 1
787
+
788
+ return max(0, min(10, base))
789
+
790
+
791
+ class IATPReputationTool:
792
+ """
793
+ IATP Reputation Query/Slash as MCP Tool.
794
+
795
+ Query or modify agent reputation in the network.
796
+ """
797
+
798
+ name = "iatp_reputation"
799
+ description = "Query or slash agent reputation in the IATP network"
800
+
801
+ input_schema = {
802
+ "type": "object",
803
+ "properties": {
804
+ "action": {
805
+ "type": "string",
806
+ "enum": ["query", "slash"],
807
+ "description": "Action to perform"
808
+ },
809
+ "agent_id": {
810
+ "type": "string",
811
+ "description": "Agent ID to query/slash"
812
+ },
813
+ "slash_reason": {
814
+ "type": "string",
815
+ "description": "Reason for slashing (required if action=slash)"
816
+ },
817
+ "slash_severity": {
818
+ "type": "string",
819
+ "enum": ["critical", "high", "medium", "low"],
820
+ "description": "Severity of violation (required if action=slash)"
821
+ },
822
+ "evidence": {
823
+ "type": "object",
824
+ "description": "Evidence for the slash (e.g., CMVK drift score)"
825
+ }
826
+ },
827
+ "required": ["action", "agent_id"]
828
+ }
829
+
830
+ # Severity penalties
831
+ SLASH_PENALTIES = {
832
+ "critical": 2.0,
833
+ "high": 1.0,
834
+ "medium": 0.5,
835
+ "low": 0.25
836
+ }
837
+
838
+ def __init__(self, config: Optional[dict] = None):
839
+ self.config = config or {}
840
+ # In-memory reputation store (production uses distributed store)
841
+ self._reputation: dict = {}
842
+
843
+ async def execute(self, arguments: dict) -> ToolResult:
844
+ """Execute reputation action."""
845
+ action = arguments.get("action", "query")
846
+ agent_id = arguments.get("agent_id", "")
847
+
848
+ if action == "query":
849
+ return await self._query_reputation(agent_id)
850
+ elif action == "slash":
851
+ reason = arguments.get("slash_reason", "unknown")
852
+ severity = arguments.get("slash_severity", "medium")
853
+ evidence = arguments.get("evidence", {})
854
+ return await self._slash_reputation(agent_id, reason, severity, evidence)
855
+ else:
856
+ return ToolResult(
857
+ success=False,
858
+ data=None,
859
+ error=f"Unknown action: {action}"
860
+ )
861
+
862
+ async def _query_reputation(self, agent_id: str) -> ToolResult:
863
+ """Query agent reputation."""
864
+ score = self._reputation.get(agent_id, 5.0) # Default to 5.0
865
+
866
+ # Determine trust level from score
867
+ if score >= 8.0:
868
+ level = "verified_partner"
869
+ elif score >= 6.0:
870
+ level = "trusted"
871
+ elif score >= 4.0:
872
+ level = "standard"
873
+ elif score >= 2.0:
874
+ level = "unknown"
875
+ else:
876
+ level = "untrusted"
877
+
878
+ return ToolResult(
879
+ success=True,
880
+ data={
881
+ "agent_id": agent_id,
882
+ "reputation_score": round(score, 2),
883
+ "trust_level": level,
884
+ "history_count": 0 # Would track actual history
885
+ }
886
+ )
887
+
888
+ async def _slash_reputation(
889
+ self, agent_id: str, reason: str, severity: str, evidence: dict
890
+ ) -> ToolResult:
891
+ """Slash agent reputation."""
892
+ current = self._reputation.get(agent_id, 5.0)
893
+ penalty = self.SLASH_PENALTIES.get(severity, 0.5)
894
+ new_score = max(0.0, current - penalty)
895
+
896
+ self._reputation[agent_id] = new_score
897
+
898
+ return ToolResult(
899
+ success=True,
900
+ data={
901
+ "agent_id": agent_id,
902
+ "previous_score": round(current, 2),
903
+ "new_score": round(new_score, 2),
904
+ "penalty_applied": penalty,
905
+ "reason": reason,
906
+ "severity": severity,
907
+ "evidence": evidence
908
+ },
909
+ metadata={
910
+ "tool": self.name,
911
+ "action": "slash",
912
+ "timestamp": datetime.now(timezone.utc).isoformat()
913
+ }
914
+ )
915
+
916
+
917
+ class CMVKReviewCodeTool:
918
+ """
919
+ CMVK Code Review as MCP Tool.
920
+
921
+ Performs multi-model code review for security, bugs, and best practices.
922
+ This is optimized for code analysis rather than general claim verification.
923
+ """
924
+
925
+ name = "cmvk_review"
926
+ description = "Multi-model code review for security, bugs, and best practices"
927
+
928
+ input_schema = {
929
+ "type": "object",
930
+ "properties": {
931
+ "code": {
932
+ "type": "string",
933
+ "description": "The code to review"
934
+ },
935
+ "language": {
936
+ "type": "string",
937
+ "description": "Programming language"
938
+ },
939
+ "models": {
940
+ "type": "array",
941
+ "items": {"type": "string"},
942
+ "description": "Models to use for review (default: ['gpt-4', 'claude-sonnet-4', 'gemini-pro'])"
943
+ },
944
+ "focus": {
945
+ "type": "array",
946
+ "items": {"type": "string"},
947
+ "description": "Areas to focus on: 'security', 'bugs', 'performance', 'style'"
948
+ }
949
+ },
950
+ "required": ["code"]
951
+ }
952
+
953
+ def __init__(self, config: Optional[dict] = None):
954
+ self.config = config or {}
955
+
956
+ async def execute(self, arguments: dict) -> ToolResult:
957
+ """Execute code review."""
958
+ code = arguments.get("code", "")
959
+ language = arguments.get("language", "unknown")
960
+ models = arguments.get("models", ["gpt-4", "claude-sonnet-4", "gemini-pro"])
961
+ focus = arguments.get("focus", ["security", "bugs"])
962
+
963
+ # Perform static analysis first
964
+ issues = self._static_analysis(code, language, focus)
965
+
966
+ # Generate mock multi-model reviews (production calls real APIs)
967
+ model_results = []
968
+ for model in models:
969
+ # Vary results per model to simulate disagreement
970
+ model_issues = [i for i in issues if hash(model + i["issue"]) % 3 != 0]
971
+ passed = len(model_issues) == 0
972
+
973
+ model_results.append({
974
+ "model": model,
975
+ "passed": passed,
976
+ "issues": model_issues,
977
+ "summary": "No issues found" if passed else f"Found {len(model_issues)} issue(s)"
978
+ })
979
+
980
+ # Calculate consensus
981
+ passed_count = sum(1 for m in model_results if m["passed"])
982
+ consensus = passed_count / len(models) if models else 1.0
983
+
984
+ # Build recommendations
985
+ all_issues = []
986
+ for m in model_results:
987
+ for issue in m.get("issues", []):
988
+ if issue not in all_issues:
989
+ all_issues.append(issue)
990
+
991
+ recommendation = ""
992
+ if all_issues:
993
+ recommendation = "Based on multi-model review:\n"
994
+ for i, issue in enumerate(all_issues[:5], 1): # Top 5 issues
995
+ recommendation += f"{i}. {issue['issue']}: {issue.get('fix', 'Review needed')}\n"
996
+
997
+ return ToolResult(
998
+ success=True,
999
+ data={
1000
+ "consensus": round(consensus, 2),
1001
+ "reviews": model_results,
1002
+ "issues": all_issues,
1003
+ "recommendation": recommendation,
1004
+ "models_used": models,
1005
+ "language": language,
1006
+ "focus_areas": focus
1007
+ },
1008
+ metadata={
1009
+ "tool": self.name,
1010
+ "timestamp": datetime.now(timezone.utc).isoformat()
1011
+ }
1012
+ )
1013
+
1014
+ def _static_analysis(self, code: str, language: str, focus: List[str]) -> List[dict]:
1015
+ """Perform basic static analysis."""
1016
+ issues = []
1017
+
1018
+ if "security" in focus:
1019
+ # SQL injection
1020
+ if re.search(r'\+\s*["\'][^"\']*\+', code) and re.search(r'SELECT|INSERT|UPDATE|DELETE', code, re.I):
1021
+ issues.append({
1022
+ "category": "security",
1023
+ "severity": "high",
1024
+ "issue": "Potential SQL injection via string concatenation",
1025
+ "fix": "Use parameterized queries or an ORM"
1026
+ })
1027
+
1028
+ # eval usage
1029
+ if re.search(r'\beval\s*\(', code):
1030
+ issues.append({
1031
+ "category": "security",
1032
+ "severity": "high",
1033
+ "issue": "eval() usage is dangerous",
1034
+ "fix": "Use JSON.parse() or ast.literal_eval() for data parsing"
1035
+ })
1036
+
1037
+ # innerHTML
1038
+ if re.search(r'\.innerHTML\s*=', code):
1039
+ issues.append({
1040
+ "category": "security",
1041
+ "severity": "medium",
1042
+ "issue": "innerHTML assignment may lead to XSS",
1043
+ "fix": "Use textContent or a sanitization library"
1044
+ })
1045
+
1046
+ if "bugs" in focus:
1047
+ # Missing error handling
1048
+ if re.search(r'await\s+\w+', code) and not re.search(r'try\s*{', code):
1049
+ issues.append({
1050
+ "category": "bugs",
1051
+ "severity": "medium",
1052
+ "issue": "Async operation without error handling",
1053
+ "fix": "Wrap in try-catch block"
1054
+ })
1055
+
1056
+ # Division by zero potential
1057
+ if re.search(r'/\s*\w+', code) and not re.search(r'if.*[!=]=\s*0', code):
1058
+ issues.append({
1059
+ "category": "bugs",
1060
+ "severity": "low",
1061
+ "issue": "Potential division by zero",
1062
+ "fix": "Add zero check before division"
1063
+ })
1064
+
1065
+ if "performance" in focus:
1066
+ # Synchronous file operations
1067
+ if re.search(r'Sync\s*\(', code):
1068
+ issues.append({
1069
+ "category": "performance",
1070
+ "severity": "medium",
1071
+ "issue": "Synchronous file operation",
1072
+ "fix": "Use async alternatives to avoid blocking"
1073
+ })
1074
+
1075
+ # N+1 query pattern
1076
+ if re.search(r'for.*await.*query', code, re.I):
1077
+ issues.append({
1078
+ "category": "performance",
1079
+ "severity": "high",
1080
+ "issue": "Potential N+1 query pattern",
1081
+ "fix": "Use batch queries or eager loading"
1082
+ })
1083
+
1084
+ return issues
1085
+
1086
+
1087
+ class GetAuditLogTool:
1088
+ """
1089
+ Audit Log Retrieval as MCP Tool.
1090
+
1091
+ Retrieves the Agent OS audit trail for compliance and debugging.
1092
+ """
1093
+
1094
+ name = "get_audit_log"
1095
+ description = "Retrieve Agent OS audit trail"
1096
+
1097
+ input_schema = {
1098
+ "type": "object",
1099
+ "properties": {
1100
+ "limit": {
1101
+ "type": "number",
1102
+ "description": "Maximum number of entries to return (default: 20)"
1103
+ },
1104
+ "filter": {
1105
+ "type": "object",
1106
+ "description": "Filter criteria",
1107
+ "properties": {
1108
+ "agent_id": {"type": "string"},
1109
+ "type": {
1110
+ "type": "string",
1111
+ "enum": ["blocked", "allowed", "cmvk_review", "all"]
1112
+ },
1113
+ "since": {"type": "string", "description": "ISO timestamp"}
1114
+ }
1115
+ }
1116
+ }
1117
+ }
1118
+
1119
+ # In-memory audit log (production uses external store)
1120
+ _audit_log: List[dict] = []
1121
+
1122
+ def __init__(self, config: Optional[dict] = None):
1123
+ self.config = config or {}
1124
+
1125
+ @classmethod
1126
+ def log_entry(cls, entry: dict):
1127
+ """Add entry to audit log."""
1128
+ entry["timestamp"] = datetime.now(timezone.utc).isoformat()
1129
+ cls._audit_log.insert(0, entry)
1130
+ # Keep last 1000 entries
1131
+ if len(cls._audit_log) > 1000:
1132
+ cls._audit_log = cls._audit_log[:1000]
1133
+
1134
+ async def execute(self, arguments: dict) -> ToolResult:
1135
+ """Retrieve audit log entries."""
1136
+ limit = arguments.get("limit", 20)
1137
+ filter_criteria = arguments.get("filter", {})
1138
+
1139
+ # Filter entries
1140
+ entries = self._audit_log.copy()
1141
+
1142
+ if filter_criteria.get("agent_id"):
1143
+ entries = [e for e in entries if e.get("agent_id") == filter_criteria["agent_id"]]
1144
+
1145
+ if filter_criteria.get("type") and filter_criteria["type"] != "all":
1146
+ entries = [e for e in entries if e.get("type") == filter_criteria["type"]]
1147
+
1148
+ if filter_criteria.get("since"):
1149
+ since = filter_criteria["since"]
1150
+ entries = [e for e in entries if e.get("timestamp", "") >= since]
1151
+
1152
+ # Apply limit
1153
+ entries = entries[:limit]
1154
+
1155
+ # Calculate stats
1156
+ blocked_count = sum(1 for e in self._audit_log if e.get("type") == "blocked")
1157
+ total_count = len(self._audit_log)
1158
+
1159
+ return ToolResult(
1160
+ success=True,
1161
+ data={
1162
+ "logs": entries,
1163
+ "returned": len(entries),
1164
+ "total": total_count,
1165
+ "stats": {
1166
+ "blocked_total": blocked_count,
1167
+ "allowed_total": total_count - blocked_count
1168
+ }
1169
+ },
1170
+ metadata={
1171
+ "tool": self.name,
1172
+ "timestamp": datetime.now(timezone.utc).isoformat()
1173
+ }
1174
+ )