Build1 distinct publisher2 min readPublished
A Gemini function call arrives as a name and structured arguments, and nothing in the SDK decides whether the caller is permitted or whether the booking already went through. That gate is yours to build.
The Engineer · Build desk

Compiled by The EngineerSomething wrong?How this is made
The `parameters` block is the piece teams mistake for a guard. In the sample declaration it types `city` as a string, marks it required, and leaves `maxNightlyPriceUsd` as an optional number [4]. It says nothing about whether the city string is between 2 and 120 characters after trimming, or whether the price is positive and at most 10,000; in the post those bounds live in a Zod schema applied on arrival [5]. Raju Dandigam's reason for the split is the right one: model-generated arguments cross the same trust boundary as an HTTP request [6], and the declaration exists to help the model produce better arguments rather than to validate them on your side of the wire [7].
After shape, the questions change character. The returned object is a name and structured arguments [3], carrying no user identity and no evidence that the same call already succeeded. Authorization has to come from your context: in the sample it is a set membership test that throws unless the execution context's permissions contain `hotel:read` [10]. Policy answers what a permission set cannot, which is whether this operation should happen in this workflow at this moment [9]. Same well-formed call, same authorized user, different answer depending on which agent is running.
The tool registry is the part I would copy. Each entry carries a risk tag of read, write or irreversible alongside a timeout, a parser and an executor [13], which puts the blast radius of a tool in the same object as its code. The sample values are a 3,000 ms timeout for `search_hotels` and 8,000 ms for `book_hotel` [14], roughly 2.7 times the budget for the call you cannot take back [15]. Those two numbers are claims about someone else's inventory and booking providers. They transfer if your booking API's tail latency sits inside eight seconds and your read path is an index or a cache; otherwise keep the tag and re-measure the milliseconds.
"The model proposes. The runtime disposes," as Dandigam puts it [20]. The disposal step is where the code gets tedious, and the post's `executeOnce` is cut off in the text I was given, which is a shame, because where the dedupe key is stored is the whole question. A process-local map does not survive the worker-restart case the post itself names [17].
In my context, write tools sitting behind a payments provider, I would build that store before the policy layer, because a duplicated charge costs more than an over-permissive read. If every tool you expose is a read, invert the order and spend the week on argument validation instead.
Ranked by verification strength, evidence, and original report placement.
According to the post, Google is explicit that the model does not execute your business function: the application is responsible for executing it and returning the result.
Gemini function calling works by describing a function and providing its input schema, then letting the model decide whether the user's request requires it.
In the Google Gen AI SDK sample, a search_hotels function declaration is passed as tools: [{ functionDeclarations: [searchHotels] }] to a single ai.models.generateContent call against model gemini-2.5-flash, and the proposed call is read from response.functionCalls?.[0].
The returned function call contains a name and structured arguments.
The searchHotels declaration types city as STRING and lists it in required, with maxNightlyPriceUsd as an optional NUMBER described as a maximum nightly price in US dollars.
The post's Zod schema requires city to be a trimmed string of at least 2 and at most 120 characters, and maxNightlyPriceUsd to be a positive number of at most 10,000, optional.
Distinct publishers with included, body-backed reporting in this cluster.
dev.to
1 article · August 30, 2026
Follow any of these and your For You feed starts watching them — no settings page required.
build
The refund that fired three times: tool calls are a systems problem, not a prompt problem1 distinct publisher
build
Armenian ASR leaderboard: closed models take the top eight, then lose the domains that matter1 distinct publisher
build
Signed receipts on MCP tool calls: 20 lines buys you evidence, not trust1 distinct publisher
build
The only gate that ran was a hand-typed enum, and it had never heard of the new value1 distinct publisher
Evidence-backed comparisons of source perspectives and observed adoption signals. Read the methodology
Which Builder, Operator, and Investor concerns the observed source mix emphasized—not a truth score.
Evidence, demonstrated adoption, hype gap, incentives, and confidence are assessed independently, each on its own current evidence. How these are measured.
Self-verifying code, nothing checked outside it
The mechanical core is strong in an unusual way: the SDK snippet, the Zod schema and the risk-tagged registry are the evidence, and a reader with an API key can confirm in minutes that a function call comes back as a name and arguments and that nothing executes on Google's side. Everything above that line is reasoning — the trust-boundary analogy, the three-question split, the duplication scenarios — and it carries no external corroboration at all: no documentation citation, no incident, no measurement.
No deployment signal
Nothing in this reporting says anyone has shipped this. There is no release, no team using the pattern, no repository, no traffic or usage figure — only a design argument and illustrative code with placeholder functions like searchHotelInventory and idempotencyStore standing in for the real thing.
Sober thesis, overstated completeness
The headline claim is the modest one and it holds: function calling really does not adjudicate authorization, prior success or retry safety. The overreach is quieter. 'That boundary is where production engineering begins' promises a runtime, and what follows is fragments — a two-tool registry, timeouts and a TTL presented as settled numbers, an audit step announced and then cut off mid-line. Small gap, and it is about coverage of the design rather than inflation of the claims.
Individual byline, nothing being sold
This is a personal developer-blog post, not vendor material: no product, no sponsorship disclosure, no call to buy anything, and the framing is mildly critical of the SDK's scope rather than promotional. The pressures that remain are the ordinary ones of the format — a strong contrarian title earns attention, and thoroughness competes with publishing — which is enough to explain a piece that opens confidently and stops mid-function.
One author, one outlet, one loose end
We are confident about what the story says and much less confident about what stands behind it. A single publisher supplies every claim; the code can be checked but the operational warnings cannot; and our own record of where the text breaks off disagrees with the text itself, which is a reminder to treat the secondhand details here — including the paraphrase of Google's position — as unconfirmed.