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
atr/injection.py ADDED
@@ -0,0 +1,422 @@
1
+ # Copyright (c) Microsoft Corporation.
2
+ # Licensed under the MIT License.
3
+ """
4
+ Dependency Injection for ATR tools.
5
+
6
+ Provides a mechanism for injecting configuration, credentials, and other
7
+ dependencies into tool functions at execution time.
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ import inspect
13
+ import threading
14
+ from dataclasses import dataclass
15
+ from typing import (
16
+ Any,
17
+ Callable,
18
+ Dict,
19
+ Generic,
20
+ Optional,
21
+ Type,
22
+ TypeVar,
23
+ Union,
24
+ get_type_hints,
25
+ )
26
+
27
+ T = TypeVar("T")
28
+
29
+
30
+ class InjectionToken(Generic[T]):
31
+ """Token for identifying injectable dependencies.
32
+
33
+ Example:
34
+ >>> CONFIG_TOKEN = InjectionToken[Config]("config")
35
+ >>> @atr.register()
36
+ ... def my_tool(config: Config = inject(CONFIG_TOKEN)) -> str:
37
+ ... return config.api_key
38
+ """
39
+
40
+ def __init__(self, name: str, default: Optional[T] = None):
41
+ """Initialize injection token.
42
+
43
+ Args:
44
+ name: Unique name for this token.
45
+ default: Default value if not provided.
46
+ """
47
+ self.name = name
48
+ self.default = default
49
+
50
+ def __repr__(self) -> str:
51
+ return f"InjectionToken({self.name!r})"
52
+
53
+ def __hash__(self) -> int:
54
+ return hash(self.name)
55
+
56
+ def __eq__(self, other: object) -> bool:
57
+ if isinstance(other, InjectionToken):
58
+ return self.name == other.name
59
+ return False
60
+
61
+
62
+ @dataclass
63
+ class InjectionMarker:
64
+ """Marker class to identify parameters that need injection.
65
+
66
+ Used as a default value for parameters that should be injected.
67
+ """
68
+
69
+ token: Optional[Union[InjectionToken, str, Type]] = None
70
+ optional: bool = False
71
+ default: Any = None
72
+
73
+ def __repr__(self) -> str:
74
+ if self.token:
75
+ return f"inject({self.token!r})"
76
+ return "inject()"
77
+
78
+
79
+ def inject(
80
+ token: Optional[Union[InjectionToken, str, Type]] = None,
81
+ *,
82
+ optional: bool = False,
83
+ default: Any = None,
84
+ ) -> Any:
85
+ """Mark a parameter for dependency injection.
86
+
87
+ Use this as a default value for parameters that should be injected
88
+ by the runtime when the tool is executed.
89
+
90
+ Args:
91
+ token: Optional injection token, type, or name string.
92
+ If None, uses the parameter's type annotation.
93
+ optional: If True, allow None when dependency isn't available.
94
+ default: Default value if dependency isn't available.
95
+
96
+ Returns:
97
+ InjectionMarker instance (used as parameter default).
98
+
99
+ Example:
100
+ >>> @atr.register()
101
+ ... def pdf_parser(
102
+ ... file_path: str,
103
+ ... config: Config = inject(), # Inject by type
104
+ ... api_key: str = inject("api_key"), # Inject by name
105
+ ... ) -> dict:
106
+ ... ...
107
+ """
108
+ return InjectionMarker(token=token, optional=optional, default=default)
109
+
110
+
111
+ class DependencyContainer:
112
+ """Container for managing injectable dependencies.
113
+
114
+ Provides a thread-safe container for registering and resolving
115
+ dependencies used by tools.
116
+
117
+ Example:
118
+ >>> container = DependencyContainer()
119
+ >>> container.register(Config, Config(api_key="secret"))
120
+ >>> container.register("database", db_connection)
121
+ >>>
122
+ >>> config = container.resolve(Config)
123
+ >>> db = container.resolve("database")
124
+ """
125
+
126
+ def __init__(self):
127
+ """Initialize empty container."""
128
+ self._by_type: Dict[Type, Any] = {}
129
+ self._by_name: Dict[str, Any] = {}
130
+ self._by_token: Dict[InjectionToken, Any] = {}
131
+ self._factories: Dict[Any, Callable[[], Any]] = {}
132
+ self._lock = threading.RLock()
133
+
134
+ def register(
135
+ self,
136
+ key: Union[Type, str, InjectionToken],
137
+ value: Any = None,
138
+ *,
139
+ factory: Optional[Callable[[], Any]] = None,
140
+ singleton: bool = True,
141
+ ) -> "DependencyContainer":
142
+ """Register a dependency.
143
+
144
+ Args:
145
+ key: Type, name string, or InjectionToken.
146
+ value: The value to inject (mutually exclusive with factory).
147
+ factory: Factory function to create the value.
148
+ singleton: If using factory, whether to cache the result.
149
+
150
+ Returns:
151
+ Self for chaining.
152
+
153
+ Raises:
154
+ ValueError: If both value and factory are provided.
155
+ """
156
+ if value is not None and factory is not None:
157
+ raise ValueError("Cannot provide both value and factory")
158
+
159
+ with self._lock:
160
+ if factory is not None:
161
+ if singleton:
162
+ # Wrap factory to cache result
163
+ _cached = {}
164
+
165
+ def cached_factory():
166
+ if "value" not in _cached:
167
+ _cached["value"] = factory()
168
+ return _cached["value"]
169
+
170
+ self._factories[key] = cached_factory
171
+ else:
172
+ self._factories[key] = factory
173
+ elif isinstance(key, type):
174
+ self._by_type[key] = value
175
+ elif isinstance(key, str):
176
+ self._by_name[key] = value
177
+ elif isinstance(key, InjectionToken):
178
+ self._by_token[key] = value
179
+ else:
180
+ raise TypeError(f"Unsupported key type: {type(key)}")
181
+
182
+ return self
183
+
184
+ def register_instance(self, instance: Any) -> "DependencyContainer":
185
+ """Register an instance by its type.
186
+
187
+ Convenience method that registers the instance using its type as key.
188
+
189
+ Args:
190
+ instance: The instance to register.
191
+
192
+ Returns:
193
+ Self for chaining.
194
+ """
195
+ return self.register(type(instance), instance)
196
+
197
+ def resolve(
198
+ self, key: Union[Type[T], str, InjectionToken[T]], default: Any = None
199
+ ) -> Optional[T]:
200
+ """Resolve a dependency.
201
+
202
+ Args:
203
+ key: Type, name string, or InjectionToken to resolve.
204
+ default: Default value if not found.
205
+
206
+ Returns:
207
+ The resolved dependency or default.
208
+ """
209
+ with self._lock:
210
+ # Check factories first
211
+ if key in self._factories:
212
+ return self._factories[key]()
213
+
214
+ # Then check direct registrations
215
+ if isinstance(key, type):
216
+ if key in self._by_type:
217
+ return self._by_type[key]
218
+ # Check subclasses
219
+ for _registered_type, value in self._by_type.items():
220
+ if isinstance(value, key):
221
+ return value
222
+ elif isinstance(key, str):
223
+ if key in self._by_name:
224
+ return self._by_name[key]
225
+ elif isinstance(key, InjectionToken):
226
+ if key in self._by_token:
227
+ return self._by_token[key]
228
+ # Fall back to token's default
229
+ if key.default is not None:
230
+ return key.default
231
+
232
+ return default
233
+
234
+ def has(self, key: Union[Type, str, InjectionToken]) -> bool:
235
+ """Check if a dependency is registered.
236
+
237
+ Args:
238
+ key: The key to check.
239
+
240
+ Returns:
241
+ True if registered, False otherwise.
242
+ """
243
+ with self._lock:
244
+ if key in self._factories:
245
+ return True
246
+ if isinstance(key, type):
247
+ return key in self._by_type
248
+ elif isinstance(key, str):
249
+ return key in self._by_name
250
+ elif isinstance(key, InjectionToken):
251
+ return key in self._by_token
252
+ return False
253
+
254
+ def unregister(self, key: Union[Type, str, InjectionToken]) -> bool:
255
+ """Unregister a dependency.
256
+
257
+ Args:
258
+ key: The key to unregister.
259
+
260
+ Returns:
261
+ True if was registered, False otherwise.
262
+ """
263
+ with self._lock:
264
+ if key in self._factories:
265
+ del self._factories[key]
266
+ return True
267
+ if isinstance(key, type) and key in self._by_type:
268
+ del self._by_type[key]
269
+ return True
270
+ elif isinstance(key, str) and key in self._by_name:
271
+ del self._by_name[key]
272
+ return True
273
+ elif isinstance(key, InjectionToken) and key in self._by_token:
274
+ del self._by_token[key]
275
+ return True
276
+ return False
277
+
278
+ def clear(self) -> None:
279
+ """Clear all registered dependencies."""
280
+ with self._lock:
281
+ self._by_type.clear()
282
+ self._by_name.clear()
283
+ self._by_token.clear()
284
+ self._factories.clear()
285
+
286
+ def create_child(self) -> "DependencyContainer":
287
+ """Create a child container that inherits from this one.
288
+
289
+ The child can override dependencies without affecting the parent.
290
+
291
+ Returns:
292
+ New child container.
293
+ """
294
+ child = ChildContainer(self)
295
+ return child
296
+
297
+
298
+ class ChildContainer(DependencyContainer):
299
+ """Child container that inherits from a parent."""
300
+
301
+ def __init__(self, parent: DependencyContainer):
302
+ super().__init__()
303
+ self._parent = parent
304
+
305
+ def resolve(
306
+ self, key: Union[Type[T], str, InjectionToken[T]], default: Any = None
307
+ ) -> Optional[T]:
308
+ """Resolve from self first, then parent."""
309
+ # Try self first
310
+ result = super().resolve(key, None)
311
+ if result is not None:
312
+ return result
313
+
314
+ # Fall back to parent
315
+ return self._parent.resolve(key, default)
316
+
317
+ def has(self, key: Union[Type, str, InjectionToken]) -> bool:
318
+ """Check self and parent."""
319
+ return super().has(key) or self._parent.has(key)
320
+
321
+
322
+ class InjectionResolver:
323
+ """Resolves injection markers in function calls.
324
+
325
+ Used by the runtime to inject dependencies into tool functions.
326
+ """
327
+
328
+ def __init__(self, container: DependencyContainer):
329
+ """Initialize resolver with a container.
330
+
331
+ Args:
332
+ container: The dependency container to use.
333
+ """
334
+ self.container = container
335
+
336
+ def resolve_parameters(
337
+ self, func: Callable, args: tuple, kwargs: Dict[str, Any]
338
+ ) -> Dict[str, Any]:
339
+ """Resolve injection markers in function parameters.
340
+
341
+ Args:
342
+ func: The function being called.
343
+ args: Positional arguments provided.
344
+ kwargs: Keyword arguments provided.
345
+
346
+ Returns:
347
+ Updated kwargs with injected values.
348
+
349
+ Raises:
350
+ InjectionError: If a required dependency cannot be resolved.
351
+ """
352
+ sig = inspect.signature(func)
353
+ type_hints = get_type_hints(func) if hasattr(func, "__annotations__") else {}
354
+
355
+ resolved_kwargs = dict(kwargs)
356
+
357
+ # Convert positional args to kwargs
358
+ params = list(sig.parameters.items())
359
+ for i, arg in enumerate(args):
360
+ if i < len(params):
361
+ param_name = params[i][0]
362
+ resolved_kwargs[param_name] = arg
363
+
364
+ # Check each parameter for injection markers
365
+ for param_name, param in sig.parameters.items():
366
+ # Skip if already provided
367
+ if param_name in resolved_kwargs:
368
+ continue
369
+
370
+ # Check if default is an injection marker
371
+ if isinstance(param.default, InjectionMarker):
372
+ marker = param.default
373
+
374
+ # Determine the key to use
375
+ if marker.token is not None:
376
+ key = marker.token
377
+ elif param_name in type_hints:
378
+ key = type_hints[param_name]
379
+ else:
380
+ key = param_name
381
+
382
+ # Resolve the dependency
383
+ value = self.container.resolve(key, marker.default)
384
+
385
+ if value is None and not marker.optional:
386
+ raise InjectionError(
387
+ f"Cannot resolve dependency for parameter '{param_name}' "
388
+ f"with key {key!r}"
389
+ )
390
+
391
+ resolved_kwargs[param_name] = value
392
+
393
+ return resolved_kwargs
394
+
395
+
396
+ class InjectionError(Exception):
397
+ """Raised when dependency injection fails."""
398
+
399
+ pass
400
+
401
+
402
+ # Global container instance
403
+ _global_container: DependencyContainer = DependencyContainer()
404
+
405
+
406
+ def get_container() -> DependencyContainer:
407
+ """Get the global dependency container.
408
+
409
+ Returns:
410
+ The global DependencyContainer instance.
411
+ """
412
+ return _global_container
413
+
414
+
415
+ def set_container(container: DependencyContainer) -> None:
416
+ """Set the global dependency container.
417
+
418
+ Args:
419
+ container: The container to use globally.
420
+ """
421
+ global _global_container
422
+ _global_container = container