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,452 @@
1
+ # Copyright (c) Microsoft Corporation.
2
+ # Licensed under the MIT License.
3
+ """
4
+ Tool Registry - Dynamic Tool Management and Discovery
5
+
6
+ The Tool Registry enables dynamic registration and discovery of tools for agents,
7
+ supporting extensibility beyond the hardcoded ActionType enum. This addresses
8
+ the need for flexible tool ecosystems similar to LangChain's 100+ integrations.
9
+
10
+ Research Foundations:
11
+ - Plugin architecture patterns for extensible systems
12
+ - Service registry patterns from microservices architecture
13
+ - Tool abstraction inspired by "Multimodal Agents: A Survey" (arXiv:2404.12390)
14
+ - Dynamic capability discovery for agent systems
15
+
16
+ See docs/RESEARCH_FOUNDATION.md for complete references.
17
+ """
18
+
19
+ from typing import Any, Dict, List, Optional, Callable, Set
20
+ from dataclasses import dataclass, field
21
+ from enum import Enum
22
+ from datetime import datetime
23
+ import hashlib
24
+ import inspect
25
+ import logging
26
+ import textwrap
27
+ import uuid
28
+
29
+ logger = logging.getLogger(__name__)
30
+
31
+
32
+ class ToolType(Enum):
33
+ """Categories of tools available to agents"""
34
+ TEXT = "text"
35
+ VISION = "vision"
36
+ AUDIO = "audio"
37
+ CODE = "code"
38
+ DATABASE = "database"
39
+ API = "api"
40
+ FILE_SYSTEM = "file_system"
41
+ WORKFLOW = "workflow"
42
+ SEARCH = "search"
43
+ CUSTOM = "custom"
44
+
45
+
46
+ @dataclass
47
+ class ToolSchema:
48
+ """JSON Schema definition for tool parameters"""
49
+ type: str = "object"
50
+ properties: Dict[str, Any] = field(default_factory=dict)
51
+ required: List[str] = field(default_factory=list)
52
+ description: str = ""
53
+
54
+
55
+ @dataclass
56
+ class Tool:
57
+ """
58
+ A tool that can be used by agents.
59
+
60
+ Attributes:
61
+ tool_id: Unique identifier for the tool
62
+ name: Human-readable name
63
+ description: What the tool does
64
+ tool_type: Category of the tool
65
+ handler: Function that executes the tool
66
+ parameter_schema: JSON schema for parameters
67
+ requires_approval: Whether tool execution requires human approval
68
+ risk_level: Risk score (0.0-1.0, higher = more risky)
69
+ content_hash: SHA-256 hash of the tool handler's source code at
70
+ registration time. Used to detect tampering or aliasing.
71
+ metadata: Additional tool metadata
72
+ """
73
+ tool_id: str
74
+ name: str
75
+ description: str
76
+ tool_type: ToolType
77
+ handler: Callable
78
+ parameter_schema: ToolSchema
79
+ requires_approval: bool = False
80
+ risk_level: float = 0.0
81
+ content_hash: str = ""
82
+ metadata: Dict[str, Any] = field(default_factory=dict)
83
+ created_at: datetime = field(default_factory=datetime.now)
84
+
85
+
86
+ class ToolRegistry:
87
+ """
88
+ Central registry for dynamic tool management.
89
+
90
+ Features:
91
+ - Register tools dynamically at runtime
92
+ - Discover available tools by type or capability
93
+ - Validate tool parameters against schemas
94
+ - Support for multi-modal tools (text, vision, audio)
95
+ - Integration point for external tool providers
96
+
97
+ Usage:
98
+ registry = ToolRegistry()
99
+
100
+ # Register a tool
101
+ registry.register_tool(
102
+ name="web_search",
103
+ description="Search the web for information",
104
+ tool_type=ToolType.SEARCH,
105
+ handler=search_handler,
106
+ parameter_schema=search_schema
107
+ )
108
+
109
+ # Discover tools
110
+ tools = registry.get_tools_by_type(ToolType.SEARCH)
111
+
112
+ # Execute a tool
113
+ result = registry.execute_tool("web_search", {"query": "AI safety"})
114
+ """
115
+
116
+ def __init__(self):
117
+ self._tools: Dict[str, Tool] = {}
118
+ self._tools_by_type: Dict[ToolType, Set[str]] = {}
119
+ self._tools_by_name: Dict[str, str] = {} # name -> tool_id mapping
120
+ self._integrity_violations: List[Dict[str, Any]] = []
121
+
122
+ @staticmethod
123
+ def _compute_handler_hash(handler: Callable) -> str:
124
+ """Compute a SHA-256 content hash of a callable's source code.
125
+
126
+ Returns an empty string if source is unavailable (e.g. built-in
127
+ or C-extension functions). Callers should treat an empty hash
128
+ as "unverifiable" rather than silently trusting the handler.
129
+ """
130
+ try:
131
+ source = textwrap.dedent(inspect.getsource(handler))
132
+ return hashlib.sha256(source.encode("utf-8")).hexdigest()
133
+ except (OSError, TypeError):
134
+ logger.warning(
135
+ "Cannot compute source hash for handler %r — "
136
+ "source unavailable (built-in or C-extension)",
137
+ getattr(handler, "__qualname__", handler),
138
+ )
139
+ return ""
140
+
141
+ def register_tool(
142
+ self,
143
+ name: str,
144
+ description: str,
145
+ tool_type: ToolType,
146
+ handler: Callable,
147
+ parameter_schema: Optional[ToolSchema] = None,
148
+ requires_approval: bool = False,
149
+ risk_level: float = 0.0,
150
+ metadata: Optional[Dict[str, Any]] = None
151
+ ) -> str:
152
+ """
153
+ Register a new tool in the registry.
154
+
155
+ Args:
156
+ name: Tool name (must be unique)
157
+ description: What the tool does
158
+ tool_type: Category of the tool
159
+ handler: Function to execute the tool
160
+ parameter_schema: JSON schema for parameters (auto-generated if None)
161
+ requires_approval: Whether execution requires approval
162
+ risk_level: Risk score 0.0-1.0
163
+ metadata: Additional metadata
164
+
165
+ Returns:
166
+ tool_id: Unique identifier for the registered tool
167
+
168
+ Raises:
169
+ ValueError: If tool name already exists
170
+ """
171
+ if name in self._tools_by_name:
172
+ raise ValueError(f"Tool '{name}' already registered")
173
+
174
+ tool_id = str(uuid.uuid4())
175
+
176
+ # Auto-generate schema from function signature if not provided
177
+ if parameter_schema is None:
178
+ parameter_schema = self._generate_schema_from_handler(handler)
179
+
180
+ # Compute content hash for integrity verification
181
+ content_hash = self._compute_handler_hash(handler)
182
+
183
+ tool = Tool(
184
+ tool_id=tool_id,
185
+ name=name,
186
+ description=description,
187
+ tool_type=tool_type,
188
+ handler=handler,
189
+ parameter_schema=parameter_schema,
190
+ requires_approval=requires_approval,
191
+ risk_level=risk_level,
192
+ content_hash=content_hash,
193
+ metadata=metadata or {}
194
+ )
195
+
196
+ self._tools[tool_id] = tool
197
+ self._tools_by_name[name] = tool_id
198
+
199
+ if tool_type not in self._tools_by_type:
200
+ self._tools_by_type[tool_type] = set()
201
+ self._tools_by_type[tool_type].add(tool_id)
202
+
203
+ return tool_id
204
+
205
+ def unregister_tool(self, tool_id_or_name: str) -> bool:
206
+ """
207
+ Remove a tool from the registry.
208
+
209
+ Args:
210
+ tool_id_or_name: Tool ID or name
211
+
212
+ Returns:
213
+ True if tool was removed, False if not found
214
+ """
215
+ tool_id = self._resolve_tool_id(tool_id_or_name)
216
+ if not tool_id:
217
+ return False
218
+
219
+ tool = self._tools.get(tool_id)
220
+ if not tool:
221
+ return False
222
+
223
+ del self._tools[tool_id]
224
+ del self._tools_by_name[tool.name]
225
+ self._tools_by_type[tool.tool_type].discard(tool_id)
226
+
227
+ return True
228
+
229
+ def get_tool(self, tool_id_or_name: str) -> Optional[Tool]:
230
+ """Get a tool by ID or name"""
231
+ tool_id = self._resolve_tool_id(tool_id_or_name)
232
+ return self._tools.get(tool_id) if tool_id else None
233
+
234
+ def get_tools_by_type(self, tool_type: ToolType) -> List[Tool]:
235
+ """Get all tools of a specific type"""
236
+ tool_ids = self._tools_by_type.get(tool_type, set())
237
+ return [self._tools[tid] for tid in tool_ids]
238
+
239
+ def get_all_tools(self) -> List[Tool]:
240
+ """Get all registered tools"""
241
+ return list(self._tools.values())
242
+
243
+ def execute_tool(
244
+ self,
245
+ tool_id_or_name: str,
246
+ parameters: Dict[str, Any]
247
+ ) -> Dict[str, Any]:
248
+ """
249
+ Execute a registered tool.
250
+
251
+ Args:
252
+ tool_id_or_name: Tool ID or name
253
+ parameters: Tool parameters
254
+
255
+ Returns:
256
+ Result dictionary with 'success', 'result', or 'error' keys
257
+ """
258
+ tool = self.get_tool(tool_id_or_name)
259
+ if not tool:
260
+ return {
261
+ "success": False,
262
+ "error": f"Tool '{tool_id_or_name}' not found"
263
+ }
264
+
265
+ # Verify tool integrity before execution
266
+ integrity = self.verify_tool_integrity(tool.tool_id)
267
+ if not integrity["verified"]:
268
+ logger.warning(
269
+ "Tool integrity check FAILED for '%s': %s",
270
+ tool.name,
271
+ integrity["reason"],
272
+ )
273
+ self._integrity_violations.append({
274
+ "tool_id": tool.tool_id,
275
+ "tool_name": tool.name,
276
+ "reason": integrity["reason"],
277
+ "timestamp": datetime.now().isoformat(),
278
+ })
279
+ return {
280
+ "success": False,
281
+ "error": f"Tool integrity verification failed: {integrity['reason']}",
282
+ "tool_id": tool.tool_id,
283
+ "tool_name": tool.name,
284
+ }
285
+
286
+ # Validate parameters against schema
287
+ validation_result = self.validate_parameters(tool.tool_id, parameters)
288
+ if not validation_result["valid"]:
289
+ return {
290
+ "success": False,
291
+ "error": f"Invalid parameters: {validation_result['errors']}"
292
+ }
293
+
294
+ try:
295
+ result = tool.handler(**parameters)
296
+ return {
297
+ "success": True,
298
+ "result": result,
299
+ "tool_id": tool.tool_id,
300
+ "tool_name": tool.name
301
+ }
302
+ except Exception as e:
303
+ return {
304
+ "success": False,
305
+ "error": str(e),
306
+ "tool_id": tool.tool_id,
307
+ "tool_name": tool.name
308
+ }
309
+
310
+ def validate_parameters(
311
+ self,
312
+ tool_id_or_name: str,
313
+ parameters: Dict[str, Any]
314
+ ) -> Dict[str, Any]:
315
+ """
316
+ Validate parameters against tool schema.
317
+
318
+ Returns:
319
+ {"valid": bool, "errors": List[str]}
320
+ """
321
+ tool = self.get_tool(tool_id_or_name)
322
+ if not tool:
323
+ return {"valid": False, "errors": ["Tool not found"]}
324
+
325
+ errors = []
326
+ schema = tool.parameter_schema
327
+
328
+ # Check required parameters
329
+ for required_param in schema.required:
330
+ if required_param not in parameters:
331
+ errors.append(f"Missing required parameter: {required_param}")
332
+
333
+ # Type checking would go here (simplified for now)
334
+ # In production, use jsonschema library for full validation
335
+
336
+ return {
337
+ "valid": len(errors) == 0,
338
+ "errors": errors
339
+ }
340
+
341
+ def search_tools(self, query: str) -> List[Tool]:
342
+ """
343
+ Search tools by name or description.
344
+
345
+ Args:
346
+ query: Search string
347
+
348
+ Returns:
349
+ List of matching tools
350
+ """
351
+ query_lower = query.lower()
352
+ matches = []
353
+
354
+ for tool in self._tools.values():
355
+ if (query_lower in tool.name.lower() or
356
+ query_lower in tool.description.lower()):
357
+ matches.append(tool)
358
+
359
+ return matches
360
+
361
+ def verify_tool_integrity(self, tool_id_or_name: str) -> Dict[str, Any]:
362
+ """Verify that a tool's handler has not been modified since registration.
363
+
364
+ Compares the current SHA-256 hash of the handler's source code
365
+ against the hash recorded at registration time.
366
+
367
+ Returns:
368
+ {"verified": bool, "reason": str, "registered_hash": str, "current_hash": str}
369
+ """
370
+ tool = self.get_tool(tool_id_or_name)
371
+ if not tool:
372
+ return {
373
+ "verified": False,
374
+ "reason": "Tool not found",
375
+ "registered_hash": "",
376
+ "current_hash": "",
377
+ }
378
+
379
+ if not tool.content_hash:
380
+ return {
381
+ "verified": False,
382
+ "reason": "No content hash recorded at registration (built-in or C-extension)",
383
+ "registered_hash": "",
384
+ "current_hash": "",
385
+ }
386
+
387
+ current_hash = self._compute_handler_hash(tool.handler)
388
+ if not current_hash:
389
+ return {
390
+ "verified": False,
391
+ "reason": "Cannot compute current hash — source unavailable",
392
+ "registered_hash": tool.content_hash,
393
+ "current_hash": "",
394
+ }
395
+
396
+ verified = current_hash == tool.content_hash
397
+ return {
398
+ "verified": verified,
399
+ "reason": "" if verified else "Handler source has been modified since registration",
400
+ "registered_hash": tool.content_hash,
401
+ "current_hash": current_hash,
402
+ }
403
+
404
+ def get_integrity_violations(self) -> List[Dict[str, Any]]:
405
+ """Return all recorded integrity violations."""
406
+ return list(self._integrity_violations)
407
+
408
+ def _resolve_tool_id(self, tool_id_or_name: str) -> Optional[str]:
409
+ """Resolve a tool name to its ID, or return ID if already an ID"""
410
+ if tool_id_or_name in self._tools:
411
+ return tool_id_or_name
412
+ return self._tools_by_name.get(tool_id_or_name)
413
+
414
+ def _generate_schema_from_handler(self, handler: Callable) -> ToolSchema:
415
+ """Auto-generate a basic schema from function signature"""
416
+ sig = inspect.signature(handler)
417
+ properties = {}
418
+ required = []
419
+
420
+ for param_name, param in sig.parameters.items():
421
+ if param_name == "self":
422
+ continue
423
+
424
+ properties[param_name] = {
425
+ "type": "string", # Default to string, would need type hints for better
426
+ "description": f"Parameter {param_name}"
427
+ }
428
+
429
+ if param.default == inspect.Parameter.empty:
430
+ required.append(param_name)
431
+
432
+ return ToolSchema(
433
+ type="object",
434
+ properties=properties,
435
+ required=required,
436
+ description=handler.__doc__ or ""
437
+ )
438
+
439
+
440
+ def create_standard_tool_registry() -> ToolRegistry:
441
+ """
442
+ Create a tool registry with standard built-in tools.
443
+
444
+ Returns:
445
+ ToolRegistry with common tools pre-registered
446
+ """
447
+ registry = ToolRegistry()
448
+
449
+ # This would register standard tools
450
+ # Intentionally left minimal to show the pattern
451
+
452
+ return registry