Python 88.3%
TypeScript 7.6%
Shell 4.1%
1// Generic Gemini generateContent tool loop (TypeScript, @google/genai).2// STATUS: LIVE_VERIFIED 2026-09-18 — `node --env-file=.env --experimental-strip-types examples/shared/tool-loop/gemini_tool_loop.ts`3// (gemini-3.5-flash-lite, one get_weather + get_time parallel round trip). See docs/gemini/tool-loop.md for the patterns.4import { GoogleGenAI, Type } from "@google/genai";5import { logRequest } from "./log.ts";67const ai = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });8const MODEL = "gemini-3.5-flash-lite";9type Handler = (args: Record<string, any>) => unknown;1011export async function runToolLoop(prompt: string, declarations: any[], handlers: Record<string, Handler>, maxTurns = 6): Promise<string> {12 const contents: any[] = [{ role: "user", parts: [{ text: prompt }] }];13 for (let turn = 0; turn < maxTurns; turn++) {14 const r = await ai.models.generateContent({ model: MODEL, contents, config: { tools: [{ functionDeclarations: declarations }], maxOutputTokens: 256 } });15 logRequest("gemini", "POST", "/v1beta/models/{model}:generateContent", 200, 0.0001, `ts gemini tool loop turn ${turn}`);16 const modelTurn = r.candidates![0].content!; // append verbatim: functionCall parts carry thoughtSignature (required on echo)17 const calls = (modelTurn.parts ?? []).filter((p: any) => p.functionCall).map((p: any) => p.functionCall);18 if (calls.length === 0) return r.text ?? "";19 const responses = calls.map((c: any) => {20 let out: unknown;21 try { out = handlers[c.name](c.args ?? {}); } catch (e) { out = { error: String(e) }; }22 console.log(` turn ${turn}: ${c.name}(${JSON.stringify(c.args)}) -> ${JSON.stringify(out).slice(0, 80)}`);23 return { functionResponse: { name: c.name, id: c.id, response: typeof out === "object" && out !== null ? out : { result: out } } };24 });25 contents.push(modelTurn, { role: "user", parts: responses });26 }27 return "(max turns reached)";28}2930if (import.meta.url === `file://${process.argv[1]}`) {31 const decls = [32 { name: "get_weather", description: "Current weather for a city.", parameters: { type: Type.OBJECT, properties: { city: { type: Type.STRING } }, required: ["city"] } },33 { name: "get_time", description: "Current local time in a city.", parameters: { type: Type.OBJECT, properties: { city: { type: Type.STRING } }, required: ["city"] } },34 ];35 console.log(await runToolLoop("Weather in Paris and time in Tokyo? Use the tools, then answer in one sentence.", decls,36 { get_weather: (a) => ({ city: a.city, temperature_c: 18, conditions: "light rain" }), get_time: (a) => ({ city: a.city, time: "14:05" }) }));37}38