gcloud auth application-default login or a service
account), like the rest of your code.
With the AI SDK
npm install ai @ai-sdk/google-vertex @doconda/sdk
import { createVertex } from "@ai-sdk/google-vertex"
import { generateText, isStepCount, jsonSchema, tool } from "ai"
import { Doconda } from "@doconda/sdk"
const vertex = createVertex({ project: "my-project", location: "europe-west1" })
const doconda = new Doconda()
const tools = Object.fromEntries(
doconda.tools().map((t) => [
t.name,
tool({ description: t.description, inputSchema: jsonSchema(t.inputSchema), execute: (input) => t.run(input as Record<string, unknown>) }),
]),
)
const { text } = await generateText({
model: vertex("gemini-3.5-flash"),
tools,
stopWhen: isStepCount(5),
prompt: "Create a 5-slide presentation on our quarterly results",
})
With @google/genai
npm install @google/genai @doconda/sdk
vertexai: true:
import { type Content, GoogleGenAI } from "@google/genai"
import { Doconda } from "@doconda/sdk"
const ai = new GoogleGenAI({ vertexai: true, project: "my-project", location: "europe-west1" })
const tools = new Doconda().tools()
const contents: Content[] = [{ role: "user", parts: [{ text: "Make me an Excel file with the event budget" }] }]
while (true) {
const res = await ai.models.generateContent({
model: "gemini-3.5-flash",
contents,
config: { tools: [{ functionDeclarations: tools.map((t) => ({ name: t.name, description: t.description, parametersJsonSchema: t.inputSchema })) }] },
})
if (!res.functionCalls?.length) break
contents.push(res.candidates![0].content!)
const parts = await Promise.all(
res.functionCalls.map(async (call) => ({
functionResponse: { name: call.name, response: { result: await tools.find((t) => t.name === call.name)!.run(call.args ?? {}) } },
})),
)
contents.push({ role: "user", parts })
}