Google Gemini
Guard the function-calling loop you run with the Gemini SDK, so every dispatch is scored before it executes.
The Gemini SDK does not run your tools. Your loop does: the model returns
functionCall parts, you execute them, and you send back functionResponse
parts. So this adapter guards your dispatch step, exactly like the
Anthropic adapter. Hand it each function call
plus your handlers, and it scores the call through AxioRank first, returning a
ready-to-send function response.
Install
npm install @axiorank/sdkpip install axiorankThe adapter only reads a call's name / args / id, so it never imports the
Google GenAI client itself. Bring your own (@google/genai or google-genai).
Guard your dispatch
import { GoogleGenAI } from "@google/genai";
import { AxioRank } from "@axiorank/sdk";
import { guardFunctionHandlers } from "@axiorank/sdk/gemini";
const ai = new GoogleGenAI({});
const axio = new AxioRank({ apiKey: process.env.AXIORANK_KEY! });
const dispatch = guardFunctionHandlers(
{
deployToProd: async ({ service }) => deploy(service),
lookupOrder: async ({ id }) => orders.get(id),
},
axio.trace(), // one trace correlates the whole run for kill-chain detection
{ onDeny: "return" }, // the model reads the refusal and can re-plan
);
const res = await ai.models.generateContent({ model, contents, config: { tools } });
const parts = [];
for (const call of res.functionCalls ?? []) {
parts.push(await dispatch(call));
}
// send `parts` back as the next turn's contentfrom google import genai
from google.genai import types
from axiorank import AxioRank
from axiorank.integrations.google_genai import guard_function_handlers
ai = genai.Client()
axio = AxioRank(api_key="axr_live_...")
dispatch = guard_function_handlers(
{
"deploy_to_prod": lambda a: deploy(a["service"]),
"lookup_order": lambda a: orders.get(a["id"]),
},
axio.trace(),
on_deny="return",
)
res = ai.models.generate_content(model=model, contents=contents, config=config)
replies = [
types.Part.from_function_response(name=r["name"], response=r["response"])
for r in (dispatch(fc) for fc in (res.function_calls or []))
]
# send `replies` back as the next turnAsync code uses guard_function_handlers_async with an AsyncAxioRank client;
async handlers are awaited automatically.
On a deny the function response carries an error field with the refusal, so
the model sees why the action vanished instead of silently losing it. Pass
onDeny: "throw" (TS) / on_deny="raise" (Python) to fail the loop instead.
Operate on assembled function calls, not streaming deltas. A handler that throws propagates unchanged; only AxioRank denials become refusal responses.
Output inspection
Pass inspectResults: true / inspect_results=True to also score each
untrusted-source tool's output (fetched pages, emails, query results) for
indirect prompt injection before the model ingests it. See
Tool-output inspection.