Google ADK adapter
For the Google Agent Development Kit. ADK accepts plain callables for Agent(tools=…) and infers tool schemas from the callable's signature — so the adapter returns signature-preserving governed wrappers (via functools.wraps), not opaque tool objects. ADK introspects them as if you'd passed the underlying function directly.
Install
pip install kitelogik google-adkIf you also want the Google Gemini provider:
pip install "kitelogik[google]" google-adk # adds google-genaigoogle-adk is not a hard dependency — only imported when you call adk_tools().
Setup
from kitelogik import OPAClient, PolicyGate, SessionContext
from kitelogik.adapters.google_adk import GoogleADKAdapter
gate = PolicyGate(opa_client=OPAClient())
context = SessionContext(
session_id="sess_001",
user_role="analyst",
session_scopes=["read_customer"],
)
adapter = GoogleADKAdapter(gate=gate, context=context)Register tools
register(name, fn, description="", action=None) — chainable.
async def get_customer(customer_id: str) -> str:
"""Look up a customer record by ID."""
return f"Customer {customer_id}: Acme Corp, plan=enterprise"
adapter.register("get_customer", get_customer, description="Look up a customer")The original function's signature, name, and docstring are preserved on the governed wrapper, so ADK's auto-schema inference produces the right tool spec.
Pass governed tools to an ADK Agent
from google.adk import Agent
agent = Agent(
name="support",
model="gemini-2.0-flash",
tools=adapter.adk_tools(), # ← signature-preserving callables
)ADK reads each callable's annotated parameters to build the tool schema, dispatches calls into the governed wrapper, which routes through the policy gate before the underlying function runs.
What happens on a deny
Denied calls return a JSON string {"blocked": true, "reason": "..."} as the tool result, matching ADK's expectation that tools return strings. The agent loop continues; the model sees the structured denial.
{"blocked": true, "reason": "Action blocked by governance policy."}To customise the message, pass deny_message= to the adapter constructor.
Constructor parameters
GoogleADKAdapter extends BaseGovernedAdapter:
GoogleADKAdapter(
gate: PolicyGate,
context: SessionContext,
sanitize: bool = True,
deny_message: str | None = None,
)| Param | Default | Purpose |
|---|---|---|
sanitize | True | Run prompt-injection sanitiser on string return values |
deny_message | "Action blocked by governance policy." | The string surfaced to the model on deny |
Source
kitelogik/adapters/google_adk.py on GitHub.