Vercel AI SDK (Google provider)
@ai-sdk/google with the ai package, on plugboard's Gemini API.
Connect
The provider adds /models/{id}:generateContent, so baseURL ends in /v1beta:
ts
// The provider adds /models/{id}:generateContent itself, so baseURL ends in /v1beta and not in /v1.
// It adds the models/ prefix only when the id has no /. An id with a / (anthropic/claude-haiku-4-5) would go out as
// /v1beta/anthropic/... and plugboard answers 404, so the id is percent-encoded: / as %2F, # as %23 (docs/gemini.md).
const origin = (process.env.PLUGBOARD_BASE_URL ?? "").replace(/\/v1\/?$/, "")
export const plugboardURL = `${origin}/v1beta`
export const plugboardKey = process.env.PLUGBOARD_KEY ?? ""
export const google = createGoogleGenerativeAI({ baseURL: plugboardURL, apiKey: plugboardKey })Chat
ts
const result = await generateText({ model: client(model), prompt: "Reply with exactly: pong", maxOutputTokens: 1024 })Tool calls
The SDK runs the tool and sends the follow-up request. Plugboard only returns the call.
ts
const get_weather = tool({
description: "Current weather for a city",
inputSchema: z.object({ city: z.string().describe("City name") }),
execute: async ({ city }) => {
cities.push(city)
return weatherResult
},
})
const result = await generateText({ model: client(model), tools: { get_weather }, stopWhen: isStepCount(4), prompt: PROMPT, maxOutputTokens: 1024 })Streaming
ts
const result = streamText({ model: client(model), prompt: PROMPT, maxOutputTokens: 1024 })
for await (const part of result.fullStream) {
if (part.type === "text-delta") text += part.text
if (part.type === "finish") {
finish = part.finishReason
usage = part.totalUsage
}
}Images
Use a file part with mediaType: "image/png" (the older image part also works, with a deprecation warning):
ts
// A 32px red PNG as a data URL (examples/_shared/red32.dataurl.txt). The provider sends it as inline data.
const red = readFileSync(new URL("../_shared/red32.dataurl.txt", import.meta.url), "utf8").trim()
const result = await generateText({
model: client(model),
maxOutputTokens: 1024,
messages: [
{
role: "user",
content: [
{ type: "text", text: "What color is this image? One word." },
{ type: "image", image: red, mediaType: "image/png" },
],
},
],
})Structured output
ts
const { output } = await generateText({ model: client(model), output: Output.object({ schema: Meal }), prompt: "Estimate: 2 boiled eggs and a slice of toast.", maxOutputTokens: 1024 })Model names
The provider adds the models/ prefix only to ids without a /. Send provider/model ids percent-encoded (anthropic%2Fclaude-haiku-4-5, openai%2Fgpt-5.6-luna%23low), or use an alias. See Gemini model names.
Limits
- The provider has no model-list call.
- The schema in structured output is not enforced by the provider. Validate the answer.