LoopGrid × Google ADK
loopgrid-google-adk is a native Google Agent Development Kit plugin for recording signed, independently verifiable evidence around consequential AI-agent decisions.
It uses ADK's current BasePlugin lifecycle and App(plugins=[...]) integration model. LoopGrid records evidence; it does not execute refunds, payments, account mutations, or other external business actions.
Install
pip install loopgrid-google-adk
For local development:
pip install -e ".[dev]"
Why this is ADK-native
The plugin maps current ADK lifecycle surfaces into LoopGrid evidence:
ADK before_run_callback
→ decision_created
ADK after_model_callback
→ model_completed
→ policy_evaluated (only explicit application policy)
ADK before_tool_callback
→ tool_requested
ADK after_tool_callback
→ tool_result
application confirms external execution
→ plugin.record_action_executed(...)
→ tool_executed
application observes authoritative business result
→ plugin.observe_outcome(...)
→ outcome_observed
Why after_tool_callback is tool_result, not automatically tool_executed
ADK permits plugins and agent callbacks to short-circuit a tool call by returning a response before the underlying tool body is invoked. Therefore an after_tool_callback proves that ADK observed a tool result, but by itself does not prove how that result was produced.
LoopGrid intentionally records that framework fact as tool_result. When your application has authoritative evidence that the consequential action actually executed, call record_action_executed(...) explicitly.
This avoids manufacturing execution evidence.
Basic usage
from google.adk.agents import Agent
from google.adk.apps import App
from google.adk.runners import InMemoryRunner
from loopgrid_google_adk import LoopGridADKPlugin
plugin = LoopGridADKPlugin(
authority={
"scope": "refunds",
"max_amount": 50,
"currency": "USD",
},
policy={
"policy_id": "refund-policy-v3",
"decision": "auto_allowed",
},
proposed_action={
"type": "refund",
"amount": 25,
"currency": "USD",
},
context={"prompt_version": "support-v7"},
)
root_agent = Agent(
name="support_agent",
model="gemini-2.5-flash",
tools=[...],
)
app = App(
name="support_app",
root_agent=root_agent,
plugins=[plugin],
)
runner = InMemoryRunner(app=app)
Per-invocation evidence
Prefer an explicit run binding:
run_id = plugin.bind_run(
"case-123",
authority={"scope": "refunds", "max_amount": 50},
policy={"policy_id": "refund-policy-v3", "decision": "auto_allowed"},
proposed_action={"type": "refund", "amount": 25, "currency": "USD"},
)
async for event in runner.run_async(
user_id="customer-42",
session_id=session.id,
invocation_id=run_id,
new_message=user_message,
):
...
Using the same value for bind_run(...) and ADK's invocation_id keeps application-owned evidence correlated without putting sensitive authority or policy values into model context.
ADK RunConfig.custom_metadata["loopgrid"] is also supported for non-secret metadata, but ADK attaches custom metadata to invocation/event state. Do not use that channel for credentials or secrets.
Explicit action and outcome
After your application has authoritative evidence that an external action ran:
await plugin.record_action_executed(
run_id,
{
"tool": "refund-service",
"external_ref": "refund_123",
"sandbox": True,
"real_money_moved": False,
},
)
After the downstream system returns the authoritative result:
await plugin.observe_outcome(
run_id,
{
"status": "sandbox_refunded",
"external_ref": "refund_123",
"sandbox": True,
"real_money_moved": False,
},
)
Privacy defaults
By default:
capture_content=False
Raw user content, model responses, tool arguments, tool results, and exception messages are not stored by this integration. SHA-256 commitments plus bounded metadata are recorded instead.
Raw content capture is explicit opt-in:
LoopGridADKPlugin(capture_content=True)
Failure mode
The default is fail-closed:
fail_open=False
If evidence cannot be recorded, the integration surfaces the error rather than silently running an evidence-required path without evidence.
For low-risk telemetry-only use cases, applications may opt into:
fail_open=True
Deterministic runtime validation
The repository includes a real ADK runtime test using a deterministic custom BaseLlm. It exercises:
real ADK App
→ real InMemoryRunner
→ real BasePlugin callbacks
→ custom deterministic BaseLlm
→ real function tool call
→ LoopGrid plugin lifecycle
→ final model turn
No Gemini key, Google Cloud project, paid billing account, or credit card is required for that runtime test.
Run:
python -m pytest -v
python -m compileall -q src examples tests
Then, with LoopGrid Core running:
python examples/refund_gate.py
The release gate is:
evidence_complete
100% applicable evidence coverage
verify.valid = true
The included refund example is sandbox-only and explicitly records real_money_moved=false.
Security and evidence boundaries
See:
License
Apache-2.0.
Release files for loopgrid-google-adk 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| loopgrid_google_adk-0.1.0.tar.gz | 26.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| loopgrid_google_adk-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 44.9 kB
Release files / loopgrid_google_adk-0.1.0.tar.gz
| Download URL | loopgrid_google_adk-0.1.0.tar.gz |
|---|---|
| Size | 26.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
53ba51d52bf81a37bcc340e047949b33fc85aa84d21671b6bd87fcb01add658b
|
|
BLAKE2b-256 checksum How to use checksums |
bdce82343e0781f04fba0ae9ced5bf17e85f459bbfd060d2f38873c2b0ca6231
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 27, 2026.
Transparency logRelease files / loopgrid_google_adk-0.1.0-py3-none-any.whl
| Download URL | loopgrid_google_adk-0.1.0-py3-none-any.whl |
|---|---|
| Size | 18.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
0c5c3918965466be832f8ff9837a3d16985b23a69fb25daeaecadedd8283349d
|
|
BLAKE2b-256 checksum How to use checksums |
2ec8be838c07d01c1b4857811a4cba04447efeb9aebb24ce9a0273389c34cb43
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 27, 2026.
Transparency log