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,364 @@
1
+ # Copyright (c) Microsoft Corporation.
2
+ # Licensed under the MIT License.
3
+ """
4
+ Google Gemini Integration
5
+
6
+ Wraps Google's Generative AI SDK with Agent OS governance.
7
+
8
+ Usage:
9
+ from agent_os.integrations.gemini_adapter import GeminiKernel
10
+ import google.generativeai as genai
11
+
12
+ kernel = GeminiKernel(policy=GovernancePolicy(
13
+ max_tokens=4096,
14
+ allowed_tools=["web_search"],
15
+ blocked_patterns=["password"],
16
+ ))
17
+
18
+ model = genai.GenerativeModel("gemini-pro")
19
+ governed = kernel.wrap(model)
20
+ response = governed.generate_content("Hello")
21
+
22
+ Features:
23
+ - Pre-execution policy checks on prompts
24
+ - Tool call interception and validation
25
+ - Token limit enforcement
26
+ - Content filtering via blocked patterns
27
+ - Audit logging for all calls
28
+ - Health check endpoint
29
+ """
30
+
31
+ from __future__ import annotations
32
+
33
+ import logging
34
+ import time
35
+ from dataclasses import dataclass, field
36
+ from datetime import datetime
37
+ from typing import Any
38
+
39
+ from .base import BaseIntegration, ExecutionContext, GovernancePolicy
40
+
41
+ logger = logging.getLogger("agent_os.gemini")
42
+
43
+ try:
44
+ import warnings
45
+ with warnings.catch_warnings():
46
+ warnings.simplefilter("ignore", FutureWarning)
47
+ import google.generativeai as _genai_mod # noqa: F401
48
+
49
+ _HAS_GENAI = True
50
+ except ImportError:
51
+ _HAS_GENAI = False
52
+
53
+
54
+ def _check_genai_available() -> None:
55
+ """Raise a helpful error when the ``google-generativeai`` package is missing."""
56
+ if not _HAS_GENAI:
57
+ raise ImportError(
58
+ "The 'google-generativeai' package is required for GeminiKernel. "
59
+ "Install it with: pip install google-generativeai"
60
+ )
61
+
62
+
63
+ @dataclass
64
+ class GeminiContext(ExecutionContext):
65
+ """Execution context for Google Gemini interactions.
66
+
67
+ Attributes:
68
+ model_name: The Gemini model used for this session.
69
+ generation_ids: Recorded generation response identifiers.
70
+ function_calls: History of function calls returned by Gemini.
71
+ prompt_tokens: Cumulative prompt tokens consumed.
72
+ completion_tokens: Cumulative candidate tokens consumed.
73
+ """
74
+
75
+ model_name: str = ""
76
+ generation_ids: list[str] = field(default_factory=list)
77
+ function_calls: list[dict[str, Any]] = field(default_factory=list)
78
+ prompt_tokens: int = 0
79
+ completion_tokens: int = 0
80
+
81
+
82
+ class PolicyViolationError(Exception):
83
+ """Raised when a Gemini request violates governance policy."""
84
+
85
+ pass
86
+
87
+
88
+ class GeminiKernel(BaseIntegration):
89
+ """Google Gemini adapter for Agent OS.
90
+
91
+ Provides governance for ``GenerativeModel.generate_content()`` calls
92
+ including policy enforcement, tool-call validation, token tracking,
93
+ and audit logging.
94
+
95
+ Example:
96
+ >>> kernel = GeminiKernel(policy=GovernancePolicy(max_tokens=8192))
97
+ >>> governed = kernel.wrap(genai.GenerativeModel("gemini-pro"))
98
+ >>> response = governed.generate_content("Explain quantum computing")
99
+ """
100
+
101
+ def __init__(
102
+ self,
103
+ policy: GovernancePolicy | None = None,
104
+ ) -> None:
105
+ """Initialise the Gemini governance kernel.
106
+
107
+ Args:
108
+ policy: Governance policy to enforce. Uses default when ``None``.
109
+ """
110
+ super().__init__(policy)
111
+ self._wrapped_models: dict[int, Any] = {}
112
+ self._start_time = time.monotonic()
113
+ self._last_error: str | None = None
114
+
115
+ def wrap(self, model: Any) -> GovernedGeminiModel:
116
+ """Wrap a Gemini GenerativeModel with governance.
117
+
118
+ Args:
119
+ model: A ``google.generativeai.GenerativeModel`` instance.
120
+
121
+ Returns:
122
+ A ``GovernedGeminiModel`` that enforces policy on all
123
+ ``generate_content()`` calls.
124
+ """
125
+ _check_genai_available()
126
+ model_id = id(model)
127
+ model_name = getattr(model, "model_name", "unknown")
128
+ ctx = GeminiContext(
129
+ agent_id=f"gemini-{model_id}",
130
+ session_id=f"gem-{int(time.time())}",
131
+ policy=self.policy,
132
+ model_name=model_name,
133
+ )
134
+ self.contexts[ctx.agent_id] = ctx
135
+ self._wrapped_models[model_id] = model
136
+
137
+ return GovernedGeminiModel(
138
+ model=model,
139
+ kernel=self,
140
+ ctx=ctx,
141
+ )
142
+
143
+ def unwrap(self, governed_agent: Any) -> Any:
144
+ """Retrieve the original unwrapped Gemini model.
145
+
146
+ Args:
147
+ governed_agent: A ``GovernedGeminiModel`` or any object.
148
+
149
+ Returns:
150
+ The original GenerativeModel if applicable, otherwise
151
+ *governed_agent* as-is.
152
+ """
153
+ if isinstance(governed_agent, GovernedGeminiModel):
154
+ return governed_agent._model
155
+ return governed_agent
156
+
157
+ def health_check(self) -> dict[str, Any]:
158
+ """Return adapter health status.
159
+
160
+ Returns:
161
+ A dict with ``status``, ``backend``, ``last_error``, and
162
+ ``uptime_seconds`` keys.
163
+ """
164
+ uptime = time.monotonic() - self._start_time
165
+ has_models = bool(self._wrapped_models)
166
+ status = "degraded" if self._last_error else "healthy"
167
+ return {
168
+ "status": status,
169
+ "backend": "gemini",
170
+ "backend_connected": has_models,
171
+ "last_error": self._last_error,
172
+ "uptime_seconds": round(uptime, 2),
173
+ }
174
+
175
+
176
+ class GovernedGeminiModel:
177
+ """Gemini GenerativeModel wrapped with Agent OS governance.
178
+
179
+ Intercepts ``generate_content()`` for policy enforcement while
180
+ proxying all other attributes to the underlying model.
181
+ """
182
+
183
+ def __init__(
184
+ self,
185
+ model: Any,
186
+ kernel: GeminiKernel,
187
+ ctx: GeminiContext,
188
+ ) -> None:
189
+ self._model = model
190
+ self._kernel = kernel
191
+ self._ctx = ctx
192
+
193
+ def generate_content(self, contents: Any, **kwargs: Any) -> Any:
194
+ """Generate content with governance enforcement.
195
+
196
+ Validates prompt content against blocked patterns, enforces
197
+ tool-call allowlists, checks token limits, and records an
198
+ audit trail.
199
+
200
+ Args:
201
+ contents: The prompt content (string, list, or Content object).
202
+ **kwargs: Forwarded to ``model.generate_content()``.
203
+
204
+ Returns:
205
+ The Gemini generation response.
206
+
207
+ Raises:
208
+ PolicyViolationError: If a governance policy is violated.
209
+ """
210
+ # --- pre-execution checks ---
211
+ content_str = str(contents)
212
+ allowed, reason = self._kernel.pre_execute(self._ctx, content_str)
213
+ if not allowed:
214
+ raise PolicyViolationError(f"Content blocked: {reason}")
215
+
216
+ # Validate tools against policy
217
+ tools = kwargs.get("tools")
218
+ if tools:
219
+ self._validate_tools(tools)
220
+
221
+ # Audit log
222
+ logger.info(
223
+ "Gemini generate_content | agent=%s model=%s",
224
+ self._ctx.agent_id,
225
+ self._ctx.model_name,
226
+ )
227
+
228
+ # --- execute ---
229
+ try:
230
+ response = self._kernel._wrapped_models.get(
231
+ id(self._model), self._model
232
+ ).generate_content(contents, **kwargs)
233
+ except Exception as exc:
234
+ self._kernel._last_error = str(exc)
235
+ raise
236
+
237
+ # --- post-execution checks ---
238
+ gen_id = f"gen-{int(time.time())}-{self._ctx.call_count}"
239
+ self._ctx.generation_ids.append(gen_id)
240
+
241
+ # Track tokens from usage_metadata
242
+ usage = getattr(response, "usage_metadata", None)
243
+ if usage:
244
+ self._ctx.prompt_tokens += getattr(usage, "prompt_token_count", 0)
245
+ self._ctx.completion_tokens += getattr(
246
+ usage, "candidates_token_count", 0
247
+ )
248
+
249
+ total = self._ctx.prompt_tokens + self._ctx.completion_tokens
250
+ if total > self._kernel.policy.max_tokens:
251
+ raise PolicyViolationError(
252
+ f"Token limit exceeded: {total} > "
253
+ f"{self._kernel.policy.max_tokens}"
254
+ )
255
+
256
+ # Check for function calls in candidates
257
+ candidates = getattr(response, "candidates", [])
258
+ for candidate in candidates:
259
+ content = getattr(candidate, "content", None)
260
+ if content is None:
261
+ continue
262
+ parts = getattr(content, "parts", [])
263
+ for part in parts:
264
+ fn_call = getattr(part, "function_call", None)
265
+ if fn_call is None:
266
+ continue
267
+ fn_name = getattr(fn_call, "name", "")
268
+ call_info = {
269
+ "name": fn_name,
270
+ "args": dict(getattr(fn_call, "args", {})),
271
+ "timestamp": datetime.now().isoformat(),
272
+ }
273
+ self._ctx.function_calls.append(call_info)
274
+ self._ctx.tool_calls.append(call_info)
275
+
276
+ if len(self._ctx.tool_calls) > self._kernel.policy.max_tool_calls:
277
+ raise PolicyViolationError(
278
+ f"Tool call limit exceeded: "
279
+ f"{len(self._ctx.tool_calls)} > "
280
+ f"{self._kernel.policy.max_tool_calls}"
281
+ )
282
+
283
+ if self._kernel.policy.allowed_tools:
284
+ if fn_name not in self._kernel.policy.allowed_tools:
285
+ raise PolicyViolationError(
286
+ f"Tool not allowed: {fn_name}"
287
+ )
288
+
289
+ if self._kernel.policy.require_human_approval:
290
+ raise PolicyViolationError(
291
+ f"Tool '{fn_name}' requires human approval per governance policy"
292
+ )
293
+
294
+ # Post-execute bookkeeping
295
+ self._kernel.post_execute(self._ctx, response)
296
+
297
+ return response
298
+
299
+ def get_context(self) -> GeminiContext:
300
+ """Return the execution context with the full audit trail.
301
+
302
+ Returns:
303
+ The ``GeminiContext`` for this governed model.
304
+ """
305
+ return self._ctx
306
+
307
+ def get_token_usage(self) -> dict[str, Any]:
308
+ """Return cumulative token usage statistics.
309
+
310
+ Returns:
311
+ A dict with ``prompt_tokens``, ``completion_tokens``,
312
+ ``total_tokens``, and ``limit``.
313
+ """
314
+ return {
315
+ "prompt_tokens": self._ctx.prompt_tokens,
316
+ "completion_tokens": self._ctx.completion_tokens,
317
+ "total_tokens": self._ctx.prompt_tokens + self._ctx.completion_tokens,
318
+ "limit": self._kernel.policy.max_tokens,
319
+ }
320
+
321
+ def _validate_tools(self, tools: Any) -> None:
322
+ """Validate tool definitions against policy allowlist.
323
+
324
+ Args:
325
+ tools: Tool definitions from the request.
326
+
327
+ Raises:
328
+ PolicyViolationError: If a tool is not in the allowed list.
329
+ """
330
+ if not self._kernel.policy.allowed_tools:
331
+ return
332
+ tool_list = tools if isinstance(tools, list) else [tools]
333
+ for tool in tool_list:
334
+ declarations = getattr(tool, "function_declarations", None)
335
+ if declarations:
336
+ for decl in declarations:
337
+ name = getattr(decl, "name", "") if not isinstance(decl, dict) else decl.get("name", "")
338
+ if name and name not in self._kernel.policy.allowed_tools:
339
+ raise PolicyViolationError(f"Tool not allowed: {name}")
340
+
341
+ def __getattr__(self, name: str) -> Any:
342
+ """Proxy attribute access to the underlying Gemini model."""
343
+ return getattr(self._model, name)
344
+
345
+
346
+ def wrap_model(
347
+ model: Any,
348
+ policy: GovernancePolicy | None = None,
349
+ ) -> GovernedGeminiModel:
350
+ """Quick wrapper for Gemini GenerativeModel.
351
+
352
+ Args:
353
+ model: A ``google.generativeai.GenerativeModel`` instance.
354
+ policy: Optional governance policy.
355
+
356
+ Returns:
357
+ A governed model.
358
+
359
+ Example:
360
+ >>> from agent_os.integrations.gemini_adapter import wrap_model
361
+ >>> governed = wrap_model(my_model)
362
+ >>> response = governed.generate_content("Hello")
363
+ """
364
+ return GeminiKernel(policy=policy).wrap(model)