entorin

Google ADK

Plug EntorinPlugin into a Runner. Every ADK lifecycle callback translates into the v1 Entorin taxonomy; the ledger ticks on every model response.

EntorinPlugin is a BasePlugin subclass. Wire it into a Runner once; every ADK run that follows emits Entorin events on every lifecycle boundary.

from decimal import Decimal
from google.adk.runners import Runner
from pydantic import SecretStr

from adapters.google_adk import EntorinPlugin
from entorin.auth import Capability, Principal
from entorin.budget import MemoryLedger, OverflowPolicy
from entorin.context import RunContext
from entorin.events import EventBus
from entorin.model.pricing import ConstPricing, Rate

principal = Principal(
    user_id="alice",
    caps=(Capability(kind="model.google.key", value=SecretStr("...")),),
)
ctx     = RunContext(run_id="run-1", principal=principal)
bus     = EventBus()
ledger  = MemoryLedger()
ledger.set_cap("alice", Decimal("0.50"),
               bucket_id="adk-research",
               overflow_policy=OverflowPolicy.FINISH_RUN)
pricing = ConstPricing({"gemini-2.0-flash": Rate(
    input_per_mtok=Decimal("0.075"), output_per_mtok=Decimal("0.30"),
)})

plugin = EntorinPlugin(
    ctx=ctx, bus=bus, ledger=ledger, pricing=pricing,
    bucket_id="adk-research",
)
runner = Runner(plugins=[plugin])

Callback mapping

ADK callbackEntorin eventSide effect
before_runrun.start (phase implicit)
after_runrun.end (phase=done)
before_agentnode.pre
after_agentnode.post
before_modelllm.call.prepush model id onto stack
after_modelllm.call.postLedger.debit from LlmResponse.usage_metadata
on_model_errorllm.call.errorpop model id from stack
before_tooltool.call.pre
after_tooltool.call.post
on_tool_errortool.call.error

Model id stack

ADK’s after_model callback receives only the LlmResponse, not the original LlmRequest, so the plugin pushes the model id in before_model and pops it in after_model / on_model_error. This works for serialized LLM calls per run — the common case.

A runnable demo using duck-typed stubs (no Google credentials needed): examples/google_adk_qa.py.